Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
debugger.h
Go to the documentation of this file.
1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_DEBUGGER_H_
6#define RUNTIME_VM_DEBUGGER_H_
7
8#include <memory>
9
11
13#include "vm/kernel_isolate.h"
14#include "vm/object.h"
15#include "vm/port.h"
16#include "vm/scopes.h"
17#include "vm/service_event.h"
18#include "vm/simulator.h"
19#include "vm/stack_frame.h"
20#include "vm/stack_trace.h"
21
22#if !defined(PRODUCT)
23
24DECLARE_FLAG(bool, verbose_debug);
25
26// 'Trace Debugger' TD_Print.
27#if defined(_MSC_VER)
28#define TD_Print(format, ...) \
29 if (FLAG_verbose_debug) Log::Current()->Print(format, __VA_ARGS__)
30#else
31#define TD_Print(format, ...) \
32 if (FLAG_verbose_debug) Log::Current()->Print(format, ##__VA_ARGS__)
33#endif
34
35namespace dart {
36
37class CodeBreakpoint;
38class Isolate;
39class JSONArray;
40class JSONStream;
41class ObjectPointerVisitor;
42class BreakpointLocation;
43class StackFrame;
44
45// A user-defined breakpoint, which can be set for a particular closure
46// (if |closure| is not |null|) and can fire one (|is_single_shot| is |true|)
47// or many times.
49 public:
50 Breakpoint(intptr_t id,
52 bool is_single_shot,
53 const Closure& closure)
54 : id_(id),
55 next_(nullptr),
56 closure_(closure.ptr()),
57 bpt_location_(bpt_location),
58 is_single_shot_(is_single_shot) {}
59
60 intptr_t id() const { return id_; }
61 Breakpoint* next() const { return next_; }
62 void set_next(Breakpoint* n) { next_ = n; }
63
64 BreakpointLocation* bpt_location() const { return bpt_location_; }
65 void set_bpt_location(BreakpointLocation* new_bpt_location);
66
67 bool is_single_shot() const { return is_single_shot_; }
68 ClosurePtr closure() const { return closure_; }
69
70 void Enable() {
71 ASSERT(!enabled_);
72 enabled_ = true;
73 }
74
75 void Disable() {
76 ASSERT(enabled_);
77 enabled_ = false;
78 }
79
80 bool is_enabled() const { return enabled_; }
81
82 void PrintJSON(JSONStream* stream);
83
84 private:
85 void VisitObjectPointers(ObjectPointerVisitor* visitor);
86
87 intptr_t id_;
88 Breakpoint* next_;
89 ClosurePtr closure_;
90 BreakpointLocation* bpt_location_;
91 bool is_single_shot_;
92 bool enabled_ = false;
93
94 friend class BreakpointLocation;
96};
97
98// BreakpointLocation represents a collection of breakpoint conditions at the
99// same token position in Dart source. There may be more than one CodeBreakpoint
100// object per BreakpointLocation.
101// An unresolved breakpoint is one where the underlying code has not
102// been compiled yet. Since the code has not been compiled, we don't know
103// the definitive source location yet. The requested source location may
104// change when the underlying code gets compiled.
105// A latent breakpoint represents a breakpoint location in Dart source
106// that is not loaded in the VM when the breakpoint is requested.
107// When a script with matching url is loaded, a latent breakpoint
108// becomes an unresolved breakpoint.
110 public:
111 // Create a new unresolved breakpoint.
116 intptr_t requested_line_number,
117 intptr_t requested_column_number);
118 // Create a new latent breakpoint.
120 const String& url,
121 intptr_t requested_line_number,
122 intptr_t requested_column_number);
123
125
126 TokenPosition token_pos() const { return token_pos_.load(); }
127 intptr_t line_number();
128 TokenPosition end_token_pos() const { return end_token_pos_.load(); }
129
130 ScriptPtr script() const {
131 if (scripts_.length() == 0) {
132 return Script::null();
133 }
134 return scripts_.At(0);
135 }
136 StringPtr url() const { return url_; }
137
138 intptr_t requested_line_number() const { return requested_line_number_; }
139 intptr_t requested_column_number() const { return requested_column_number_; }
140
142
146 const Closure& closure,
147 bool single_shot);
148
149 bool AnyEnabled() const;
150 bool IsResolved() const { return code_token_pos_.IsReal(); }
151 bool IsLatent() const { return !token_pos().IsReal(); }
152
153 bool EnsureIsResolved(const Function& target_function,
154 TokenPosition exact_token_pos);
155
156 Debugger* debugger() { return debugger_; }
157
158 private:
159 void VisitObjectPointers(ObjectPointerVisitor* visitor);
160
161 void SetResolved(const Function& func, TokenPosition token_pos);
162
163 BreakpointLocation* next() const { return this->next_; }
164 void set_next(BreakpointLocation* value) { next_ = value; }
165
166 void AddBreakpoint(Breakpoint* bpt, Debugger* dbg);
167
168 Breakpoint* breakpoints() const { return this->conditions_; }
169 void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
170
171 // Finds the breakpoint we hit at |location|.
172 Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
173
174 SafepointRwLock* line_number_lock() { return line_number_lock_.get(); }
175
176 Debugger* debugger_;
177 MallocGrowableArray<ScriptPtr> scripts_;
178 StringPtr url_;
179 std::unique_ptr<SafepointRwLock> line_number_lock_;
180 intptr_t line_number_; // lazily computed for token_pos_
181 std::atomic<TokenPosition> token_pos_;
182 std::atomic<TokenPosition> end_token_pos_;
183 BreakpointLocation* next_;
184 Breakpoint* conditions_;
185 intptr_t requested_line_number_;
186 intptr_t requested_column_number_;
187
188 // Valid for resolved breakpoints:
189 TokenPosition code_token_pos_;
190
191 friend class Debugger;
192 friend class GroupDebugger;
194};
195
196// CodeBreakpoint represents a location in compiled code.
197// There may be more than one CodeBreakpoint for one BreakpointLocation,
198// e.g. when a function gets compiled as a regular function and as a closure.
199// There may be more than one BreakpointLocation associated with CodeBreakpoint,
200// one for every isolate in a group that sets a breakpoint at particular
201// code location represented by the CodeBreakpoint.
202// Each BreakpointLocation might be enabled/disabled based on whether it has
203// any actual breakpoints associated with it.
204// The CodeBreakpoint is enabled if it has any such BreakpointLocations
205// associated with it.
206// The class is not thread-safe - users of this class need to ensure the access
207// is synchronized, guarded by mutexes or run inside of a safepoint scope.
209 public:
210 // Unless CodeBreakpoint is unlinked and is no longer used there should be at
211 // least one BreakpointLocation associated with CodeBreakpoint. If there are
212 // more BreakpointLocation added assumption is is that all of them point to
213 // the same source so have the same token pos.
214 CodeBreakpoint(const Code& code,
216 uword pc,
219
220 // Used by GroupDebugger to find CodeBreakpoint associated with
221 // particular function.
222 FunctionPtr function() const { return Code::Handle(code_).function(); }
223
224 uword pc() const { return pc_; }
225 bool HasBreakpointLocation(BreakpointLocation* breakpoint_location);
226 bool FindAndDeleteBreakpointLocation(BreakpointLocation* breakpoint_location);
228 return breakpoint_locations_.length() == 0;
229 }
230
231 void Enable();
232 void Disable();
233 bool IsEnabled() const { return enabled_count_ > 0; }
234
235 CodePtr OrigStubAddress() const;
236
237 const char* ToCString() const;
238
239 private:
240 void VisitObjectPointers(ObjectPointerVisitor* visitor);
241
242 // Finds right BreakpointLocation for a given Isolate's debugger.
243 BreakpointLocation* FindBreakpointForDebugger(Debugger* debugger);
244 // Adds new BreakpointLocation for another isolate that wants to
245 // break at the same function/code location that this CodeBreakpoint
246 // represents.
247 void AddBreakpointLocation(BreakpointLocation* breakpoint_location) {
248 ASSERT(breakpoint_locations_.length() == 0 ||
249 (breakpoint_location->token_pos() ==
250 breakpoint_locations_.At(0)->token_pos() &&
251 breakpoint_location->url() == breakpoint_locations_.At(0)->url()));
252 breakpoint_locations_.Add(breakpoint_location);
253 }
254
255 void set_next(CodeBreakpoint* value) { next_ = value; }
256 CodeBreakpoint* next() const { return this->next_; }
257
258 void PatchCode();
259 void RestoreCode();
260
261 CodePtr code_;
262 uword pc_;
263 int enabled_count_; // incremented for every enabled breakpoint location
264
265 // Breakpoint locations from different debuggers/isolates that
266 // point to this code breakpoint.
267 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
268 CodeBreakpoint* next_;
269
270 UntaggedPcDescriptors::Kind breakpoint_kind_;
271 CodePtr saved_value_;
272
273 friend class Debugger;
274 friend class GroupDebugger;
276};
277
278// ActivationFrame represents one dart function activation frame
279// on the call stack.
281 public:
287
289 uword fp,
290 uword sp,
291 const Code& code,
292 const Array& deopt_frame,
293 intptr_t deopt_frame_offset);
294
295 // Create a |kAsyncAwaiter| frame representing asynchronous awaiter
296 // waiting for the completion of a |Future|.
297 //
298 // |closure| is the listener which will be invoked when awaited
299 // computation completes.
301
302 explicit ActivationFrame(Kind kind);
303
304 Kind kind() const { return kind_; }
305
306 uword pc() const { return pc_; }
307 uword fp() const { return fp_; }
308 uword sp() const { return sp_; }
309
311
312 // For |kAsyncAwaiter| frames this is the listener which will be invoked
313 // when the frame below (callee) completes.
314 const Closure& closure() const { return closure_; }
315
316 const Function& function() const { return function_; }
317 const Code& code() const {
318 ASSERT(!code_.IsNull());
319 return code_;
320 }
321
327
328 Relation CompareTo(uword other_fp) const;
329
330 StringPtr QualifiedFunctionName();
331 StringPtr SourceUrl();
332 ScriptPtr SourceScript();
333 LibraryPtr Library();
335 intptr_t LineNumber();
336 intptr_t ColumnNumber();
337
338 // Returns true if this frame is for a function that is visible
339 // to the user and can be debugged.
340 bool IsDebuggable() const;
341
342 // Returns true if it is possible to rewind the debugger to this frame.
343 bool IsRewindable() const;
344
345 // The context level of a frame is the context level at the
346 // PC/token index of the frame. It determines the depth of the context
347 // chain that belongs to the function of this activation frame.
348 intptr_t ContextLevel();
349
350 const char* ToCString();
351
352 intptr_t NumLocalVariables();
353
354 void VariableAt(intptr_t i,
355 String* name,
356 TokenPosition* declaration_token_pos,
357 TokenPosition* visible_start_token_pos,
358 TokenPosition* visible_end_token_pos,
359 Object* value);
360
361 ArrayPtr GetLocalVariables();
362 ObjectPtr GetParameter(intptr_t index);
363 ClosurePtr GetClosure();
365
369
370 TypeArgumentsPtr BuildParameters(
371 const GrowableObjectArray& param_names,
372 const GrowableObjectArray& param_values,
373 const GrowableObjectArray& type_params_names,
374 const GrowableObjectArray& type_params_bounds,
375 const GrowableObjectArray& type_params_defaults);
376
378 const Array& arguments,
379 const Array& type_definitions,
380 const TypeArguments& type_arguments);
381
382 void PrintToJSONObject(JSONObject* jsobj);
383
384 bool HandlesException(const Instance& exc_obj);
385
386 private:
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);
394
395 intptr_t TryIndex();
396 intptr_t DeoptId();
397 void GetPcDescriptors();
398 void GetVarDescriptors();
399 void GetDescIndices();
400
401 static const char* KindToCString(Kind kind) {
402 switch (kind) {
403 case kRegular:
404 return "Regular";
405 case kAsyncAwaiter:
406 // Keeping the legacy name in the protocol itself.
407 return "AsyncCausal";
409 return "AsyncSuspensionMarker";
410 default:
411 UNREACHABLE();
412 return "";
413 }
414 }
415
416 ObjectPtr GetStackVar(VariableIndex var_index);
417 ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
418 intptr_t slot_index,
419 intptr_t frame_ctx_level);
420 ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
421
422 uword pc_ = 0;
423 uword fp_ = 0;
424 uword sp_ = 0;
425
426 // The anchor of the context chain for this function.
428 const Code& code_;
429 const Function& function_;
430 const Closure& closure_;
431
432 bool token_pos_initialized_ = false;
433 TokenPosition token_pos_ = TokenPosition::kNoSource;
434 intptr_t try_index_ = -1;
435 intptr_t deopt_id_ = dart::DeoptId::kNone;
436
437 intptr_t line_number_ = -1;
438 intptr_t column_number_ = -1;
439 intptr_t context_level_ = -1;
440
441 // Some frames are deoptimized into a side array in order to inspect them.
442 const Array& deopt_frame_;
443 const intptr_t deopt_frame_offset_;
444
445 Kind kind_;
446
447 bool vars_initialized_ = false;
448 LocalVarDescriptors& var_descriptors_ = LocalVarDescriptors::ZoneHandle();
449 ZoneGrowableArray<intptr_t> desc_indices_;
450 PcDescriptors& pc_desc_ = PcDescriptors::ZoneHandle();
451
452 friend class Debugger;
453 friend class DebuggerStackTrace;
455};
456
457// Array of function activations on the call stack.
459 public:
460 explicit DebuggerStackTrace(int capacity)
461 : thread_(Thread::Current()), zone_(thread_->zone()), trace_(capacity) {}
462
463 intptr_t Length() const { return trace_.length(); }
464
465 ActivationFrame* FrameAt(int i) const { return trace_[i]; }
466
467 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
468
469 static DebuggerStackTrace* Collect();
471
472 // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
473 // Frames corresponding to invisible functions are omitted. It is not valid
474 // to query local variables in the returned stack.
475 static DebuggerStackTrace* From(const class StackTrace& ex_trace);
476
477 bool has_async_catch_error() const { return has_async_catch_error_; }
479 has_async_catch_error_ = has_async_catch_error;
480 }
481
482 private:
483 void AddActivation(ActivationFrame* frame);
484 void AddAsyncSuspension();
485 void AddAsyncAwaiterFrame(uword pc, const Code& code, const Closure& closure);
486
487 void AppendCodeFrames(StackFrame* frame, const Code& code);
488
489 Thread* thread_;
490 Zone* zone_;
491 Code& inlined_code_ = Code::Handle();
492 Array& deopt_frame_ = Array::Handle();
494 bool has_async_catch_error_ = false;
495
496 friend class Debugger;
497
499};
500
501// On which exceptions to pause.
508
510 public:
511 typedef const Debugger* Key;
512 typedef bool Value;
513
514 struct Pair {
517 Pair() : key(nullptr), value(false) {}
518 Pair(const Key key, const Value& value) : key(key), value(value) {}
519 Pair(const Pair& other) : key(other.key), value(other.value) {}
520 Pair& operator=(const Pair&) = default;
521 };
522
523 static Key KeyOf(Pair kv) { return kv.key; }
524 static Value ValueOf(Pair kv) { return kv.value; }
525 static uword Hash(Key key) {
526 return Utils::WordHash(reinterpret_cast<intptr_t>(key));
527 }
528 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
529};
530
531class DebuggerSet : public MallocDirectChainedHashMap<DebuggerKeyValueTrait> {
532 public:
536
537 virtual ~DebuggerSet() { Clear(); }
538
539 void Insert(const Key& key) {
540 Pair pair(key, /*value=*/true);
542 }
543
547};
548
549class BoolCallable : public ValueObject {
550 public:
552 virtual ~BoolCallable() {}
553
554 virtual bool Call() = 0;
555
556 private:
558};
559
560template <typename T>
562 public:
563 explicit LambdaBoolCallable(T& lambda) : lambda_(lambda) {}
564 bool Call() { return lambda_(); }
565
566 private:
567 T& lambda_;
569};
570
572 public:
575
576 void MakeCodeBreakpointAtUnsafe(const Function& func,
577 BreakpointLocation* bpt);
578 void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt);
579
580 // Returns [nullptr] if no breakpoint exists for the given address.
581 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
583 uword breakpoint_address,
584 CodeBreakpoint** pcbpt);
585 CodePtr GetPatchedStubAddress(uword breakpoint_address);
586
589
591 void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
592
593 // Returns true if the call at address pc is patched to point to
594 // a debugger stub.
595 bool HasActiveBreakpoint(uword pc);
597 bool HasCodeBreakpointInFunction(const Function& func);
598 bool HasCodeBreakpointInCode(const Code& code);
599
601 bool HasBreakpointInCode(const Code& code);
602
604
605 void Pause();
606
608 const Function& function,
609 BreakpointLocation* location);
610 void NotifyCompilation(const Function& func);
611
613
615 return code_breakpoints_lock_.get();
616 }
617
619 return breakpoint_locations_lock_.get();
620 }
621
622 RwLock* single_stepping_set_lock() { return single_stepping_set_lock_.get(); }
623
624 void RegisterSingleSteppingDebugger(Thread* thread, const Debugger* debugger);
626 const Debugger* debugger);
627
628 // Returns [true] if there is at least one breakpoint set in function or code.
629 // Checks for both user-defined and internal temporary breakpoints.
630 bool HasBreakpointUnsafe(Thread* thread, const Function& function);
631 bool HasBreakpoint(Thread* thread, const Function& function);
632 bool IsDebugging(Thread* thread, const Function& function);
633
634 IsolateGroup* isolate_group() { return isolate_group_; }
635
636 private:
637 IsolateGroup* isolate_group_;
638
639 std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
640 CodeBreakpoint* code_breakpoints_;
641
642 // Secondary list of all breakpoint_locations_(primary is in Debugger class).
643 // This list is kept in sync with all the lists in Isolate Debuggers and is
644 // used to quickly scan BreakpointLocations when new Function is compiled.
645 std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
646 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
647
648 std::unique_ptr<RwLock> single_stepping_set_lock_;
649 DebuggerSet single_stepping_set_;
650
651 void RemoveUnlinkedCodeBreakpoints();
652 void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
653
654 bool needs_breakpoint_cleanup_;
655};
656
657class Debugger {
658 public:
667
668 explicit Debugger(Isolate* isolate);
669 ~Debugger();
670
671 Isolate* isolate() const { return isolate_; }
672
674 void Shutdown();
675
676 void NotifyDoneLoading();
677
678 // Set breakpoint at closest location to function entry.
679 Breakpoint* SetBreakpointAtEntry(const Function& target_function,
680 bool single_shot);
682 bool single_shot);
684
685 // TODO(turnidge): script_url may no longer be specific enough.
686 Breakpoint* SetBreakpointAtLine(const String& script_url,
687 intptr_t line_number);
688 Breakpoint* SetBreakpointAtLineCol(const String& script_url,
689 intptr_t line_number,
690 intptr_t column_number);
691
693 intptr_t line_number,
694 intptr_t column_number);
695
696 // Returns true if the breakpoint's state changed.
697 bool SetBreakpointState(Breakpoint* bpt, bool enable);
698
699 void RemoveBreakpoint(intptr_t bp_id);
700 Breakpoint* GetBreakpointById(intptr_t id);
701
702 void AsyncStepInto(const Closure& awaiter);
703
704 void Continue();
705
707 intptr_t frame_index = 1,
708 const char** error = nullptr);
709
710 bool IsStepping() const { return resume_action_ != kContinue; }
711
712 bool IsSingleStepping() const { return resume_action_ == kStepInto; }
713
714 bool IsPaused() const { return pause_event_ != nullptr; }
715
716 bool ignore_breakpoints() const { return ignore_breakpoints_; }
718 ignore_breakpoints_ = ignore_breakpoints;
719 }
720
721 // Put the isolate into single stepping mode when Dart code next runs.
722 //
723 // This is used by the vm service to allow the user to step while
724 // paused at isolate start.
725 void EnterSingleStepMode();
726
727 // Indicates why the debugger is currently paused. If the debugger
728 // is not paused, this returns nullptr. Note that the debugger can be
729 // paused for breakpoints, isolate interruption, and (sometimes)
730 // exceptions.
731 const ServiceEvent* PauseEvent() const { return pause_event_; }
732
735
737
738 // Returns a stack trace with frames corresponding to invisible functions
739 // omitted. CurrentStackTrace always returns a new trace on the current stack.
740 // The trace returned by StackTrace may have been cached; it is suitable for
741 // use when stepping, but otherwise may be out of sync with the current stack.
743
745
746 // Pause execution for a breakpoint. Called from generated code.
747 ErrorPtr PauseBreakpoint();
748
749 // Pause execution due to stepping. Called from generated code.
750 ErrorPtr PauseStepping();
751
752 // Pause execution due to isolate interrupt.
753 ErrorPtr PauseInterrupted();
754
755 // Pause after a reload request.
756 ErrorPtr PausePostRequest();
757
758 // Pause execution due to an uncaught exception.
759 void PauseException(const Instance& exc);
760
761 // Pause execution due to a call to the debugger() function from
762 // Dart.
763 void PauseDeveloper(const String& msg);
764
765 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
766 void PrintSettingsToJSONObject(JSONObject* jsobj) const;
767
768 static bool IsDebuggable(const Function& func);
769
770 intptr_t limitBreakpointId() { return next_id_; }
771
772 // Callback to the debugger to continue frame rewind, post-deoptimization.
773 void RewindPostDeopt();
774
775 // Sets breakpoint at resumption of a suspendable function
776 // with given function data (such as _Future or _AsyncStarStreamController).
777 void SetBreakpointAtResumption(const Object& function_data);
778
779 // Check breakpoints at frame resumption. Called from generated code.
781
782 private:
783 ErrorPtr PauseRequest(ServiceEvent::EventKind kind);
784
785 // Will return false if we are not at an await.
786 bool SetupStepOverAsyncSuspension(const char** error);
787
788 bool NeedsIsolateEvents();
789 bool NeedsDebugEvents();
790
791 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);
792
793 void FindCompiledFunctions(
795 TokenPosition start_pos,
796 TokenPosition end_pos,
797 GrowableObjectArray* code_function_list);
798 bool FindBestFit(const Script& script,
799 TokenPosition token_pos,
800 TokenPosition last_token_pos,
801 Function* best_fit);
802 void DeoptimizeWorld();
803 void RunWithStoppedDeoptimizedWorld(std::function<void()> fun);
804 void NotifySingleStepping(bool value);
805 BreakpointLocation* SetCodeBreakpoints(
807 TokenPosition token_pos,
808 TokenPosition last_token_pos,
809 intptr_t requested_line,
810 intptr_t requested_column,
811 TokenPosition exact_token_pos,
812 const GrowableObjectArray& functions);
813 BreakpointLocation* SetBreakpoint(const Script& script,
814 TokenPosition token_pos,
815 TokenPosition last_token_pos,
816 intptr_t requested_line,
817 intptr_t requested_column,
818 const Function& function);
819 BreakpointLocation* SetBreakpoint(
821 TokenPosition token_pos,
822 TokenPosition last_token_pos,
823 intptr_t requested_line,
824 intptr_t requested_column,
825 const Function& function);
826 bool RemoveBreakpointFromTheList(intptr_t bp_id, BreakpointLocation** list);
827 Breakpoint* GetBreakpointByIdInTheList(intptr_t id, BreakpointLocation* list);
828 BreakpointLocation* GetLatentBreakpoint(const String& url,
829 intptr_t line,
830 intptr_t column);
831 void RegisterBreakpointLocationUnsafe(BreakpointLocation* loc);
832 void RegisterBreakpointLocation(BreakpointLocation* bpt);
833 BreakpointLocation* GetResolvedBreakpointLocation(
834 const String& script_url,
835 TokenPosition code_token_pos);
836 BreakpointLocation* GetBreakpointLocation(
837 const String& script_url,
838 TokenPosition token_pos,
839 intptr_t requested_line,
840 intptr_t requested_column,
841 TokenPosition code_token_pos = TokenPosition::kNoSource);
842
843 void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
844 JSONArray* jsarr) const;
845
846 void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);
847
848 intptr_t nextId() { return next_id_++; }
849
850 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
851 const Instance& exc);
852
853 // Handles any events which pause vm execution. Breakpoints,
854 // interrupts, etc.
855 void Pause(ServiceEvent* event);
856
857 void HandleSteppingRequest(bool skip_next_step = false);
858
859 void CacheStackTraces(DebuggerStackTrace* stack_trace,
860 DebuggerStackTrace* async_awaiter_stack_trace);
861 void ClearCachedStackTraces();
862
863 void RewindToFrame(intptr_t frame_index);
864 void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code);
865 void RewindToOptimizedFrame(StackFrame* frame,
866 const Code& code,
867 intptr_t post_deopt_frame_index);
868
869 void ResetSteppingFramePointer();
870 void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
871
872 GroupDebugger* group_debugger() { return isolate_->group()->debugger(); }
873
874 Isolate* isolate_;
875
876 // ID number generator.
877 intptr_t next_id_;
878
879 BreakpointLocation* latent_locations_;
880 BreakpointLocation* breakpoint_locations_;
881
882 // Tells debugger what to do when resuming execution after a breakpoint.
883 ResumeAction resume_action_;
884 void set_resume_action(ResumeAction action);
885 intptr_t resume_frame_index_;
886 intptr_t post_deopt_frame_index_;
887
888 // Do not call back to breakpoint handler if this flag is set.
889 // Effectively this means ignoring breakpoints. Set when Dart code may
890 // be run as a side effect of getting values of fields.
891 bool ignore_breakpoints_;
892
893 // Indicates why the debugger is currently paused. If the debugger
894 // is not paused, this is nullptr. Note that the debugger can be
895 // paused for breakpoints, isolate interruption, and (sometimes)
896 // exceptions.
897 ServiceEvent* pause_event_;
898
899 // Current stack trace. Valid only while IsPaused().
900 DebuggerStackTrace* stack_trace_;
901 DebuggerStackTrace* async_awaiter_stack_trace_;
902
903 // When stepping through code, only pause the program if the top
904 // frame corresponds to this fp value, or if the top frame is
905 // lower on the stack.
906 uword stepping_fp_;
907
908 // When stepping through code, do not stop more than once in the same
909 // token position range.
910 uword last_stepping_fp_;
911 TokenPosition last_stepping_pos_;
912
913 // If we step while at a breakpoint, we would hit the same pc twice.
914 // We use this field to let us skip the next single-step after a
915 // breakpoint.
916 bool skip_next_step_;
917
918 Dart_ExceptionPauseInfo exc_pause_info_;
919
920 // Holds function data corresponding to suspendable
921 // function which should be stopped when resumed.
922 MallocGrowableArray<ObjectPtr> breakpoints_at_resumption_;
923
924 friend class Isolate;
925 friend class BreakpointLocation;
927};
928
930 public:
931 DisableBreakpointsScope(Debugger* debugger, bool disable)
932 : debugger_(debugger) {
933 ASSERT(debugger_ != nullptr);
934 initial_state_ = debugger_->ignore_breakpoints();
935 debugger_->set_ignore_breakpoints(disable);
936 }
937
939 debugger_->set_ignore_breakpoints(initial_state_);
940 }
941
942 private:
943 Debugger* debugger_;
944 bool initial_state_;
945
947};
948
949} // namespace dart
950
951#endif // !defined(PRODUCT)
952
953#endif // RUNTIME_VM_DEBUGGER_H_
#define UNREACHABLE()
Definition assert.h:248
intptr_t ColumnNumber()
Definition debugger.cc:562
StringPtr QualifiedFunctionName()
Definition debugger.cc:492
const Context & GetSavedCurrentContext()
Definition debugger.cc:700
LibraryPtr Library()
Definition debugger.cc:505
Relation CompareTo(uword other_fp) const
Definition debugger.cc:485
void PrintToJSONObject(JSONObject *jsobj)
Definition debugger.cc:1221
const Closure & closure() const
Definition debugger.h:314
const Function & function() const
Definition debugger.h:316
ArrayPtr GetLocalVariables()
Definition debugger.cc:1033
uword fp() const
Definition debugger.h:307
ClosurePtr GetClosure()
Definition debugger.cc:860
uword sp() const
Definition debugger.h:308
ObjectPtr GetParameter(intptr_t index)
Definition debugger.cc:838
intptr_t LineNumber()
Definition debugger.cc:552
bool IsDebuggable() const
Definition debugger.cc:595
const char * ToCString()
Definition debugger.cc:1190
ScriptPtr SourceScript()
Definition debugger.cc:501
ObjectPtr GetSuspendableFunctionData()
Definition debugger.cc:873
bool HandlesException(const Instance &exc_obj)
Definition debugger.cc:657
ObjectPtr GetReceiver()
Definition debugger.cc:1048
StringPtr SourceUrl()
Definition debugger.cc:496
uword pc() const
Definition debugger.h:306
Kind kind() const
Definition debugger.h:304
uword GetCallerSp() const
Definition debugger.h:310
intptr_t NumLocalVariables()
Definition debugger.cc:828
ObjectPtr GetSuspendStateVar()
Definition debugger.cc:868
ObjectPtr EvaluateCompiledExpression(const ExternalTypedData &kernel_data, const Array &arguments, const Array &type_definitions, const TypeArguments &type_arguments)
Definition debugger.cc:1071
TypeArgumentsPtr BuildParameters(const GrowableObjectArray &param_names, const GrowableObjectArray &param_values, const GrowableObjectArray &type_params_names, const GrowableObjectArray &type_params_bounds, const GrowableObjectArray &type_params_defaults)
Definition debugger.cc:1099
const Code & code() const
Definition debugger.h:317
bool IsRewindable() const
Definition debugger.cc:891
intptr_t ContextLevel()
Definition debugger.cc:624
void VariableAt(intptr_t i, String *name, TokenPosition *declaration_token_pos, TokenPosition *visible_start_token_pos, TokenPosition *visible_end_token_pos, Object *value)
Definition debugger.cc:956
TokenPosition TokenPos()
Definition debugger.cc:519
const T & At(intptr_t index) const
intptr_t length() const
virtual bool Call()=0
virtual ~BoolCallable()
Definition debugger.h:552
TokenPosition token_pos() const
Definition debugger.h:126
bool AnyEnabled() const
Definition debugger.cc:115
TokenPosition end_token_pos() const
Definition debugger.h:128
Debugger * debugger()
Definition debugger.h:156
intptr_t requested_column_number() const
Definition debugger.h:139
Breakpoint * AddSingleShot(Debugger *dbg)
Definition debugger.cc:344
bool EnsureIsResolved(const Function &target_function, TokenPosition exact_token_pos)
Definition debugger.cc:2172
StringPtr url() const
Definition debugger.h:136
Breakpoint * AddRepeated(Debugger *dbg)
Definition debugger.cc:340
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)
Definition debugger.cc:60
bool IsResolved() const
Definition debugger.h:150
ScriptPtr script() const
Definition debugger.h:130
Breakpoint * AddBreakpoint(Debugger *dbg, const Closure &closure, bool single_shot)
Definition debugger.cc:348
void GetCodeLocation(Script *script, TokenPosition *token_pos) const
Definition debugger.cc:142
intptr_t requested_line_number() const
Definition debugger.h:138
bool IsLatent() const
Definition debugger.h:151
friend class Debugger
Definition debugger.h:191
ClosurePtr closure() const
Definition debugger.h:68
BreakpointLocation * bpt_location() const
Definition debugger.h:64
bool is_enabled() const
Definition debugger.h:80
bool is_single_shot() const
Definition debugger.h:67
Breakpoint * next() const
Definition debugger.h:61
void set_bpt_location(BreakpointLocation *new_bpt_location)
Definition debugger.cc:168
intptr_t id() const
Definition debugger.h:60
void set_next(Breakpoint *n)
Definition debugger.h:62
void PrintJSON(JSONStream *stream)
Definition debugger.cc:191
Breakpoint(intptr_t id, BreakpointLocation *bpt_location, bool is_single_shot, const Closure &closure)
Definition debugger.h:50
FunctionPtr function() const
Definition debugger.h:222
bool IsEnabled() const
Definition debugger.h:233
const char * ToCString() const
Definition debugger.cc:211
CodeBreakpoint(const Code &code, BreakpointLocation *loc, uword pc, UntaggedPcDescriptors::Kind kind)
Definition debugger.cc:1317
CodePtr OrigStubAddress() const
bool HasNoBreakpointLocations()
Definition debugger.h:227
bool HasBreakpointLocation(BreakpointLocation *breakpoint_location)
Definition debugger.cc:1360
bool FindAndDeleteBreakpointLocation(BreakpointLocation *breakpoint_location)
Definition debugger.cc:1370
uword pc() const
Definition debugger.h:224
static bool IsKeyEqual(Pair kv, Key key)
Definition debugger.h:528
static Value ValueOf(Pair kv)
Definition debugger.h:524
static uword Hash(Key key)
Definition debugger.h:525
const Debugger * Key
Definition debugger.h:511
static Key KeyOf(Pair kv)
Definition debugger.h:523
void Remove(const Key &key)
Definition debugger.h:544
virtual ~DebuggerSet()
Definition debugger.h:537
DebuggerKeyValueTrait::Pair Pair
Definition debugger.h:535
void Insert(const Key &key)
Definition debugger.h:539
DebuggerKeyValueTrait::Value Value
Definition debugger.h:534
DebuggerKeyValueTrait::Key Key
Definition debugger.h:533
intptr_t Length() const
Definition debugger.h:463
ActivationFrame * GetHandlerFrame(const Instance &exc_obj) const
Definition debugger.cc:733
static DebuggerStackTrace * Collect()
Definition debugger.cc:1671
ActivationFrame * FrameAt(int i) const
Definition debugger.h:465
void set_has_async_catch_error(bool has_async_catch_error)
Definition debugger.h:478
bool has_async_catch_error() const
Definition debugger.h:477
DebuggerStackTrace(int capacity)
Definition debugger.h:460
static DebuggerStackTrace * From(const class StackTrace &ex_trace)
Definition debugger.cc:1808
static DebuggerStackTrace * CollectAsyncAwaiters()
Definition debugger.cc:1732
bool IsStepping() const
Definition debugger.h:710
Breakpoint * SetBreakpointAtEntry(const Function &target_function, bool single_shot)
Definition debugger.cc:2699
void AsyncStepInto(const Closure &awaiter)
Definition debugger.cc:4142
Dart_ExceptionPauseInfo GetExceptionPauseInfo() const
Definition debugger.cc:1867
bool SetBreakpointState(Breakpoint *bpt, bool enable)
Definition debugger.cc:3927
void ResumptionBreakpoint()
Definition debugger.cc:2760
Breakpoint * SetBreakpointAtActivation(const Instance &closure, bool single_shot)
Definition debugger.cc:2720
bool SetResumeAction(ResumeAction action, intptr_t frame_index=1, const char **error=nullptr)
Definition debugger.cc:1486
void RemoveBreakpoint(intptr_t bp_id)
Definition debugger.cc:3944
void PrintBreakpointsToJSONArray(JSONArray *jsarr) const
Definition debugger.cc:451
Isolate * isolate() const
Definition debugger.h:671
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition debugger.cc:3014
void PauseException(const Instance &exc)
Definition debugger.cc:1914
void PrintSettingsToJSONObject(JSONObject *jsobj) const
Definition debugger.cc:468
DebuggerStackTrace * StackTrace()
Definition debugger.cc:1797
void RewindPostDeopt()
Definition debugger.cc:3360
bool ignore_breakpoints() const
Definition debugger.h:716
DebuggerStackTrace * AsyncAwaiterStackTrace()
Definition debugger.cc:1802
BreakpointLocation * BreakpointLocationAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition debugger.cc:2817
friend class BreakpointLocation
Definition debugger.h:925
void NotifyIsolateCreated()
Definition debugger.cc:3726
ErrorPtr PauseInterrupted()
Definition debugger.cc:289
bool IsSingleStepping() const
Definition debugger.h:712
ErrorPtr PausePostRequest()
Definition debugger.cc:293
Breakpoint * SetBreakpointAtLine(const String &script_url, intptr_t line_number)
Definition debugger.cc:2786
ErrorPtr PauseStepping()
Definition debugger.cc:3524
const ServiceEvent * PauseEvent() const
Definition debugger.h:731
void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info)
Definition debugger.cc:1860
Breakpoint * GetBreakpointById(intptr_t id)
Definition debugger.cc:4118
Breakpoint * BreakpointAtActivation(const Instance &closure)
Definition debugger.cc:2733
bool IsPaused() const
Definition debugger.h:714
void set_ignore_breakpoints(bool ignore_breakpoints)
Definition debugger.h:717
void NotifyDoneLoading()
Definition debugger.cc:3749
void PauseDeveloper(const String &msg)
Definition debugger.cc:3705
@ kStepOverAsyncSuspension
Definition debugger.h:665
void SetBreakpointAtResumption(const Object &function_data)
Definition debugger.cc:2753
Breakpoint * SetBreakpointAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition debugger.cc:2801
intptr_t limitBreakpointId()
Definition debugger.h:770
void EnterSingleStepMode()
Definition debugger.cc:3079
friend class Isolate
Definition debugger.h:924
static bool IsDebuggable(const Function &func)
Definition debugger.cc:3403
ErrorPtr PauseBreakpoint()
Definition debugger.cc:3610
static constexpr intptr_t kNone
Definition deopt_id.h:27
DisableBreakpointsScope(Debugger *debugger, bool disable)
Definition debugger.h:931
RwLock * single_stepping_set_lock()
Definition debugger.h:622
CodePtr GetPatchedStubAddress(uword breakpoint_address)
Definition debugger.cc:3917
bool HasCodeBreakpointInFunction(const Function &func)
Definition debugger.cc:427
void RegisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
Definition debugger.cc:3412
void UnregisterBreakpointLocation(BreakpointLocation *location)
Definition debugger.cc:4026
void RemoveBreakpointLocation(BreakpointLocation *bpt_location)
bool HasCodeBreakpointInFunctionUnsafe(const Function &func)
Definition debugger.cc:414
bool HasBreakpointInCode(const Code &code)
Definition debugger.cc:438
IsolateGroup * isolate_group()
Definition debugger.h:634
bool HasBreakpoint(Thread *thread, const Function &function)
Definition debugger.cc:3441
void MakeCodeBreakpointAt(const Function &func, BreakpointLocation *bpt)
Definition debugger.cc:2269
SafepointRwLock * code_breakpoints_lock()
Definition debugger.h:614
bool IsDebugging(Thread *thread, const Function &function)
Definition debugger.cc:3465
bool HasBreakpointInFunction(const Function &func)
bool EnsureLocationIsInFunction(Zone *zone, const Function &function, BreakpointLocation *location)
Definition debugger.cc:2916
BreakpointLocation * GetBreakpointLocationFor(Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
Definition debugger.cc:3893
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition debugger.cc:3005
bool HasCodeBreakpointInCode(const Code &code)
bool HasActiveBreakpoint(uword pc)
Definition debugger.cc:3876
void NotifyCompilation(const Function &func)
Definition debugger.cc:2954
void MakeCodeBreakpointAtUnsafe(const Function &func, BreakpointLocation *bpt)
Definition debugger.cc:2211
void RegisterBreakpointLocation(BreakpointLocation *location)
Definition debugger.cc:4020
bool HasBreakpointUnsafe(Thread *thread, const Function &function)
Definition debugger.cc:3424
CodeBreakpoint * GetCodeBreakpoint(uword breakpoint_address)
Definition debugger.cc:3882
void SyncBreakpointLocation(BreakpointLocation *loc)
Definition debugger.cc:2683
void UnregisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
Definition debugger.cc:3418
SafepointRwLock * breakpoint_locations_lock()
Definition debugger.h:618
void UnlinkCodeBreakpoints(BreakpointLocation *bpt_location)
Definition debugger.cc:4040
GroupDebugger * debugger() const
Definition isolate.h:314
IsolateGroup * group() const
Definition isolate.h:990
LambdaBoolCallable(T &lambda)
Definition debugger.h:563
static ObjectPtr null()
Definition object.h:433
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static Object & ZoneHandle()
Definition object.h:419
static uint32_t WordHash(intptr_t key)
Definition utils.cc:217
#define ASSERT(E)
double frame
Definition examples.cpp:31
FlKeyEvent * event
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
#define DECLARE_FLAG(type, name)
Definition flags.h:14
Dart_NativeFunction function
Definition fuchsia.cc:51
Win32Message message
const char *const name
uintptr_t uword
Definition globals.h:501
static constexpr int kCallerSpSlotFromFp
constexpr intptr_t kWordSize
Definition globals.h:509
Dart_ExceptionPauseInfo
Definition debugger.h:502
@ kInvalidExceptionPauseInfo
Definition debugger.h:506
@ kPauseOnUnhandledExceptions
Definition debugger.h:504
@ kNoPauseOnExceptions
Definition debugger.h:503
@ kPauseOnAllExceptions
Definition debugger.h:505
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
#define T
Pair(const Key key, const Value &value)
Definition debugger.h:518
Pair & operator=(const Pair &)=default