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;
131 if (scripts_.
length() == 0) {
134 return scripts_.
At(0);
136 StringPtr
url()
const {
return url_; }
164 void set_next(BreakpointLocation* value) { next_ =
value; }
168 Breakpoint* breakpoints()
const {
return this->conditions_; }
169 void set_breakpoints(Breakpoint* head) { this->conditions_ =
head; }
172 Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
174 SafepointRwLock* line_number_lock() {
return line_number_lock_.get(); }
177 MallocGrowableArray<ScriptPtr> scripts_;
179 std::unique_ptr<SafepointRwLock> line_number_lock_;
180 intptr_t line_number_;
181 std::atomic<TokenPosition> token_pos_;
182 std::atomic<TokenPosition> end_token_pos_;
184 Breakpoint* conditions_;
185 intptr_t requested_line_number_;
186 intptr_t requested_column_number_;
189 TokenPosition code_token_pos_;
228 return breakpoint_locations_.length() == 0;
248 ASSERT(breakpoint_locations_.length() == 0 ||
250 breakpoint_locations_.At(0)->token_pos() &&
251 breakpoint_location->
url() == breakpoint_locations_.At(0)->url()));
252 breakpoint_locations_.Add(breakpoint_location);
256 CodeBreakpoint* next()
const {
return this->next_; }
267 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
271 CodePtr saved_value_;
292 const Array& deopt_frame,
293 intptr_t deopt_frame_offset);
378 const Array& arguments,
379 const Array& type_definitions,
387 void PrintToJSONObjectRegular(
JSONObject* jsobj);
388 void PrintToJSONObjectAsyncAwaiter(
JSONObject* jsobj);
389 void PrintToJSONObjectAsyncSuspensionMarker(
JSONObject* jsobj);
390 void PrintContextMismatchError(intptr_t ctx_slot,
391 intptr_t frame_ctx_level,
392 intptr_t var_ctx_level);
393 void PrintDescriptorsError(
const char*
message);
397 void GetPcDescriptors();
398 void GetVarDescriptors();
399 void GetDescIndices();
401 static const char* KindToCString(
Kind kind) {
407 return "AsyncCausal";
409 return "AsyncSuspensionMarker";
416 ObjectPtr GetStackVar(VariableIndex var_index);
417 ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
419 intptr_t frame_ctx_level);
420 ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
429 const Function& function_;
430 const Closure& closure_;
432 bool token_pos_initialized_ =
false;
433 TokenPosition token_pos_ = TokenPosition::kNoSource;
434 intptr_t try_index_ = -1;
437 intptr_t line_number_ = -1;
438 intptr_t column_number_ = -1;
439 intptr_t context_level_ = -1;
442 const Array& deopt_frame_;
443 const intptr_t deopt_frame_offset_;
447 bool vars_initialized_ =
false;
449 ZoneGrowableArray<intptr_t> desc_indices_;
461 : thread_(
Thread::Current()), zone_(thread_->zone()), trace_(capacity) {}
463 intptr_t
Length()
const {
return trace_.length(); }
484 void AddAsyncSuspension();
485 void AddAsyncAwaiterFrame(
uword pc,
const Code& code,
const Closure& closure);
494 bool has_async_catch_error_ =
false;
564 bool Call() {
return lambda_(); }
583 uword breakpoint_address,
615 return code_breakpoints_lock_.get();
619 return breakpoint_locations_lock_.get();
639 std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
645 std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
648 std::unique_ptr<RwLock> single_stepping_set_lock_;
651 void RemoveUnlinkedCodeBreakpoints();
654 bool needs_breakpoint_cleanup_;
687 intptr_t line_number);
689 intptr_t line_number,
690 intptr_t column_number);
693 intptr_t line_number,
694 intptr_t column_number);
707 intptr_t frame_index = 1,
708 const char**
error =
nullptr);
714 bool IsPaused()
const {
return pause_event_ !=
nullptr; }
786 bool SetupStepOverAsyncSuspension(
const char**
error);
788 bool NeedsIsolateEvents();
789 bool NeedsDebugEvents();
793 void FindCompiledFunctions(
798 bool FindBestFit(
const Script& script,
802 void DeoptimizeWorld();
803 void RunWithStoppedDeoptimizedWorld(std::function<
void()> fun);
804 void NotifySingleStepping(
bool value);
809 intptr_t requested_line,
810 intptr_t requested_column,
816 intptr_t requested_line,
817 intptr_t requested_column,
823 intptr_t requested_line,
824 intptr_t requested_column,
839 intptr_t requested_line,
840 intptr_t requested_column,
848 intptr_t nextId() {
return next_id_++; }
850 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
851 const Instance& exc);
855 void Pause(ServiceEvent*
event);
857 void HandleSteppingRequest(
bool skip_next_step =
false);
859 void CacheStackTraces(DebuggerStackTrace* stack_trace,
860 DebuggerStackTrace* async_awaiter_stack_trace);
861 void ClearCachedStackTraces();
863 void RewindToFrame(intptr_t frame_index);
864 void RewindToUnoptimizedFrame(StackFrame*
frame,
const Code& code);
865 void RewindToOptimizedFrame(StackFrame*
frame,
867 intptr_t post_deopt_frame_index);
869 void ResetSteppingFramePointer();
870 void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
872 GroupDebugger* group_debugger() {
return isolate_->
group()->
debugger(); }
885 intptr_t resume_frame_index_;
886 intptr_t post_deopt_frame_index_;
891 bool ignore_breakpoints_;
897 ServiceEvent* pause_event_;
900 DebuggerStackTrace* stack_trace_;
901 DebuggerStackTrace* async_awaiter_stack_trace_;
910 uword last_stepping_fp_;
911 TokenPosition last_stepping_pos_;
916 bool skip_next_step_;
922 MallocGrowableArray<ObjectPtr> breakpoints_at_resumption_;
932 : debugger_(debugger) {
933 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()
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()
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)
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)
const uint8_t uint32_t uint32_t GError ** error
#define DECLARE_FLAG(type, name)
Dart_NativeFunction function
static constexpr int kCallerSpSlotFromFp
constexpr intptr_t kWordSize
@ kInvalidExceptionPauseInfo
@ kPauseOnUnhandledExceptions
Pair(const Key key, const Value &value)
Pair & operator=(const Pair &)=default