Merge pull request #3141 from Kingcom/StackFramesDisplay

Stack frames display
This commit is contained in:
Henrik Rydgård 2013-08-13 08:29:29 -07:00
commit 2f39c8ca41
6 changed files with 226 additions and 4 deletions

View file

@ -138,10 +138,17 @@ CDisasm::CDisasm(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu) : Di
threadList->setDialogItem(GetDlgItem(m_hDlg,IDC_THREADLIST));
threadList->reloadThreads();
stackTraceView = new CtrlStackTraceView();
stackTraceView->setCpu(cpu);
stackTraceView->setDisasm(ptr);
stackTraceView->setDialogItem(GetDlgItem(m_hDlg,IDC_STACKFRAMES));
stackTraceView->loadStackTrace();
// init memory/breakpoint "tab"
ShowWindow(GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST), SW_HIDE);
ShowWindow(GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW), SW_NORMAL);
ShowWindow(GetDlgItem(m_hDlg, IDC_THREADLIST), SW_HIDE);
ShowWindow(GetDlgItem(m_hDlg, IDC_STACKFRAMES), SW_HIDE);
// init status bar
statusBarWnd = CreateStatusWindow(WS_CHILD | WS_VISIBLE, "", m_hDlg, IDC_DISASMSTATUSBAR);
@ -206,6 +213,9 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
case IDC_THREADLIST:
threadList->handleNotify(lParam);
break;
case IDC_STACKFRAMES:
stackTraceView->handleNotify(lParam);
break;
}
break;
case WM_COMMAND:
@ -283,6 +293,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
CtrlMemView::getFrom(GetDlgItem(m_hDlg,IDC_DEBUGMEMVIEW))->redraw();
threadList->reloadThreads();
stackTraceView->loadStackTrace();
updateThreadLabel(false);
}
break;
@ -504,23 +515,34 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
HWND bp = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
HWND mem = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW);
HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST);
HWND stackFrames = GetDlgItem(m_hDlg, IDC_STACKFRAMES);
if (IsWindowVisible(bp))
{
ShowWindow(bp,SW_HIDE);
ShowWindow(mem,SW_HIDE);
ShowWindow(bp,SW_HIDE);
ShowWindow(threads,SW_NORMAL);
ShowWindow(stackFrames,SW_HIDE);
SetFocus(threads);
} else if (IsWindowVisible(threads))
{
ShowWindow(mem,SW_HIDE);
ShowWindow(bp,SW_HIDE);
ShowWindow(mem,SW_NORMAL);
ShowWindow(threads,SW_HIDE);
ShowWindow(stackFrames,SW_NORMAL);
SetFocus(stackFrames);
} else if (IsWindowVisible(stackFrames))
{
ShowWindow(mem,SW_NORMAL);
ShowWindow(bp,SW_HIDE);
ShowWindow(threads,SW_HIDE);
ShowWindow(stackFrames,SW_HIDE);
SetFocus(mem);
} else {
ShowWindow(bp,SW_NORMAL);
ShowWindow(mem,SW_HIDE);
ShowWindow(bp,SW_NORMAL);
ShowWindow(threads,SW_HIDE);
ShowWindow(stackFrames,SW_HIDE);
SetFocus(bp);
}
}
@ -590,6 +612,7 @@ void CDisasm::UpdateSize(WORD width, WORD height)
HWND breakpointList = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST);
HWND memView = GetDlgItem(m_hDlg, IDC_DEBUGMEMVIEW);
HWND threads = GetDlgItem(m_hDlg, IDC_THREADLIST);
HWND stackFrame = GetDlgItem(m_hDlg,IDC_STACKFRAMES);
if (g_Config.bDisplayStatusBar)
{
@ -617,6 +640,7 @@ void CDisasm::UpdateSize(WORD width, WORD height)
MoveWindow(breakpointList,8,breakpointTop,width-16,breakpointHeight,TRUE);
MoveWindow(memView,8,breakpointTop,width-16,breakpointHeight,TRUE);
MoveWindow(threads,8,breakpointTop,width-16,breakpointHeight,TRUE);
MoveWindow(stackFrame,8,breakpointTop,width-16,breakpointHeight,TRUE);
GetWindowRect(GetDlgItem(m_hDlg, IDC_REGLIST),&regRect);
GetWindowRect(GetDlgItem(m_hDlg, IDC_DISASMVIEW),&disRect);
@ -646,6 +670,7 @@ void CDisasm::SetDebugMode(bool _bDebug)
CBreakPoints::ClearTemporaryBreakPoints();
breakpointList->update();
threadList->reloadThreads();
stackTraceView->loadStackTrace();
updateThreadLabel(false);
EnableWindow( GetDlgItem(hDlg, IDC_GO), TRUE);

View file

@ -30,6 +30,7 @@ private:
HWND statusBarWnd;
CtrlBreakpointList* breakpointList;
CtrlThreadList* threadList;
CtrlStackTraceView* stackTraceView;
std::vector<BreakPoint> displayedBreakPoints_;
std::vector<MemCheck> displayedMemChecks_;

View file

@ -7,6 +7,7 @@
#include "Windows/resource.h"
#include "Windows/main.h"
#include "BreakpointWindow.h"
#include "../../Core/HLE/sceKernelThread.h"
typedef struct
{
@ -16,6 +17,7 @@ typedef struct
enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT };
enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_CONDITION, BPL_HITS, BPL_ENABLED, BPL_COLUMNCOUNT };
enum { SF_ENTRY, SF_ENTRYNAME, SF_CURPC, SF_CUROPCODE, SF_CURSP, SF_FRAMESIZE, SF_COLUMNCOUNT };
ListViewColumn threadColumns[TL_COLUMNCOUNT] = {
{ "Name", 0.20f },
@ -36,6 +38,15 @@ ListViewColumn breakpointColumns[BPL_COLUMNCOUNT] = {
{ "Enabled", 0.08f }
};
ListViewColumn stackTraceColumns[SF_COLUMNCOUNT] = {
{ "Entry", 0.12f },
{ "Name", 0.24f },
{ "PC", 0.12f },
{ "Opcode", 0.28f },
{ "SP", 0.12f },
{ "Frame Size", 0.12f }
};
const int POPUP_SUBMENU_ID_BREAKPOINTLIST = 5;
const int POPUP_SUBMENU_ID_THREADLIST = 6;
const int POPUP_SUBMENU_ID_NEWBREAKPOINT = 7;
@ -710,3 +721,163 @@ void CtrlBreakpointList::showBreakpointMenu(int itemIndex, const POINT &pt)
}
}
}
//
// CtrlStackTraceView
//
void CtrlStackTraceView::setDialogItem(HWND hwnd)
{
wnd = hwnd;
SetWindowLongPtr(wnd,GWLP_USERDATA,(LONG_PTR)this);
oldProc = (WNDPROC) SetWindowLongPtr(wnd,GWLP_WNDPROC,(LONG_PTR)wndProc);
SendMessage(wnd, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
LVCOLUMN lvc;
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.fmt = LVCFMT_LEFT;
RECT rect;
GetWindowRect(wnd,&rect);
int totalListSize = (rect.right-rect.left-20);
for (int i = 0; i < SF_COLUMNCOUNT; i++)
{
lvc.cx = stackTraceColumns[i].size * totalListSize;
lvc.pszText = stackTraceColumns[i].name;
ListView_InsertColumn(wnd, i, &lvc);
}
}
LRESULT CALLBACK CtrlStackTraceView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CtrlStackTraceView* sv = (CtrlStackTraceView*) GetWindowLongPtr(hwnd,GWLP_USERDATA);
switch (msg)
{
case WM_SIZE:
{
int width = LOWORD(lParam);
RECT rect;
GetWindowRect(hwnd,&rect);
int totalListSize = (rect.right-rect.left-20);
for (int i = 0; i < SF_COLUMNCOUNT; i++)
{
ListView_SetColumnWidth(hwnd,i,stackTraceColumns[i].size * totalListSize);
}
}
break;
case WM_KEYDOWN:
if (wParam == VK_TAB)
{
SendMessage(GetParent(hwnd),WM_DEB_TABPRESSED,0,0);
return 0;
}
break;
case WM_GETDLGCODE:
if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN)
{
if (wParam == VK_TAB) return DLGC_WANTMESSAGE;
}
break;
}
return (LRESULT)CallWindowProc((WNDPROC)sv->oldProc,hwnd,msg,wParam,lParam);
}
void CtrlStackTraceView::handleNotify(LPARAM lParam)
{
LPNMHDR mhdr = (LPNMHDR) lParam;
if (mhdr->code == NM_DBLCLK)
{
LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam;
SendMessage(GetParent(wnd),WM_DEB_GOTOWPARAM,frames[item->iItem].pc,0);
return;
}
if (mhdr->code == LVN_GETDISPINFO)
{
NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam;
int index = dispInfo->item.iItem;
stringBuffer[0] = 0;
switch (dispInfo->item.iSubItem)
{
case SF_ENTRY:
sprintf(stringBuffer,"%08X",frames[index].entry);
break;
case SF_ENTRYNAME:
{
const char* sym = cpu->findSymbolForAddress(frames[index].entry);
if (sym != NULL)
{
strcpy(stringBuffer,sym);
} else {
strcpy(stringBuffer,"-");
}
}
break;
case SF_CURPC:
sprintf(stringBuffer,"%08X",frames[index].pc);
break;
case SF_CUROPCODE:
disasm->getOpcodeText(frames[index].pc,stringBuffer);
break;
case SF_CURSP:
sprintf(stringBuffer,"%08X",frames[index].sp);
break;
case SF_FRAMESIZE:
sprintf(stringBuffer,"%08X",frames[index].stackSize);
break;
}
if (stringBuffer[0] == 0) strcat(stringBuffer,"Invalid");
dispInfo->item.pszText = stringBuffer;
}
}
void CtrlStackTraceView::loadStackTrace()
{
auto threads = GetThreadsInfo();
u32 entry, stackTop;
for (size_t i = 0; i < threads.size(); i++)
{
if (threads[i].isCurrent)
{
entry = threads[i].entrypoint;
stackTop = threads[i].initialStack;
break;
}
}
frames = MIPSStackWalk::Walk(cpu->GetPC(),cpu->GetRegValue(0,31),cpu->GetRegValue(0,29),entry,stackTop);
int items = ListView_GetItemCount(wnd);
while (items < (int)frames.size())
{
LVITEM lvI;
lvI.pszText = LPSTR_TEXTCALLBACK; // Sends an LVN_GETDISPINFO message.
lvI.mask = LVIF_TEXT | LVIF_IMAGE |LVIF_STATE;
lvI.stateMask = 0;
lvI.iSubItem = 0;
lvI.state = 0;
lvI.iItem = items;
lvI.iImage = items;
ListView_InsertItem(wnd, &lvI);
items++;
}
while (items > (int)frames.size())
{
ListView_DeleteItem(wnd,--items);
}
InvalidateRect(wnd,NULL,true);
UpdateWindow(wnd);
}

View file

@ -3,6 +3,7 @@
#include "../../Core/Debugger/DebugInterface.h"
#include "../../Core/HLE/sceKernelThread.h"
#include "../../Core/Debugger/Breakpoints.h"
#include "../../Core/MIPS/MIPSStackWalk.h"
class CtrlThreadList
{
@ -53,4 +54,28 @@ public:
void handleNotify(LPARAM lParam);
void showMenu(int itemIndex, const POINT &pt);
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};
class CtrlStackTraceView
{
HWND wnd;
WNDPROC oldProc;
std::vector<MIPSStackWalk::StackFrame> frames;
DebugInterface* cpu;
CtrlDisAsmView* disasm;
char stringBuffer[256];
public:
void setCpu(DebugInterface* cpu)
{
this->cpu = cpu;
};
void setDisasm(CtrlDisAsmView* disasm)
{
this->disasm = disasm;
};
void setDialogItem(HWND hwnd);
void loadStackTrace();
void handleNotify(LPARAM lParam);
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
};

Binary file not shown.

Binary file not shown.