5#ifndef RUNTIME_VM_DEBUGGER_H_
6#define RUNTIME_VM_DEBUGGER_H_
28#define TD_Print(format, ...) \
29 if (FLAG_verbose_debug) Log::Current()->Print(format, __VA_ARGS__)
31#define TD_Print(format, ...) \
32 if (FLAG_verbose_debug) Log::Current()->Print(format, ##__VA_ARGS__)
41class ObjectPointerVisitor;
42class BreakpointLocation;
60 intptr_t
id()
const {
return id_; }
68 ClosurePtr
closure()
const {
return closure_; }
92 bool enabled_ =
false;
133 if (scripts_.
length() == 0) {
136 return scripts_.
At(0);
138 StringPtr
url()
const {
return url_; }
170 Breakpoint* breakpoints()
const {
return this->conditions_; }
171 void set_breakpoints(Breakpoint*
head) { this->conditions_ =
head; }
174 Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
176 SafepointRwLock* line_number_lock() {
return line_number_lock_.get(); }
179 MallocGrowableArray<ScriptPtr> scripts_;
181 std::unique_ptr<SafepointRwLock> line_number_lock_;
182 intptr_t line_number_;
183 std::atomic<TokenPosition> token_pos_;
184 std::atomic<TokenPosition> end_token_pos_;
186 Breakpoint* conditions_;
187 intptr_t requested_line_number_;
188 intptr_t requested_column_number_;
191 TokenPosition code_token_pos_;
230 return breakpoint_locations_.length() == 0;
250 ASSERT(breakpoint_locations_.length() == 0 ||
252 breakpoint_locations_.At(0)->token_pos() &&
253 breakpoint_location->
url() == breakpoint_locations_.At(0)->url()));
254 breakpoint_locations_.Add(breakpoint_location);
269 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
273 CodePtr saved_value_;
294 const Array& deopt_frame,
295 intptr_t deopt_frame_offset);
380 const Array& arguments,
381 const Array& type_definitions,
389 void PrintToJSONObjectRegular(
JSONObject* jsobj);
390 void PrintToJSONObjectAsyncAwaiter(
JSONObject* jsobj);
391 void PrintToJSONObjectAsyncSuspensionMarker(
JSONObject* jsobj);
392 void PrintContextMismatchError(intptr_t ctx_slot,
393 intptr_t frame_ctx_level,
394 intptr_t var_ctx_level);
395 void PrintDescriptorsError(
const char*
message);
399 void GetPcDescriptors();
400 void GetVarDescriptors();
401 void GetDescIndices();
403 static const char* KindToCString(
Kind kind) {
409 return "AsyncCausal";
411 return "AsyncSuspensionMarker";
418 ObjectPtr GetStackVar(VariableIndex var_index);
419 ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
421 intptr_t frame_ctx_level);
422 ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
431 const Function& function_;
432 const Closure& closure_;
434 bool token_pos_initialized_ =
false;
435 TokenPosition token_pos_ = TokenPosition::kNoSource;
436 intptr_t try_index_ = -1;
439 intptr_t line_number_ = -1;
440 intptr_t column_number_ = -1;
441 intptr_t context_level_ = -1;
444 const Array& deopt_frame_;
445 const intptr_t deopt_frame_offset_;
449 bool vars_initialized_ =
false;
451 ZoneGrowableArray<intptr_t> desc_indices_;
463 : thread_(
Thread::Current()), zone_(thread_->zone()), trace_(capacity) {}
465 intptr_t
Length()
const {
return trace_.length(); }
486 void AddAsyncSuspension();
496 bool has_async_catch_error_ =
false;
566 bool Call() {
return lambda_(); }
585 uword breakpoint_address,
617 return code_breakpoints_lock_.get();
621 return breakpoint_locations_lock_.get();
641 std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
647 std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
650 std::unique_ptr<RwLock> single_stepping_set_lock_;
653 void RemoveUnlinkedCodeBreakpoints();
656 bool needs_breakpoint_cleanup_;
689 intptr_t line_number);
691 intptr_t line_number,
692 intptr_t column_number);
695 intptr_t line_number,
696 intptr_t column_number);
709 intptr_t frame_index = 1,
710 const char**
error =
nullptr);
716 bool IsPaused()
const {
return pause_event_ !=
nullptr; }
788 bool SetupStepOverAsyncSuspension(
const char**
error);
790 bool NeedsIsolateEvents();
791 bool NeedsDebugEvents();
795 void FindCompiledFunctions(
804 void DeoptimizeWorld();
805 void RunWithStoppedDeoptimizedWorld(
std::function<
void()> fun);
806 void NotifySingleStepping(
bool value);
811 intptr_t requested_line,
812 intptr_t requested_column,
818 intptr_t requested_line,
819 intptr_t requested_column,
825 intptr_t requested_line,
826 intptr_t requested_column,
841 intptr_t requested_line,
842 intptr_t requested_column,
850 intptr_t nextId() {
return next_id_++; }
852 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
853 const Instance& exc);
857 void Pause(ServiceEvent*
event);
859 void HandleSteppingRequest(
bool skip_next_step =
false);
861 void CacheStackTraces(DebuggerStackTrace* stack_trace,
862 DebuggerStackTrace* async_awaiter_stack_trace);
863 void ClearCachedStackTraces();
865 void RewindToFrame(intptr_t frame_index);
866 void RewindToUnoptimizedFrame(StackFrame*
frame,
const Code&
code);
867 void RewindToOptimizedFrame(StackFrame*
frame,
869 intptr_t post_deopt_frame_index);
871 void ResetSteppingFramePointer();
872 void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
874 GroupDebugger* group_debugger() {
return isolate_->
group()->
debugger(); }
887 intptr_t resume_frame_index_;
888 intptr_t post_deopt_frame_index_;
893 bool ignore_breakpoints_;
899 ServiceEvent* pause_event_;
902 DebuggerStackTrace* stack_trace_;
903 DebuggerStackTrace* async_awaiter_stack_trace_;
912 uword last_stepping_fp_;
913 TokenPosition last_stepping_pos_;
918 bool skip_next_step_;
924 MallocGrowableArray<ObjectPtr> breakpoints_at_resumption_;
934 : debugger_(debugger) {
935 ASSERT(debugger_ !=
nullptr);
StringPtr QualifiedFunctionName()
const Context & GetSavedCurrentContext()
Relation CompareTo(uword other_fp) const
void PrintToJSONObject(JSONObject *jsobj)
const Closure & closure() const
const Function & function() const
ArrayPtr GetLocalVariables()
ActivationFrame(uword pc, uword fp, uword sp, const Code &code, const Array &deopt_frame, intptr_t deopt_frame_offset)
ObjectPtr GetParameter(intptr_t index)
bool IsDebuggable() const
ObjectPtr GetSuspendableFunctionData()
bool HandlesException(const Instance &exc_obj)
uword GetCallerSp() const
intptr_t NumLocalVariables()
ObjectPtr GetSuspendStateVar()
ObjectPtr EvaluateCompiledExpression(const ExternalTypedData &kernel_data, const Array &arguments, const Array &type_definitions, const TypeArguments &type_arguments)
TypeArgumentsPtr BuildParameters(const GrowableObjectArray ¶m_names, const GrowableObjectArray ¶m_values, const GrowableObjectArray &type_params_names, const GrowableObjectArray &type_params_bounds, const GrowableObjectArray &type_params_defaults)
const Code & code() const
bool IsRewindable() const
void VariableAt(intptr_t i, String *name, TokenPosition *declaration_token_pos, TokenPosition *visible_start_token_pos, TokenPosition *visible_end_token_pos, Object *value)
bool Remove(typename KeyValueTrait::Key key)
void Insert(typename KeyValueTrait::Pair kv)
const T & At(intptr_t index) const
TokenPosition token_pos() const
TokenPosition end_token_pos() const
intptr_t requested_column_number() const
Breakpoint * AddSingleShot(Debugger *dbg)
bool EnsureIsResolved(const Function &target_function, TokenPosition exact_token_pos)
Breakpoint * AddRepeated(Debugger *dbg)
BreakpointLocation(Debugger *debugger, const GrowableHandlePtrArray< const Script > &scripts, TokenPosition token_pos, TokenPosition end_token_pos, intptr_t requested_line_number, intptr_t requested_column_number)
Breakpoint * AddBreakpoint(Debugger *dbg, const Closure &closure, bool single_shot)
void GetCodeLocation(Script *script, TokenPosition *token_pos) const
intptr_t requested_line_number() const
ClosurePtr closure() const
BreakpointLocation * bpt_location() const
bool is_single_shot() const
Breakpoint * next() const
void set_bpt_location(BreakpointLocation *new_bpt_location)
void set_next(Breakpoint *n)
void PrintJSON(JSONStream *stream)
Breakpoint(intptr_t id, BreakpointLocation *bpt_location, bool is_single_shot, const Closure &closure)
FunctionPtr function() const
const char * ToCString() const
CodeBreakpoint(const Code &code, BreakpointLocation *loc, uword pc, UntaggedPcDescriptors::Kind kind)
CodePtr OrigStubAddress() const
bool HasNoBreakpointLocations()
bool HasBreakpointLocation(BreakpointLocation *breakpoint_location)
bool FindAndDeleteBreakpointLocation(BreakpointLocation *breakpoint_location)
static bool IsKeyEqual(Pair kv, Key key)
static Value ValueOf(Pair kv)
static uword Hash(Key key)
static Key KeyOf(Pair kv)
void Remove(const Key &key)
DebuggerKeyValueTrait::Pair Pair
void Insert(const Key &key)
DebuggerKeyValueTrait::Value Value
DebuggerKeyValueTrait::Key Key
ActivationFrame * GetHandlerFrame(const Instance &exc_obj) const
static DebuggerStackTrace * Collect()
ActivationFrame * FrameAt(int i) const
void set_has_async_catch_error(bool has_async_catch_error)
bool has_async_catch_error() const
DebuggerStackTrace(int capacity)
static DebuggerStackTrace * From(const class StackTrace &ex_trace)
static DebuggerStackTrace * CollectAsyncAwaiters()
Breakpoint * SetBreakpointAtEntry(const Function &target_function, bool single_shot)
void AsyncStepInto(const Closure &awaiter)
Dart_ExceptionPauseInfo GetExceptionPauseInfo() const
bool SetBreakpointState(Breakpoint *bpt, bool enable)
void ResumptionBreakpoint()
Debugger(Isolate *isolate)
Breakpoint * SetBreakpointAtActivation(const Instance &closure, bool single_shot)
bool SetResumeAction(ResumeAction action, intptr_t frame_index=1, const char **error=nullptr)
void RemoveBreakpoint(intptr_t bp_id)
void PrintBreakpointsToJSONArray(JSONArray *jsarr) const
Isolate * isolate() const
void VisitObjectPointers(ObjectPointerVisitor *visitor)
void PauseException(const Instance &exc)
void PrintSettingsToJSONObject(JSONObject *jsobj) const
DebuggerStackTrace * StackTrace()
bool ignore_breakpoints() const
DebuggerStackTrace * AsyncAwaiterStackTrace()
BreakpointLocation * BreakpointLocationAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
friend class BreakpointLocation
void NotifyIsolateCreated()
ErrorPtr PauseInterrupted()
bool IsSingleStepping() const
ErrorPtr PausePostRequest()
Breakpoint * SetBreakpointAtLine(const String &script_url, intptr_t line_number)
const ServiceEvent * PauseEvent() const
void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info)
Breakpoint * GetBreakpointById(intptr_t id)
Breakpoint * BreakpointAtActivation(const Instance &closure)
void set_ignore_breakpoints(bool ignore_breakpoints)
void PauseDeveloper(const String &msg)
@ kStepOverAsyncSuspension
void SetBreakpointAtResumption(const Object &function_data)
Breakpoint * SetBreakpointAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
intptr_t limitBreakpointId()
void EnterSingleStepMode()
static bool IsDebuggable(const Function &func)
ErrorPtr PauseBreakpoint()
static constexpr intptr_t kNone
~DisableBreakpointsScope()
DisableBreakpointsScope(Debugger *debugger, bool disable)
GroupDebugger(IsolateGroup *isolate_group)
RwLock * single_stepping_set_lock()
CodePtr GetPatchedStubAddress(uword breakpoint_address)
bool HasCodeBreakpointInFunction(const Function &func)
void RegisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
void UnregisterBreakpointLocation(BreakpointLocation *location)
void RemoveBreakpointLocation(BreakpointLocation *bpt_location)
bool HasCodeBreakpointInFunctionUnsafe(const Function &func)
bool HasBreakpointInCode(const Code &code)
IsolateGroup * isolate_group()
bool HasBreakpoint(Thread *thread, const Function &function)
void MakeCodeBreakpointAt(const Function &func, BreakpointLocation *bpt)
SafepointRwLock * code_breakpoints_lock()
bool IsDebugging(Thread *thread, const Function &function)
bool HasBreakpointInFunction(const Function &func)
bool EnsureLocationIsInFunction(Zone *zone, const Function &function, BreakpointLocation *location)
BreakpointLocation * GetBreakpointLocationFor(Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
void VisitObjectPointers(ObjectPointerVisitor *visitor)
bool HasCodeBreakpointInCode(const Code &code)
bool HasActiveBreakpoint(uword pc)
void NotifyCompilation(const Function &func)
void MakeCodeBreakpointAtUnsafe(const Function &func, BreakpointLocation *bpt)
void RegisterBreakpointLocation(BreakpointLocation *location)
bool HasBreakpointUnsafe(Thread *thread, const Function &function)
CodeBreakpoint * GetCodeBreakpoint(uword breakpoint_address)
void SyncBreakpointLocation(BreakpointLocation *loc)
void UnregisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
SafepointRwLock * breakpoint_locations_lock()
void UnlinkCodeBreakpoints(BreakpointLocation *bpt_location)
GroupDebugger * debugger() const
IsolateGroup * group() const
LambdaBoolCallable(T &lambda)
static Object & ZoneHandle()
static uint32_t WordHash(intptr_t key)
DECLARE_FLAG(bool, verbose_debug)
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
static constexpr int kCallerSpSlotFromFp
constexpr intptr_t kWordSize
@ kInvalidExceptionPauseInfo
@ kPauseOnUnhandledExceptions
std::function< void()> closure
Pair(const Key key, const Value &value)
Pair & operator=(const Pair &)=default