[ 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_;