diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp index 5658d3063..def2cd941 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterCPU.cpp @@ -305,8 +305,6 @@ void CInterpreterCPU::ExecuteCPU() continue; } - g_Debugger->CPUStep(); - /* if (PROGRAM_COUNTER > 0x80000300 && PROGRAM_COUNTER < 0x80380000) { WriteTraceF((TraceType)(TraceError | TraceNoHeader),"%X: %s",*_PROGRAM_COUNTER,R4300iOpcodeName(Opcode.Hex,*_PROGRAM_COUNTER)); @@ -317,6 +315,8 @@ void CInterpreterCPU::ExecuteCPU() m_R4300i_Opcode[Opcode.op](); NextTimer -= CountPerOp; + g_Debugger->CPUStep(); + PROGRAM_COUNTER += 4; switch (R4300iOp::m_NextInstruction) { diff --git a/Source/Project64/N64System/Debugger/Debugger-Commands.cpp b/Source/Project64/N64System/Debugger/Debugger-Commands.cpp index 70085ecbc..84dde7dbe 100644 --- a/Source/Project64/N64System/Debugger/Debugger-Commands.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-Commands.cpp @@ -136,6 +136,7 @@ LRESULT CDebugCommandsView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARA LRESULT CDebugCommandsView::OnDestroy(void) { + UnhookWindowsHookEx(hWinMessageHook); return 0; } @@ -1068,6 +1069,7 @@ void CDebugCommandsView::CPUSkip() void CDebugCommandsView::CPUStepInto() { m_Debugger->Debug_RefreshStackWindow(); + m_Debugger->Debug_RefreshStackTraceWindow(); m_Breakpoints->KeepDebugging(); m_Breakpoints->Resume(); } @@ -1075,6 +1077,7 @@ void CDebugCommandsView::CPUStepInto() void CDebugCommandsView::CPUResume() { m_Debugger->Debug_RefreshStackWindow(); + m_Debugger->Debug_RefreshStackTraceWindow(); m_Breakpoints->StopDebugging(); m_Breakpoints->Resume(); m_RegisterTabs.SetColorsEnabled(false); diff --git a/Source/Project64/N64System/Debugger/Debugger-StackTrace.cpp b/Source/Project64/N64System/Debugger/Debugger-StackTrace.cpp index 01b704793..84961ef50 100644 --- a/Source/Project64/N64System/Debugger/Debugger-StackTrace.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-StackTrace.cpp @@ -12,9 +12,11 @@ #include "stdafx.h" #include "DebuggerUI.h" +#include "Symbols.h" CDebugStackTrace::CDebugStackTrace(CDebuggerUI* debugger) : -CDebugDialog(debugger) +CDebugDialog(debugger), +m_EntriesIndex(0) { } @@ -22,18 +24,43 @@ CDebugStackTrace::~CDebugStackTrace() { } +void CDebugStackTrace::PushEntry(uint32_t routineAddress, uint32_t callingAddress) +{ + if (m_EntriesIndex < STACKTRACE_MAX_ENTRIES) + { + m_Entries[m_EntriesIndex] = { routineAddress, callingAddress }; + m_EntriesIndex++; + } +} + +void CDebugStackTrace::PopEntry() +{ + if (m_EntriesIndex > 0) + { + m_EntriesIndex--; + } +} + +void CDebugStackTrace::ClearEntries() +{ + m_EntriesIndex = 0; +} + LRESULT CDebugStackTrace::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { DlgResize_Init(); - - m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, 0); - + m_List.Attach(GetDlgItem(IDC_STACKTRACE_LIST)); - m_List.AddColumn("Routine", 0); - m_List.AddColumn("Name", 1); + m_List.AddColumn("Caller", 0); + m_List.AddColumn("Routine", 1); + m_List.AddColumn("Name", 2); + - m_List.SetColumnWidth(0, 60); - m_List.SetColumnWidth(1, 100); + m_List.SetColumnWidth(0, 70); + m_List.SetColumnWidth(1, 70); + m_List.SetColumnWidth(2, 160); + + m_List.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT); WindowCreated(); return TRUE; @@ -41,7 +68,7 @@ LRESULT CDebugStackTrace::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM LRESULT CDebugStackTrace::OnActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - RefreshList(); + Refresh(); return FALSE; } @@ -73,32 +100,46 @@ LRESULT CDebugStackTrace::OnListDblClicked(NMHDR* pNMHDR) return 0; } -void CDebugStackTrace::RefreshList() +void CDebugStackTrace::Refresh() { - vector* stackTrace = m_Debugger->StackTrace(); + if (!m_Debugger->Breakpoints()->isDebugging()) + { + return; + } + + SetWindowText(stdstr_f("Stack Trace (%d)", m_EntriesIndex).c_str()); m_List.SetRedraw(FALSE); m_List.DeleteAllItems(); - int count = stackTrace->size(); + CSymbols::EnterCriticalSection(); - if (count > 4000) + for (int i = 0; i < m_EntriesIndex; i++) { - count = 4000; - } - - for (int i = 0; i < count; i++) - { - uint32_t address = stackTrace->at(i); - - char szAddress[9]; - sprintf(szAddress, "%08X", address); + uint32_t routineAddress = m_Entries[i].routineAddress; + uint32_t callingAddress = m_Entries[i].callingAddress; + char szAddress[9]; + sprintf(szAddress, "%08X", callingAddress); m_List.AddItem(i, 0, szAddress); - m_List.AddItem(i, 1, "symbol"); - m_List.SetItemData(i, address); + sprintf(szAddress, "%08X", routineAddress); + m_List.AddItem(i, 1, szAddress); + + CSymbolEntry* symbol = CSymbols::GetEntryByAddress(routineAddress); + if(symbol != NULL) + { + m_List.AddItem(i, 2, symbol->m_Name); + } + else + { + m_List.AddItem(i, 2, ""); + } + + m_List.SetItemData(i, routineAddress); } + CSymbols::LeaveCriticalSection(); + m_List.SetRedraw(TRUE); } \ No newline at end of file diff --git a/Source/Project64/N64System/Debugger/Debugger-StackTrace.h b/Source/Project64/N64System/Debugger/Debugger-StackTrace.h index 8755961b3..e7568e8d8 100644 --- a/Source/Project64/N64System/Debugger/Debugger-StackTrace.h +++ b/Source/Project64/N64System/Debugger/Debugger-StackTrace.h @@ -12,6 +12,13 @@ #pragma once #include "DebuggerUI.h" +#define STACKTRACE_MAX_ENTRIES 100 + +typedef struct { + uint32_t routineAddress; + uint32_t callingAddress; +} STACKTRACE_ENTRY; + class CDebugStackTrace : public CDebugDialog, public CDialogResize @@ -22,10 +29,17 @@ public: CDebugStackTrace(CDebuggerUI * debugger); virtual ~CDebugStackTrace(void); - void RefreshList(); + void Refresh(); + + void PushEntry(uint32_t routineAddress, uint32_t callingAddress); + void PopEntry(); + void ClearEntries(); private: + STACKTRACE_ENTRY m_Entries[STACKTRACE_MAX_ENTRIES]; + int m_EntriesIndex; + HANDLE m_AutoRefreshThread; static DWORD WINAPI AutoRefreshProc(void* _this); diff --git a/Source/Project64/N64System/Debugger/Debugger-StackView.cpp b/Source/Project64/N64System/Debugger/Debugger-StackView.cpp index a911ed663..261ef6172 100644 --- a/Source/Project64/N64System/Debugger/Debugger-StackView.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-StackView.cpp @@ -11,6 +11,7 @@ #include "stdafx.h" #include "DebuggerUI.h" +#include "Symbols.h" CDebugStackView::CDebugStackView(CDebuggerUI * debugger) : CDebugDialog(debugger) @@ -81,6 +82,8 @@ void CDebugStackView::Refresh() m_SPStatic.SetWindowTextA(stdstr_f("SP: %08X", spBase).c_str()); } + CSymbols::EnterCriticalSection(); + for (int i = 0; i < 0x10; i++) { char t[4]; @@ -104,5 +107,7 @@ void CDebugStackView::Refresh() } } + CSymbols::LeaveCriticalSection(); + m_StackList.SetRedraw(TRUE); } \ No newline at end of file diff --git a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp index bb75122d1..134097c62 100644 --- a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp +++ b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.cpp @@ -14,6 +14,9 @@ #include "Symbols.h" #include "DMALog.h" +CDebugMemoryView* CDebugMemoryView::_this = NULL; +HHOOK CDebugMemoryView::hWinMessageHook = NULL; + CDebugMemoryView::CDebugMemoryView(CDebuggerUI * debugger) : CDebugDialog(debugger), m_MemoryList(NULL) @@ -115,10 +118,15 @@ LRESULT CDebugMemoryView::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM m_SymInfo.Attach(GetDlgItem(IDC_SYM_INFO)); m_DMAInfo.Attach(GetDlgItem(IDC_DMA_INFO)); + _this = this; + + DWORD dwThreadID = ::GetCurrentThreadId(); + hWinMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)HookProc, NULL, dwThreadID); + WindowCreated(); m_AutoRefreshThread = CreateThread(NULL, 0, AutoRefreshProc, (void*)this, 0, NULL); - + return TRUE; } @@ -132,6 +140,33 @@ DWORD WINAPI CDebugMemoryView::AutoRefreshProc(void* _this) } } +void CDebugMemoryView::InterceptMouseWheel(WPARAM wParam, LPARAM lParam) +{ + uint32_t newAddress = m_DataStartLoc - ((short)HIWORD(wParam) / WHEEL_DELTA) * 16; + + m_DataStartLoc = newAddress; + + m_MemAddr.SetValue(m_DataStartLoc, false, true); +} + +LRESULT CALLBACK CDebugMemoryView::HookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + MSG *pMsg = (MSG*)lParam; + + if (pMsg->message == WM_MOUSEWHEEL) + { + BOOL bHandled = TRUE; + _this->InterceptMouseWheel(pMsg->wParam, pMsg->lParam); + } + + if (nCode < 0) + { + return CallNextHookEx(hWinMessageHook, nCode, wParam, lParam); + } + + return 0; +} + LRESULT CDebugMemoryView::OnDestroy(void) { if (m_AutoRefreshThread != NULL) @@ -145,6 +180,7 @@ LRESULT CDebugMemoryView::OnDestroy(void) delete m_MemoryList; m_MemoryList = NULL; } + UnhookWindowsHookEx(hWinMessageHook); return 0; } diff --git a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h index 94ed3e6e6..d9ca22813 100644 --- a/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h +++ b/Source/Project64/N64System/Debugger/Debugger-ViewMemory.h @@ -60,6 +60,12 @@ private: enum { MemoryToDisplay = 0x100 }; + static CDebugMemoryView* _this; + static HHOOK hWinMessageHook; + static LRESULT CALLBACK HookProc(int nCode, WPARAM wParam, LPARAM lParam); + + void InterceptMouseWheel(WPARAM wParam, LPARAM lParam); + CEditNumber m_MemAddr; CListCtrl * m_MemoryList; CAddSymbolDlg m_AddSymbolDlg; diff --git a/Source/Project64/N64System/Debugger/Debugger.cpp b/Source/Project64/N64System/Debugger/Debugger.cpp index 5f46360f5..b6f46678c 100644 --- a/Source/Project64/N64System/Debugger/Debugger.cpp +++ b/Source/Project64/N64System/Debugger/Debugger.cpp @@ -27,16 +27,13 @@ CDebuggerUI::CDebuggerUI() : m_Symbols(NULL), m_Breakpoints(NULL), m_ScriptSystem(NULL), - m_DMALogView(NULL), - m_StackTraceView(NULL), + m_StackTrace(NULL), m_StackView(NULL), + m_DMALogView(NULL), m_DMALog(NULL) { g_Debugger = this; - //m_DMALog = new vector; - m_StackTrace = new vector; - m_Breakpoints = new CBreakpoints(); m_ScriptSystem = new CScriptSystem(this); @@ -56,13 +53,12 @@ CDebuggerUI::~CDebuggerUI(void) delete m_ScriptSystem; delete m_Breakpoints; delete m_Symbols; - delete m_DMALogView; delete m_MemorySearch; + delete m_StackTrace; + delete m_DMALogView; delete m_DMALog; CSymbols::DeleteCriticalSection(); - - m_StackTrace->clear(); } void CDebuggerUI::GameReset(CDebuggerUI * _this) @@ -82,15 +78,18 @@ void CDebuggerUI::GameReset(CDebuggerUI * _this) _this->m_DMALog->ClearEntries(); } + if (_this->m_StackTrace) + { + _this->m_StackTrace->ClearEntries(); + } + CSymbols::EnterCriticalSection(); CSymbols::Load(); CSymbols::LeaveCriticalSection(); if (_this->m_Symbols) { - CSymbols::EnterCriticalSection(); _this->m_Symbols->Refresh(); - CSymbols::LeaveCriticalSection(); } } @@ -144,11 +143,11 @@ void CDebuggerUI::Debug_Reset(void) delete m_DMALogView; m_DMALogView = NULL; } - if (m_StackTraceView) + if (m_StackTrace) { - m_StackTraceView->HideWindow(); - delete m_StackTraceView; - m_StackTraceView = NULL; + m_StackTrace->HideWindow(); + delete m_StackTrace; + m_StackTrace = NULL; } if (m_StackView) { @@ -314,11 +313,11 @@ void CDebuggerUI::Debug_ShowDMALogWindow(void) void CDebuggerUI::Debug_ShowStackTrace(void) { - if (m_StackTraceView == NULL) + if (m_StackTrace == NULL) { - m_StackTraceView = new CDebugStackTrace(this); + m_StackTrace = new CDebugStackTrace(this); } - m_StackTraceView->ShowWindow(); + m_StackTrace->ShowWindow(); } void CDebuggerUI::Debug_ShowStackWindow(void) @@ -338,6 +337,14 @@ void CDebuggerUI::Debug_RefreshStackWindow(void) } } +void CDebuggerUI::Debug_RefreshStackTraceWindow(void) +{ + if (m_StackTrace != NULL) + { + m_StackTrace->Refresh(); + } +} + CBreakpoints* CDebuggerUI::Breakpoints() { return m_Breakpoints; @@ -358,16 +365,13 @@ CDMALog* CDebuggerUI::DMALog() return m_DMALog; } -vector * CDebuggerUI::StackTrace() -{ - return m_StackTrace; -} - void CDebuggerUI::BreakpointHit() { m_Breakpoints->KeepDebugging(); Debug_ShowCommandsLocation(g_Reg->m_PROGRAM_COUNTER, false); + Debug_RefreshStackWindow(); + Debug_RefreshStackTraceWindow(); m_Breakpoints->Pause(); } @@ -472,14 +476,23 @@ void CDebuggerUI::CPUStep() OPCODE Opcode = R4300iOp::m_Opcode; uint32_t op = Opcode.op; uint32_t funct = Opcode.funct; - - if (op == R4300i_JAL || funct == R4300i_SPECIAL_JALR) // JAL or JALR + + if (m_StackTrace == NULL) { - //m_StackTrace->push_back(R4300iOp::m_JumpToLocation); + m_StackTrace = new CDebugStackTrace(this); + } + + if (op == R4300i_JAL || ((op == R4300i_SPECIAL) && (funct == R4300i_SPECIAL_JALR) && (Opcode.rd == 31))) // JAL or JALR RA, x + { + m_StackTrace->PushEntry(R4300iOp::m_JumpToLocation, g_Reg->m_PROGRAM_COUNTER); } else if (funct == R4300i_SPECIAL_JR && Opcode.rs == 31) // JR RA { - //m_StackTrace->pop_back(); + m_StackTrace->PopEntry(); + } + else if (op == R4300i_CP0 && funct == R4300i_COP0_CO_ERET) // TODO may need more work + { + m_StackTrace->ClearEntries(); } } diff --git a/Source/Project64/N64System/Debugger/debugger.h b/Source/Project64/N64System/Debugger/debugger.h index 3d7cbf57f..7f9907d7a 100644 --- a/Source/Project64/N64System/Debugger/debugger.h +++ b/Source/Project64/N64System/Debugger/debugger.h @@ -44,13 +44,12 @@ class CDebuggerUI : CDebugScripts * m_Scripts; CDebugSymbols * m_Symbols; CDebugDMALogView * m_DMALogView; - CDebugStackTrace * m_StackTraceView; + CDebugStackTrace * m_StackTrace; CDebugStackView * m_StackView; CBreakpoints * m_Breakpoints; CScriptSystem * m_ScriptSystem; CDMALog * m_DMALog; - vector * m_StackTrace; void BreakpointHit(void); @@ -58,38 +57,38 @@ protected: CDebuggerUI(); virtual ~CDebuggerUI(); - void TLBChanged ( void ); - bool CPUStepStarted ( void ); - void CPUStep ( void ); - void FrameDrawn ( void ); + void TLBChanged ( void ); + bool CPUStepStarted ( void ); + void CPUStep ( void ); + void FrameDrawn ( void ); public: - void Debug_Reset ( void ); - void Debug_ShowMemoryDump ( void ); - void Debug_ShowMemoryWindow ( void ); - void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ); - void Debug_ShowMemorySearch ( void ); - void Debug_ShowTLBWindow ( void ); - void Debug_RefreshTLBWindow ( void ); - void Debug_ShowCommandsWindow ( void ); - void Debug_ShowCommandsLocation ( uint32_t address, bool top ); - void Debug_ShowScriptsWindow ( void ); - void Debug_LogScriptsWindow ( const char* text ); - void Debug_ClearScriptsWindow ( void ); - void Debug_RefreshScriptsWindow ( void ); - void Debug_RefreshSymbolsWindow ( void ); - void Debug_ShowSymbolsWindow ( void ); - void Debug_ShowStackTrace ( void ); - void Debug_ShowStackWindow ( void ); - void Debug_RefreshStackWindow ( void ); - void Debug_ShowDMALogWindow ( void ); + void Debug_Reset ( void ); + void Debug_ShowMemoryDump ( void ); + void Debug_ShowMemoryWindow ( void ); + void Debug_ShowMemoryLocation ( uint32_t Address, bool VAddr ); + void Debug_ShowMemorySearch ( void ); + void Debug_ShowTLBWindow ( void ); + void Debug_RefreshTLBWindow ( void ); + void Debug_ShowCommandsWindow ( void ); + void Debug_ShowCommandsLocation ( uint32_t address, bool top ); + void Debug_ShowScriptsWindow ( void ); + void Debug_LogScriptsWindow ( const char* text ); + void Debug_ClearScriptsWindow ( void ); + void Debug_RefreshScriptsWindow ( void ); + void Debug_RefreshSymbolsWindow ( void ); + void Debug_ShowSymbolsWindow ( void ); + void Debug_ShowStackTrace ( void ); + void Debug_ShowStackWindow ( void ); + void Debug_RefreshStackWindow ( void ); + void Debug_RefreshStackTraceWindow ( void ); + void Debug_ShowDMALogWindow ( void ); CBreakpoints* Breakpoints(); CDebugSymbols* Symbols(); CScriptSystem* ScriptSystem(); CDebugScripts* ScriptConsole(); CDMALog* DMALog(); - vector * StackTrace(); static void GameReset ( CDebuggerUI * _this ); }; diff --git a/Source/Project64/UserInterface/MainMenuClass.cpp b/Source/Project64/UserInterface/MainMenuClass.cpp index 7859f9b91..65f8d3759 100644 --- a/Source/Project64/UserInterface/MainMenuClass.cpp +++ b/Source/Project64/UserInterface/MainMenuClass.cpp @@ -1154,7 +1154,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu) /* Debug - Stack Trace *******************/ Item.Reset(ID_DEBUGGER_STACKTRACE, EMPTY_STRING, EMPTY_STDSTR, NULL, L"Stack Trace..."); - Item.SetItemEnabled(false); DebugMenu.push_back(Item); DebugMenu.push_back(MENU_ITEM(SPLITER)); diff --git a/Source/Project64/UserInterface/UIResources.rc b/Source/Project64/UserInterface/UIResources.rc index b4a02c4a0..4e1c2e0b3 100644 --- a/Source/Project64/UserInterface/UIResources.rc +++ b/Source/Project64/UserInterface/UIResources.rc @@ -961,12 +961,12 @@ BEGIN LTEXT "Block:",IDC_BLOCK_INFO,9,200,168,8 END -IDD_Debugger_StackTrace DIALOGEX 0, 0, 199, 167 +IDD_Debugger_StackTrace DIALOGEX 0, 0, 223, 221 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME CAPTION "Stack Trace" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "",IDC_STACKTRACE_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,0,0,199,167 + CONTROL "",IDC_STACKTRACE_LIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_TABSTOP,0,0,224,221 END IDD_Debugger_RegCOP0 DIALOGEX 0, 0, 190, 210 @@ -1589,8 +1589,6 @@ BEGIN IDD_Debugger_StackTrace, DIALOG BEGIN - TOPMARGIN, 7 - BOTTOMMARGIN, 160 END IDD_Debugger_RegCOP0, DIALOG