Debugger enhancements:
* Added working Step Over function. * Added hard-coded hotkeys for step into (F11), step over (F10) and toggle breakpoint (F9). The hotkeys are only active when the debugger is enabled. They function as before when the debugger is disabled. * Added Debug menu item. * Removed obsolete NotifyBreakpoint function from JIT and JITIL. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6069 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
7b8863dc9c
commit
208ecd698e
|
@ -113,14 +113,12 @@ bool PPCDebugInterface::isBreakpoint(unsigned int address)
|
||||||
|
|
||||||
void PPCDebugInterface::setBreakpoint(unsigned int address)
|
void PPCDebugInterface::setBreakpoint(unsigned int address)
|
||||||
{
|
{
|
||||||
if (PowerPC::breakpoints.Add(address))
|
PowerPC::breakpoints.Add(address);
|
||||||
jit->NotifyBreakpoint(address, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCDebugInterface::clearBreakpoint(unsigned int address)
|
void PPCDebugInterface::clearBreakpoint(unsigned int address)
|
||||||
{
|
{
|
||||||
if (PowerPC::breakpoints.Remove(address))
|
PowerPC::breakpoints.Remove(address);
|
||||||
jit->NotifyBreakpoint(address, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPCDebugInterface::clearAllBreakpoints() {}
|
void PPCDebugInterface::clearAllBreakpoints() {}
|
||||||
|
|
|
@ -265,15 +265,6 @@ void Jit64::DoNothing(UGeckoInstruction _inst)
|
||||||
// Yup, just don't do anything.
|
// Yup, just don't do anything.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::NotifyBreakpoint(u32 em_address, bool set)
|
|
||||||
{
|
|
||||||
int block_num = blocks.GetBlockNumberFromStartAddress(em_address);
|
|
||||||
if (block_num >= 0)
|
|
||||||
{
|
|
||||||
blocks.DestroyBlock(block_num, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool ImHereDebug = false;
|
static const bool ImHereDebug = false;
|
||||||
static const bool ImHereLog = false;
|
static const bool ImHereLog = false;
|
||||||
static std::map<u32, int> been_here;
|
static std::map<u32, int> been_here;
|
||||||
|
|
|
@ -115,7 +115,6 @@ public:
|
||||||
|
|
||||||
JitBlockCache *GetBlockCache() { return &blocks; }
|
JitBlockCache *GetBlockCache() { return &blocks; }
|
||||||
|
|
||||||
void NotifyBreakpoint(u32 em_address, bool set);
|
|
||||||
void Trace();
|
void Trace();
|
||||||
|
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
|
@ -256,15 +256,6 @@ void JitIL::DoNothing(UGeckoInstruction _inst)
|
||||||
// Yup, just don't do anything.
|
// Yup, just don't do anything.
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::NotifyBreakpoint(u32 em_address, bool set)
|
|
||||||
{
|
|
||||||
int block_num = blocks.GetBlockNumberFromStartAddress(em_address);
|
|
||||||
if (block_num >= 0)
|
|
||||||
{
|
|
||||||
blocks.DestroyBlock(block_num, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool ImHereDebug = false;
|
static const bool ImHereDebug = false;
|
||||||
static const bool ImHereLog = false;
|
static const bool ImHereLog = false;
|
||||||
static std::map<u32, int> been_here;
|
static std::map<u32, int> been_here;
|
||||||
|
|
|
@ -84,7 +84,6 @@ public:
|
||||||
void Jit(u32 em_address);
|
void Jit(u32 em_address);
|
||||||
const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b);
|
const u8* DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buffer, JitBlock *b);
|
||||||
|
|
||||||
void NotifyBreakpoint(u32 em_address, bool set);
|
|
||||||
void Trace();
|
void Trace();
|
||||||
|
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
|
|
|
@ -92,7 +92,6 @@ public:
|
||||||
virtual void ClearCache() = 0;
|
virtual void ClearCache() = 0;
|
||||||
virtual void Run() = 0;
|
virtual void Run() = 0;
|
||||||
virtual void SingleStep() = 0;
|
virtual void SingleStep() = 0;
|
||||||
virtual void NotifyBreakpoint(u32 em_address, bool set) = 0;
|
|
||||||
|
|
||||||
const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx);
|
const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx);
|
||||||
|
|
||||||
|
|
|
@ -123,15 +123,21 @@ void CCodeView::OnMouseDown(wxMouseEvent& event)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debugger->toggleBreakpoint(YToAddress(y));
|
ToggleBreakpoint(YToAddress(y));
|
||||||
redraw();
|
|
||||||
Host_UpdateBreakPointView();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Skip(true);
|
event.Skip(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CCodeView::ToggleBreakpoint(u32 address)
|
||||||
|
{
|
||||||
|
debugger->toggleBreakpoint(address);
|
||||||
|
redraw();
|
||||||
|
Host_UpdateBreakPointView();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void CCodeView::OnMouseMove(wxMouseEvent& event)
|
void CCodeView::OnMouseMove(wxMouseEvent& event)
|
||||||
{
|
{
|
||||||
wxRect rc = GetClientRect();
|
wxRect rc = GetClientRect();
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
void InsertBlrNop(int);
|
void InsertBlrNop(int);
|
||||||
|
|
||||||
u32 GetSelection() {return(selection);}
|
u32 GetSelection() {return(selection);}
|
||||||
|
void ToggleBreakpoint(u32 address);
|
||||||
|
|
||||||
struct BlrStruct // for IDM_INSERTBLR
|
struct BlrStruct // for IDM_INSERTBLR
|
||||||
{
|
{
|
||||||
|
|
|
@ -116,6 +116,7 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxPanel)
|
||||||
// Toolbar
|
// Toolbar
|
||||||
EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep)
|
EVT_MENU(IDM_STEP, CCodeWindow::OnCodeStep)
|
||||||
EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep)
|
EVT_MENU(IDM_STEPOVER, CCodeWindow::OnCodeStep)
|
||||||
|
EVT_MENU(IDM_TOGGLE_BREAKPOINT, CCodeWindow::OnCodeStep)
|
||||||
EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep)
|
EVT_MENU(IDM_SKIP, CCodeWindow::OnCodeStep)
|
||||||
EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep)
|
EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep)
|
||||||
EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep)
|
EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep)
|
||||||
|
@ -167,9 +168,10 @@ wxAuiToolBar *CCodeWindow::GetToolBar()
|
||||||
|
|
||||||
void CCodeWindow::OnKeyDown(wxKeyEvent& event)
|
void CCodeWindow::OnKeyDown(wxKeyEvent& event)
|
||||||
{
|
{
|
||||||
event.Skip();
|
if (event.GetKeyCode() == WXK_SPACE && event.GetModifiers() == wxMOD_NONE)
|
||||||
|
SingleStep();
|
||||||
if ((event.GetKeyCode() == WXK_SPACE) && Parent->IsActive()) SingleCPUStep();
|
else
|
||||||
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
||||||
|
@ -199,13 +201,17 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
|
||||||
switch (event.GetId())
|
switch (event.GetId())
|
||||||
{
|
{
|
||||||
case IDM_STEP:
|
case IDM_STEP:
|
||||||
SingleCPUStep();
|
SingleStep();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_STEPOVER:
|
case IDM_STEPOVER:
|
||||||
CCPU::EnableStepping(true); // TODO: Huh?
|
StepOver();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IDM_TOGGLE_BREAKPOINT:
|
||||||
|
ToggleBreakpoint();
|
||||||
|
break;
|
||||||
|
|
||||||
case IDM_SKIP:
|
case IDM_SKIP:
|
||||||
PC += 4;
|
PC += 4;
|
||||||
Update();
|
Update();
|
||||||
|
@ -289,14 +295,47 @@ void CCodeWindow::OnCallsListChange(wxCommandEvent& event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeWindow::SingleCPUStep()
|
void CCodeWindow::SingleStep()
|
||||||
{
|
{
|
||||||
CCPU::StepOpcode(&sync_event);
|
if (CCPU::IsStepping())
|
||||||
wxThread::Sleep(20);
|
{
|
||||||
// need a short wait here
|
CCPU::StepOpcode(&sync_event);
|
||||||
JumpToAddress(PC);
|
wxThread::Sleep(20);
|
||||||
Update();
|
// need a short wait here
|
||||||
Host_UpdateLogDisplay();
|
JumpToAddress(PC);
|
||||||
|
Update();
|
||||||
|
Host_UpdateLogDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCodeWindow::StepOver()
|
||||||
|
{
|
||||||
|
if (CCPU::IsStepping())
|
||||||
|
{
|
||||||
|
UGeckoInstruction inst = Memory::Read_Instruction(PC);
|
||||||
|
if (inst.LK)
|
||||||
|
{
|
||||||
|
PowerPC::breakpoints.Add(PC + 4, true);
|
||||||
|
CCPU::EnableStepping(false);
|
||||||
|
JumpToAddress(PC);
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SingleStep();
|
||||||
|
|
||||||
|
UpdateButtonStates();
|
||||||
|
// Update all toolbars in the aui manager
|
||||||
|
Parent->UpdateGUI();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCodeWindow::ToggleBreakpoint()
|
||||||
|
{
|
||||||
|
if (CCPU::IsStepping())
|
||||||
|
{
|
||||||
|
if (codeview) codeview->ToggleBreakpoint(codeview->GetSelection());
|
||||||
|
Update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCodeWindow::UpdateLists()
|
void CCodeWindow::UpdateLists()
|
||||||
|
@ -439,6 +478,16 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
|
||||||
|
|
||||||
pMenuBar->Append(pCoreMenu, _T("&JIT"));
|
pMenuBar->Append(pCoreMenu, _T("&JIT"));
|
||||||
|
|
||||||
|
|
||||||
|
// Debug Menu
|
||||||
|
wxMenu* pDebugMenu = new wxMenu;
|
||||||
|
|
||||||
|
wxMenuItem* stepinto = pDebugMenu->Append(IDM_STEP, _T("Step &Into\tF11"));
|
||||||
|
wxMenuItem* stepover = pDebugMenu->Append(IDM_STEPOVER, _T("Step &Over\tF10"));
|
||||||
|
wxMenuItem* togglebreakpoint = pDebugMenu->Append(IDM_TOGGLE_BREAKPOINT, _T("Toggle &Breakpoint\tF9"));
|
||||||
|
|
||||||
|
pMenuBar->Append(pDebugMenu, _T("&Debug"));
|
||||||
|
|
||||||
CreateMenuSymbols(pMenuBar);
|
CreateMenuSymbols(pMenuBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -129,9 +129,13 @@ class CCodeWindow
|
||||||
void OnCallersListChange(wxCommandEvent& event);
|
void OnCallersListChange(wxCommandEvent& event);
|
||||||
void OnCallsListChange(wxCommandEvent& event);
|
void OnCallsListChange(wxCommandEvent& event);
|
||||||
void OnCodeViewChange(wxCommandEvent &event);
|
void OnCodeViewChange(wxCommandEvent &event);
|
||||||
void SingleCPUStep();
|
|
||||||
void OnHostMessage(wxCommandEvent& event);
|
void OnHostMessage(wxCommandEvent& event);
|
||||||
|
|
||||||
|
// Debugger functions
|
||||||
|
void SingleStep();
|
||||||
|
void StepOver();
|
||||||
|
void ToggleBreakpoint();
|
||||||
|
|
||||||
void UpdateLists();
|
void UpdateLists();
|
||||||
void UpdateCallstack();
|
void UpdateCallstack();
|
||||||
void OnKeyDown(wxKeyEvent& event);
|
void OnKeyDown(wxKeyEvent& event);
|
||||||
|
|
|
@ -738,6 +738,9 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
|
||||||
// Toggle fullscreen
|
// Toggle fullscreen
|
||||||
if (IsHotkey(event, HK_FULLSCREEN))
|
if (IsHotkey(event, HK_FULLSCREEN))
|
||||||
DoFullscreen(!RendererIsFullscreen());
|
DoFullscreen(!RendererIsFullscreen());
|
||||||
|
// Send Debugger keys to CodeWindow
|
||||||
|
else if (g_pCodeWindow && (event.GetKeyCode() >= WXK_F9 && event.GetKeyCode() <= WXK_F11))
|
||||||
|
event.Skip();
|
||||||
// Pause and Unpause
|
// Pause and Unpause
|
||||||
else if (IsHotkey(event, HK_PLAY_PAUSE))
|
else if (IsHotkey(event, HK_PLAY_PAUSE))
|
||||||
DoPause();
|
DoPause();
|
||||||
|
|
|
@ -157,7 +157,13 @@ void CFrame::CreateMenu()
|
||||||
saveMenu->AppendSeparator();
|
saveMenu->AppendSeparator();
|
||||||
|
|
||||||
loadMenu->Append(IDM_LOADSTATEFILE, _T("Load State..."));
|
loadMenu->Append(IDM_LOADSTATEFILE, _T("Load State..."));
|
||||||
loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State\tF11"));
|
|
||||||
|
// Reserve F11 for the "step into" function in the debugger
|
||||||
|
if (g_pCodeWindow)
|
||||||
|
loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State"));
|
||||||
|
else
|
||||||
|
loadMenu->Append(IDM_LOADLASTSTATE, _T("Last Saved State\tF11"));
|
||||||
|
|
||||||
loadMenu->Append(IDM_UNDOLOADSTATE, _T("Undo Load State\tF12"));
|
loadMenu->Append(IDM_UNDOLOADSTATE, _T("Undo Load State\tF12"));
|
||||||
loadMenu->AppendSeparator();
|
loadMenu->AppendSeparator();
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,7 @@ enum
|
||||||
ID_TOOLBAR_DEBUG,
|
ID_TOOLBAR_DEBUG,
|
||||||
IDM_STEP,
|
IDM_STEP,
|
||||||
IDM_STEPOVER,
|
IDM_STEPOVER,
|
||||||
|
IDM_TOGGLE_BREAKPOINT,
|
||||||
IDM_SKIP,
|
IDM_SKIP,
|
||||||
IDM_SETPC,
|
IDM_SETPC,
|
||||||
IDM_GOTOPC,
|
IDM_GOTOPC,
|
||||||
|
|
Loading…
Reference in New Issue