[ VM / Debugger ] Fix issue where a 'Step' command issued when there's no stack caused a crash.
For example, running this sample, pausing the isolate, and stepping
would crash, whereas we would expect to pause in the ServerSocket.listen
callback.
```
import 'dart:io';
main() {
ServerSocket.bind('127.0.0.1', 22000).then((s) {
s.listen((m) { // Should pause here on socket connection after step.
print(m);
});
});
}
```
Fixes #35601.
Change-Id: I2155de1cface159f92734d3112b6e17c35ab7550
Reviewed-on: https://dart-review.googlesource.com/c/89780
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 1153d2c..f78316d 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -3174,19 +3174,27 @@
}
}
-void Debugger::SetAsyncSteppingFramePointer() {
+void Debugger::SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace) {
if (!FLAG_async_debugger) {
return;
}
- if ((stack_trace_->Length()) > 0 &&
- (stack_trace_->FrameAt(0)->function().IsAsyncClosure() ||
- stack_trace_->FrameAt(0)->function().IsAsyncGenClosure())) {
- async_stepping_fp_ = stack_trace_->FrameAt(0)->fp();
+ if ((stack_trace->Length()) > 0 &&
+ (stack_trace->FrameAt(0)->function().IsAsyncClosure() ||
+ stack_trace->FrameAt(0)->function().IsAsyncGenClosure())) {
+ async_stepping_fp_ = stack_trace->FrameAt(0)->fp();
} else {
async_stepping_fp_ = 0;
}
}
+void Debugger::SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace) {
+ if (stack_trace->Length() > 0) {
+ stepping_fp_ = stack_trace->FrameAt(0)->fp();
+ } else {
+ stepping_fp_ = 0;
+ }
+}
+
void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace,
bool skip_next_step) {
ResetSteppingFramePointers();
@@ -3200,7 +3208,7 @@
DeoptimizeWorld();
isolate_->set_single_step(true);
skip_next_step_ = skip_next_step;
- SetAsyncSteppingFramePointer();
+ SetAsyncSteppingFramePointer(stack_trace);
if (FLAG_verbose_debug) {
OS::PrintErr("HandleSteppingRequest- kStepInto\n");
}
@@ -3208,9 +3216,8 @@
DeoptimizeWorld();
isolate_->set_single_step(true);
skip_next_step_ = skip_next_step;
- ASSERT(stack_trace->Length() > 0);
- stepping_fp_ = stack_trace->FrameAt(0)->fp();
- SetAsyncSteppingFramePointer();
+ SetSyncSteppingFramePointer(stack_trace);
+ SetAsyncSteppingFramePointer(stack_trace);
if (FLAG_verbose_debug) {
OS::PrintErr("HandleSteppingRequest- kStepOver %" Px "\n", stepping_fp_);
}
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 3e1a0c0..759a180 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -720,7 +720,8 @@
bool SteppedForSyntheticAsyncBreakpoint() const;
void CleanupSyntheticAsyncBreakpoint();
void RememberTopFrameAwaiter();
- void SetAsyncSteppingFramePointer();
+ void SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
+ void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
Isolate* isolate_;