| Index: runtime/vm/debugger.h
|
| diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
|
| index fa9c3a61466776e9cf319922d508f8806b11296c..7bd5d2878a3088daece976aee7f7ece8ce24e046 100644
|
| --- a/runtime/vm/debugger.h
|
| +++ b/runtime/vm/debugger.h
|
| @@ -11,6 +11,18 @@
|
| #include "vm/port.h"
|
| #include "vm/service_event.h"
|
|
|
| +DECLARE_FLAG(bool, verbose_debug);
|
| +
|
| +// 'Trace Debugger' TD_Print.
|
| +#if defined(_MSC_VER)
|
| +#define TD_Print(format, ...) \
|
| + if (FLAG_verbose_debug) Log::Current()->Print(format, __VA_ARGS__)
|
| +#else
|
| +#define TD_Print(format, ...) \
|
| + if (FLAG_verbose_debug) Log::Current()->Print(format, ##__VA_ARGS__)
|
| +#endif
|
| +
|
| +
|
| namespace dart {
|
|
|
| class CodeBreakpoint;
|
| @@ -245,12 +257,23 @@ class CodeBreakpoint {
|
| // on the call stack.
|
| class ActivationFrame : public ZoneAllocated {
|
| public:
|
| + enum Kind {
|
| + kRegular,
|
| + kAsyncSuspensionMarker,
|
| + kAsyncCausal,
|
| + };
|
| +
|
| ActivationFrame(uword pc,
|
| uword fp,
|
| uword sp,
|
| const Code& code,
|
| const Array& deopt_frame,
|
| - intptr_t deopt_frame_offset);
|
| + intptr_t deopt_frame_offset,
|
| + Kind kind = kRegular);
|
| +
|
| + ActivationFrame(uword pc, const Code& code);
|
| +
|
| + explicit ActivationFrame(Kind kind);
|
|
|
| uword pc() const { return pc_; }
|
| uword fp() const { return fp_; }
|
| @@ -311,6 +334,10 @@ class ActivationFrame : public ZoneAllocated {
|
| void PrintToJSONObject(JSONObject* jsobj, bool full = false);
|
|
|
| private:
|
| + void PrintToJSONObjectRegular(JSONObject* jsobj, bool full);
|
| + void PrintToJSONObjectAsyncCausal(JSONObject* jsobj, bool full);
|
| + void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, bool full);
|
| +
|
| void PrintContextMismatchError(intptr_t ctx_slot,
|
| intptr_t frame_ctx_level,
|
| intptr_t var_ctx_level);
|
| @@ -320,6 +347,20 @@ class ActivationFrame : public ZoneAllocated {
|
| void GetVarDescriptors();
|
| void GetDescIndices();
|
|
|
| + static const char* KindToCString(Kind kind) {
|
| + switch (kind) {
|
| + case kRegular:
|
| + return "kRegular";
|
| + case kAsyncCausal:
|
| + return "kAsyncCausal";
|
| + case kAsyncSuspensionMarker:
|
| + return "kAsyncSuspensionMarker";
|
| + default:
|
| + UNREACHABLE();
|
| + return "";
|
| + }
|
| + }
|
| +
|
| RawObject* GetStackVar(intptr_t slot_index);
|
| RawObject* GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
|
|
|
| @@ -329,8 +370,9 @@ class ActivationFrame : public ZoneAllocated {
|
|
|
| // The anchor of the context chain for this function.
|
| Context& ctx_;
|
| - const Code& code_;
|
| - const Function& function_;
|
| + Code& code_;
|
| + Function& function_;
|
| + bool live_frame_; // Is this frame a live frame?
|
| bool token_pos_initialized_;
|
| TokenPosition token_pos_;
|
| intptr_t try_index_;
|
| @@ -343,6 +385,8 @@ class ActivationFrame : public ZoneAllocated {
|
| const Array& deopt_frame_;
|
| const intptr_t deopt_frame_offset_;
|
|
|
| + Kind kind_;
|
| +
|
| bool vars_initialized_;
|
| LocalVarDescriptors& var_descriptors_;
|
| ZoneGrowableArray<intptr_t> desc_indices_;
|
| @@ -367,6 +411,9 @@ class DebuggerStackTrace : public ZoneAllocated {
|
|
|
| private:
|
| void AddActivation(ActivationFrame* frame);
|
| + void AddMarker(ActivationFrame::Kind marker);
|
| + void AddAsyncCausalFrame(uword pc, const Code& code);
|
| +
|
| ZoneGrowableArray<ActivationFrame*> trace_;
|
|
|
| friend class Debugger;
|
| @@ -470,6 +517,9 @@ class Debugger {
|
| DebuggerStackTrace* StackTrace();
|
| DebuggerStackTrace* CurrentStackTrace();
|
|
|
| + DebuggerStackTrace* AsyncCausalStackTrace();
|
| + DebuggerStackTrace* CurrentAsyncCausalStackTrace();
|
| +
|
| // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
|
| // Frames corresponding to invisible functions are omitted. It is not valid
|
| // to query local variables in the returned stack.
|
| @@ -530,6 +580,10 @@ class Debugger {
|
| private:
|
| RawError* PauseRequest(ServiceEvent::EventKind kind);
|
|
|
| + // Finds the breakpoint we hit at |location|.
|
| + Breakpoint* FindHitBreakpoint(BreakpointLocation* location,
|
| + ActivationFrame* top_frame);
|
| +
|
| // Will return false if we are not at an await.
|
| bool SetupStepOverAsyncSuspension(const char** error);
|
|
|
| @@ -583,7 +637,18 @@ class Debugger {
|
| static RawArray* DeoptimizeToArray(Thread* thread,
|
| StackFrame* frame,
|
| const Code& code);
|
| + // Appends at least one stack frame. Multiple frames will be appended
|
| + // if |code| at the frame's pc contains inlined functions.
|
| + static void AppendCodeFrames(Thread* thread,
|
| + Isolate* isolate,
|
| + Zone* zone,
|
| + DebuggerStackTrace* stack_trace,
|
| + StackFrame* frame,
|
| + Code* code,
|
| + Code* inlined_code,
|
| + Array* deopt_frame);
|
| static DebuggerStackTrace* CollectStackTrace();
|
| + static DebuggerStackTrace* CollectAsyncCausalStackTrace();
|
| void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);
|
|
|
| intptr_t nextId() { return next_id_++; }
|
| @@ -603,6 +668,11 @@ class Debugger {
|
| void HandleSteppingRequest(DebuggerStackTrace* stack_trace,
|
| bool skip_next_step = false);
|
|
|
| + void CacheStackTraces(DebuggerStackTrace* stack_trace,
|
| + DebuggerStackTrace* async_causal_stack_trace);
|
| + void ClearCachedStackTraces();
|
| +
|
| +
|
| // Can we rewind to the indicated frame?
|
| bool CanRewindFrame(intptr_t frame_index, const char** error) const;
|
|
|
| @@ -644,6 +714,7 @@ class Debugger {
|
|
|
| // Current stack trace. Valid only while IsPaused().
|
| DebuggerStackTrace* stack_trace_;
|
| + DebuggerStackTrace* async_causal_stack_trace_;
|
|
|
| // When stepping through code, only pause the program if the top
|
| // frame corresponds to this fp value, or if the top frame is
|
|
|