[vm,dyn_modules] Fix stepping over when debugging the interpreter.

Since any instruction is a possible pause point when single stepping in
the interpreter, the debugger may pause too early when stepping over an
expression; for example, if the value returned from an expression is
ignored, stepping over the expression should also step over the
following Drop1 instruction (which will have the same source location),
but currently does not.

To avoid this, set last_stepping_fp_ and last_stepping_pos_ when
stepping over either a sync or async expression so that the debugger
won't pause until a new source position is reached.

TEST=pkg/vm_service/test

Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try,vm-dyn-mac-debug-arm64-try
Change-Id: I0934f6bda3fc075a225a85b66eccf46b94cb4020
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/449420
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
This commit is contained in:
Tess Strickland
2025-09-15 04:29:39 -07:00
committed by Commit Queue
parent 68516556da
commit 2871699e89
+16
View File
@@ -3091,6 +3091,16 @@ void Debugger::ResumptionBreakpoint() {
"ResumptionBreakpoint - hit a breakpoint, continue single "
"stepping\n");
}
#if defined(DART_DYNAMIC_MODULES)
if (top_frame->IsInterpreted()) {
// The interpreter calls the single step handler on every instruction,
// so set the last stepping fp/position to the current fp/position when
// stepping over so the debugger doesn't pause until it reaches
// a _new_ source position.
last_stepping_fp_ = top_frame->fp();
last_stepping_pos_ = top_frame->TokenPos();
}
#endif
EnterSingleStepMode();
return;
}
@@ -3416,6 +3426,12 @@ void Debugger::SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace) {
stepping_fp_ = frame->fp();
#if defined(DART_DYNAMIC_MODULES)
stepping_fp_from_interpreted_frame_ = frame->IsInterpreted();
// The interpreter calls the single step handler on every instruction,
// so set the last stepping fp/position to the current fp/position when
// stepping over so the debugger doesn't pause until it reaches
// a _new_ source position.
last_stepping_fp_ = frame->fp();
last_stepping_pos_ = frame->TokenPos();
#endif
} else {
stepping_fp_ = 0;