diff options
| author | Anthony <Helios747@users.noreply.github.com> | 2016-12-01 13:32:44 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-12-01 13:32:44 -0600 |
| commit | 0705c53681fceb1f0b8c33b8d498f7b8507d60c6 (patch) | |
| tree | 73e5d8bf79e7695619e04b6a43e8a67cf57621e8 /Source/Core/DolphinWX/Debugger/CodeWindow.cpp | |
| parent | 4baa368f8bfc0f47e92b002483db9a5e581ea003 (diff) | |
| parent | 744b993dcd9184e3c665a68e72857e5348e260c5 (diff) | |
Merge pull request #4340 from sepalani/step_timeout
CodeWindow: Fix step out issues
Diffstat (limited to 'Source/Core/DolphinWX/Debugger/CodeWindow.cpp')
| -rw-r--r-- | Source/Core/DolphinWX/Debugger/CodeWindow.cpp | 51 |
1 files changed, 34 insertions, 17 deletions
diff --git a/Source/Core/DolphinWX/Debugger/CodeWindow.cpp b/Source/Core/DolphinWX/Debugger/CodeWindow.cpp index 1465437152..4305d24da6 100644 --- a/Source/Core/DolphinWX/Debugger/CodeWindow.cpp +++ b/Source/Core/DolphinWX/Debugger/CodeWindow.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <array> +#include <chrono> #include <cstdio> #include <string> #include <vector> @@ -302,6 +303,7 @@ void CCodeWindow::SingleStep() CPU::StepOpcode(&sync_event); sync_event.WaitFor(std::chrono::milliseconds(20)); PowerPC::SetMode(old_mode); + Core::DisplayMessage(_("Step successful!").ToStdString(), 2000); // Will get a IDM_UPDATE_DISASM_DIALOG. Don't update the GUI here. } } @@ -316,6 +318,7 @@ void CCodeWindow::StepOver() PowerPC::breakpoints.ClearAllTemporary(); PowerPC::breakpoints.Add(PC + 4, true); CPU::EnableStepping(false); + Core::DisplayMessage(_("Step over in progress...").ToStdString(), 2000); } else { @@ -324,9 +327,12 @@ void CCodeWindow::StepOver() } } -// Returns true on a blr or on a bclr that evaluates to true. +// Returns true on a rfi, blr or on a bclr that evaluates to true. static bool WillInstructionReturn(UGeckoInstruction inst) { + // Is a rfi instruction + if (inst.hex == 0x4C000064u) + return true; bool counter = (inst.BO_2 >> 2 & 1) != 0 || (CTR != 0) != ((inst.BO_2 >> 1 & 1) != 0); bool condition = inst.BO_2 >> 4 != 0 || GetCRBit(inst.BI_2) == (inst.BO_2 >> 3 & 1); bool isBclr = inst.OPCD_7 == 0b010011 && (inst.hex >> 1 & 0b10000) != 0; @@ -340,44 +346,55 @@ void CCodeWindow::StepOut() CPU::PauseAndLock(true, false); PowerPC::breakpoints.ClearAllTemporary(); - // Keep stepping until the next return instruction or timeout after one second - u64 timeout = SystemTimers::GetTicksPerSecond(); - u64 steps = 0; + // Keep stepping until the next return instruction or timeout after five seconds + using clock = std::chrono::steady_clock; + clock::time_point timeout = clock::now() + std::chrono::seconds(5); PowerPC::CoreMode old_mode = PowerPC::GetMode(); PowerPC::SetMode(PowerPC::MODE_INTERPRETER); - UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC); + // Loop until either the current instruction is a return instruction with no Link flag - // or a breakpoint is detected so it can step at the breakpoint. - while (!(WillInstructionReturn(inst)) && steps < timeout && - !PowerPC::breakpoints.IsAddressBreakPoint(PC)) + // or a breakpoint is detected so it can step at the breakpoint. If the PC is currently + // on a breakpoint, skip it. + UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC); + do { + if (WillInstructionReturn(inst)) + { + PowerPC::SingleStep(); + break; + } + if (inst.LK) { // Step over branches u32 next_pc = PC + 4; - while (PC != next_pc && steps < timeout) + do { PowerPC::SingleStep(); - ++steps; - } + } while (PC != next_pc && clock::now() < timeout && + !PowerPC::breakpoints.IsAddressBreakPoint(PC)); } else { PowerPC::SingleStep(); - ++steps; } + inst = PowerPC::HostRead_Instruction(PC); - } - // If the loop stopped because of a breakpoint, we do not want to step to - // an instruction after it. - if (!PowerPC::breakpoints.IsAddressBreakPoint(PC)) - PowerPC::SingleStep(); + } while (clock::now() < timeout && !PowerPC::breakpoints.IsAddressBreakPoint(PC)); + PowerPC::SetMode(old_mode); CPU::PauseAndLock(false, false); wxCommandEvent ev(wxEVT_HOST_COMMAND, IDM_UPDATE_DISASM_DIALOG); GetEventHandler()->ProcessEvent(ev); + if (PowerPC::breakpoints.IsAddressBreakPoint(PC)) + Core::DisplayMessage(_("Breakpoint encountered! Step out aborted.").ToStdString(), 2000); + else if (clock::now() >= timeout) + Core::DisplayMessage(_("Step out timed out!").ToStdString(), 2000); + else + Core::DisplayMessage(_("Step out successful!").ToStdString(), 2000); + // Update all toolbars in the aui manager Parent->UpdateGUI(); } |
