mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #3141 from Kingcom/StackFramesDisplay
Stack frames display
This commit is contained in:
commit
2f39c8ca41
6 changed files with 226 additions and 4 deletions
|
@ -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),®Rect);
|
||||
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);
|
||||
|
|
|
@ -30,6 +30,7 @@ private:
|
|||
HWND statusBarWnd;
|
||||
CtrlBreakpointList* breakpointList;
|
||||
CtrlThreadList* threadList;
|
||||
CtrlStackTraceView* stackTraceView;
|
||||
std::vector<BreakPoint> displayedBreakPoints_;
|
||||
std::vector<MemCheck> displayedMemChecks_;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
Loading…
Add table
Reference in a new issue