mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Move the temporary breakpoint out of the user's breakpoint list
step-over, step-out and run-until plant a one-shot breakpoint at the address they want execution to return to. Keeping it in breakPoints_ alongside the user's own meant the two kept colliding: - Adding a log-only user breakpoint at the same address hijacked the temporary one. AddBreakPoint() didn't match across temp-ness so both existed, and then ChangeBreakPoint() looked up "the first enabled breakpoint at this address" - a log-only breakpoint isn't enabled, so the temporary one won and had its action overwritten to log-only. It lost PAUSE and the step never came back. - RemoveBreakPoint() erased up to two entries per address to catch an overlapping temporary one, so deleting either deleted both - including the interpreter's cleanup path in CheckExecBreakpoints() taking the user's breakpoint with it. - ExecBreakPoint() handled one breakpoint per address, so with both at the same address only one of them did anything: the step completed but the user's log line never printed. - Nothing dropped it when something *else* stopped us first, so an interrupted step left a breakpoint armed at an address nobody was waiting for anymore, which later fired as a phantom stop. It's a single TempBreakPoint member now, invisible to the breakpoint lists and untouched by user edits. One is enough: step over/out and cross-thread step into all require the CPU to already be stepping and resume it immediately, so only one can be in flight, and run-until now replaces rather than stacking (two pending run-untils had no coherent meaning, and the loser stayed armed). Behavior follows what other debuggers do. Both breakpoints at an address are evaluated independently and their actions combine, so a log-only breakpoint logs without stopping and still lets the step finish. Core_Break() drops the temporary breakpoint on any stop, whatever the reason - the same way gdb deletes its step-resume breakpoint and lldb discards the thread plan. Two things to be careful of, both covered by the new TempBreakpoints test: HasBreakPoints() has to account for it, or the interpreter's checked run loop and the JIT skip breakpoint checking entirely and a step with no user breakpoints set never returns; and IsAddressBreakPoint() (user-facing, for the lists and disassembly markers) is now separate from NeedsBreakCheckAt() (what the JIT frontends and interpreter ask), since only the latter should see it. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
1 parent
0c510ca62e
commit
35a91b757a
16 files changed
+258
-119
No files matched your search
@@ -234,7 +234,7 @@ void BreakpointWindow::addBreakpoint() {
|
||||
}
|
||||
else {
|
||||
// add breakpoint
|
||||
g_breakpoints.AddBreakPoint(address, false);
|
||||
g_breakpoints.AddBreakPoint(address);
|
||||
|
||||
if (!condition.empty()) {
|
||||
BreakPointCond cond;
|
||||
|
||||
@@ -223,7 +223,7 @@ void CDisasm::runToLine() {
|
||||
ptr->setDontRedraw(true);
|
||||
// Route the breakpoint mutation to the CPU thread instead of poking at it directly from this
|
||||
// GUI thread - see Core_RunOnCPUThread() in Core.h. Core_Resume() itself is free-threaded.
|
||||
Core_RunOnCPUThread([&] { breakpoints_->AddBreakPoint(pos,true); });
|
||||
Core_RunOnCPUThread([&] { breakpoints_->SetTempBreakPoint(pos); });
|
||||
Core_Resume();
|
||||
}
|
||||
|
||||
|
||||
@@ -444,13 +444,8 @@ void CtrlBreakpointList::removeBreakpoint(int itemIndex)
|
||||
}
|
||||
|
||||
int CtrlBreakpointList::getTotalBreakpointCount() {
|
||||
int count = (int)displayedMemChecks_.size();
|
||||
for (auto bp : displayedBreakPoints_) {
|
||||
if (!bp.temporary)
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
// displayedBreakPoints_ never contains the internal step-over/run-until breakpoint.
|
||||
return (int)displayedMemChecks_.size() + (int)displayedBreakPoints_.size();
|
||||
}
|
||||
|
||||
int CtrlBreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory)
|
||||
@@ -467,12 +462,6 @@ int CtrlBreakpointList::getBreakpointIndex(int itemIndex, bool& isMemory)
|
||||
size_t i = 0;
|
||||
while (i < displayedBreakPoints_.size())
|
||||
{
|
||||
if (displayedBreakPoints_[i].temporary)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// the index is 0 when there are no more breakpoints to skip
|
||||
if (itemIndex == 0)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user