Flutter Engine
The Flutter Engine
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
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//
102// An unresolved breakpoint, also known as a pending breakpoint, is one where
103// the underlying code has not been compiled yet. Since the code has not been
104// compiled, we can't determine the definitive token position to associate with
105// the breakpoint yet.
106//
107// A latent breakpoint represents a breakpoint location in Dart source
108// that is not loaded in the VM when the breakpoint is requested.
109// When a script with matching url is loaded, a latent breakpoint
110// becomes an unresolved breakpoint.
112 public:
113 // Create a new unresolved breakpoint.
118 intptr_t requested_line_number,
119 intptr_t requested_column_number);
120 // Create a new latent breakpoint.
122 const String& url,
123 intptr_t requested_line_number,
124 intptr_t requested_column_number);
125
127
128 TokenPosition token_pos() const { return token_pos_.load(); }
129 intptr_t line_number();
130 TokenPosition end_token_pos() const { return end_token_pos_.load(); }
131
132 ScriptPtr script() const {
133 if (scripts_.length() == 0) {
134 return Script::null();
135 }
136 return scripts_.At(0);
137 }
138 StringPtr url() const { return url_; }
139
140 intptr_t requested_line_number() const { return requested_line_number_; }
141 intptr_t requested_column_number() const { return requested_column_number_; }
142
144
148 const Closure& closure,
149 bool single_shot);
150
151 bool AnyEnabled() const;
152 bool IsResolved() const { return code_token_pos_.IsReal(); }
153 bool IsLatent() const { return !token_pos().IsReal(); }
154
155 bool EnsureIsResolved(const Function& target_function,
156 TokenPosition exact_token_pos);
157
158 Debugger* debugger() { return debugger_; }
159
160 private:
161 void VisitObjectPointers(ObjectPointerVisitor* visitor);
162
163 void SetResolved(const Function& func, TokenPosition token_pos);
164
165 BreakpointLocation* next() const { return this->next_; }
166 void set_next(BreakpointLocation* value) { next_ = value; }
167
168 void AddBreakpoint(Breakpoint* bpt, Debugger* dbg);
169
170 Breakpoint* breakpoints() const { return this->conditions_; }
171 void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }
172
173 // Finds the breakpoint we hit at |location|.
174 Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);
175
176 SafepointRwLock* line_number_lock() { return line_number_lock_.get(); }
177
178 Debugger* debugger_;
179 MallocGrowableArray<ScriptPtr> scripts_;
180 StringPtr url_;
181 std::unique_ptr<SafepointRwLock> line_number_lock_;
182 intptr_t line_number_; // lazily computed for token_pos_
183 std::atomic<TokenPosition> token_pos_;
184 std::atomic<TokenPosition> end_token_pos_;
185 BreakpointLocation* next_;
186 Breakpoint* conditions_;
187 intptr_t requested_line_number_;
188 intptr_t requested_column_number_;
189
190 // Valid for resolved breakpoints:
191 TokenPosition code_token_pos_;
192
193 friend class Debugger;
194 friend class GroupDebugger;
196};
197
198// CodeBreakpoint represents a location in compiled code.
199// There may be more than one CodeBreakpoint for one BreakpointLocation,
200// e.g. when a function gets compiled as a regular function and as a closure.
201// There may be more than one BreakpointLocation associated with CodeBreakpoint,
202// one for every isolate in a group that sets a breakpoint at particular
203// code location represented by the CodeBreakpoint.
204// Each BreakpointLocation might be enabled/disabled based on whether it has
205// any actual breakpoints associated with it.
206// The CodeBreakpoint is enabled if it has any such BreakpointLocations
207// associated with it.
208// The class is not thread-safe - users of this class need to ensure the access
209// is synchronized, guarded by mutexes or run inside of a safepoint scope.
211 public:
212 // Unless CodeBreakpoint is unlinked and is no longer used there should be at
213 // least one BreakpointLocation associated with CodeBreakpoint. If there are
214 // more BreakpointLocation added assumption is is that all of them point to
215 // the same source so have the same token pos.
216 CodeBreakpoint(const Code& code,
218 uword pc,
221
222 // Used by GroupDebugger to find CodeBreakpoint associated with
223 // particular function.
224 FunctionPtr function() const { return Code::Handle(code_).function(); }
225
226 uword pc() const { return pc_; }
227 bool HasBreakpointLocation(BreakpointLocation* breakpoint_location);
228 bool FindAndDeleteBreakpointLocation(BreakpointLocation* breakpoint_location);
230 return breakpoint_locations_.length() == 0;
231 }
232
233 void Enable();
234 void Disable();
235 bool IsEnabled() const { return enabled_count_ > 0; }
236
237 CodePtr OrigStubAddress() const;
238
239 const char* ToCString() const;
240
241 private:
242 void VisitObjectPointers(ObjectPointerVisitor* visitor);
243
244 // Finds right BreakpointLocation for a given Isolate's debugger.
245 BreakpointLocation* FindBreakpointForDebugger(Debugger* debugger);
246 // Adds new BreakpointLocation for another isolate that wants to
247 // break at the same function/code location that this CodeBreakpoint
248 // represents.
249 void AddBreakpointLocation(BreakpointLocation* breakpoint_location) {
250 ASSERT(breakpoint_locations_.length() == 0 ||
251 (breakpoint_location->token_pos() ==
252 breakpoint_locations_.At(0)->token_pos() &&
253 breakpoint_location->url() == breakpoint_locations_.At(0)->url()));
254 breakpoint_locations_.Add(breakpoint_location);
255 }
256
257 void set_next(CodeBreakpoint* value) { next_ = value; }
258 CodeBreakpoint* next() const { return this->next_; }
259
260 void PatchCode();
261 void RestoreCode();
262
263 CodePtr code_;
264 uword pc_;
265 int enabled_count_; // incremented for every enabled breakpoint location
266
267 // Breakpoint locations from different debuggers/isolates that
268 // point to this code breakpoint.
269 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
270 CodeBreakpoint* next_;
271
272 UntaggedPcDescriptors::Kind breakpoint_kind_;
273 CodePtr saved_value_;
274
275 friend class Debugger;
276 friend class GroupDebugger;
278};
279
280// ActivationFrame represents one dart function activation frame
281// on the call stack.
283 public:
284 enum Kind {
288 };
289
291 uword fp,
292 uword sp,
293 const Code& code,
294 const Array& deopt_frame,
295 intptr_t deopt_frame_offset);
296
297 // Create a |kAsyncAwaiter| frame representing asynchronous awaiter
298 // waiting for the completion of a |Future|.
299 //
300 // |closure| is the listener which will be invoked when awaited
301 // computation completes.
303
304 explicit ActivationFrame(Kind kind);
305
306 Kind kind() const { return kind_; }
307
308 uword pc() const { return pc_; }
309 uword fp() const { return fp_; }
310 uword sp() const { return sp_; }
311
313
314 // For |kAsyncAwaiter| frames this is the listener which will be invoked
315 // when the frame below (callee) completes.
316 const Closure& closure() const { return closure_; }
317
318 const Function& function() const { return function_; }
319 const Code& code() const {
320 ASSERT(!code_.IsNull());
321 return code_;
322 }
323
324 enum Relation {
328 };
329
330 Relation CompareTo(uword other_fp) const;
331
332 StringPtr QualifiedFunctionName();
333 StringPtr SourceUrl();
334 ScriptPtr SourceScript();
335 LibraryPtr Library();
337 intptr_t LineNumber();
338 intptr_t ColumnNumber();
339
340 // Returns true if this frame is for a function that is visible
341 // to the user and can be debugged.
342 bool IsDebuggable() const;
343
344 // Returns true if it is possible to rewind the debugger to this frame.
345 bool IsRewindable() const;
346
347 // The context level of a frame is the context level at the
348 // PC/token index of the frame. It determines the depth of the context
349 // chain that belongs to the function of this activation frame.
350 intptr_t ContextLevel();
351
352 const char* ToCString();
353
354 intptr_t NumLocalVariables();
355
356 void VariableAt(intptr_t i,
357 String* name,
358 TokenPosition* declaration_token_pos,
359 TokenPosition* visible_start_token_pos,
360 TokenPosition* visible_end_token_pos,
361 Object* value);
362
363 ArrayPtr GetLocalVariables();
364 ObjectPtr GetParameter(intptr_t index);
365 ClosurePtr GetClosure();
367
371
372 TypeArgumentsPtr BuildParameters(
373 const GrowableObjectArray& param_names,
374 const GrowableObjectArray& param_values,
375 const GrowableObjectArray& type_params_names,
376 const GrowableObjectArray& type_params_bounds,
377 const GrowableObjectArray& type_params_defaults);
378
380 const Array& arguments,
381 const Array& type_definitions,
382 const TypeArguments& type_arguments);
383
384 void PrintToJSONObject(JSONObject* jsobj);
385
386 bool HandlesException(const Instance& exc_obj);
387
388 private:
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);
396
397 intptr_t TryIndex();
398 intptr_t DeoptId();
399 void GetPcDescriptors();
400 void GetVarDescriptors();
401 void GetDescIndices();
402
403 static const char* KindToCString(Kind kind) {
404 switch (kind) {
405 case kRegular:
406 return "Regular";
407 case kAsyncAwaiter:
408 // Keeping the legacy name in the protocol itself.
409 return "AsyncCausal";
411 return "AsyncSuspensionMarker";
412 default:
413 UNREACHABLE();
414 return "";
415 }
416 }
417
418 ObjectPtr GetStackVar(VariableIndex var_index);
419 ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
420 intptr_t slot_index,
421 intptr_t frame_ctx_level);
422 ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
423
424 uword pc_ = 0;
425 uword fp_ = 0;
426 uword sp_ = 0;
427
428 // The anchor of the context chain for this function.
430 const Code& code_;
431 const Function& function_;
432 const Closure& closure_;
433
434 bool token_pos_initialized_ = false;
435 TokenPosition token_pos_ = TokenPosition::kNoSource;
436 intptr_t try_index_ = -1;
437 intptr_t deopt_id_ = dart::DeoptId::kNone;
438
439 intptr_t line_number_ = -1;
440 intptr_t column_number_ = -1;
441 intptr_t context_level_ = -1;
442
443 // Some frames are deoptimized into a side array in order to inspect them.
444 const Array& deopt_frame_;
445 const intptr_t deopt_frame_offset_;
446
447 Kind kind_;
448
449 bool vars_initialized_ = false;
450 LocalVarDescriptors& var_descriptors_ = LocalVarDescriptors::ZoneHandle();
451 ZoneGrowableArray<intptr_t> desc_indices_;
452 PcDescriptors& pc_desc_ = PcDescriptors::ZoneHandle();
453
454 friend class Debugger;
455 friend class DebuggerStackTrace;
457};
458
459// Array of function activations on the call stack.
461 public:
462 explicit DebuggerStackTrace(int capacity)
463 : thread_(Thread::Current()), zone_(thread_->zone()), trace_(capacity) {}
464
465 intptr_t Length() const { return trace_.length(); }
466
467 ActivationFrame* FrameAt(int i) const { return trace_[i]; }
468
469 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
470
471 static DebuggerStackTrace* Collect();
473
474 // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
475 // Frames corresponding to invisible functions are omitted. It is not valid
476 // to query local variables in the returned stack.
477 static DebuggerStackTrace* From(const class StackTrace& ex_trace);
478
479 bool has_async_catch_error() const { return has_async_catch_error_; }
481 has_async_catch_error_ = has_async_catch_error;
482 }
483
484 private:
485 void AddActivation(ActivationFrame* frame);
486 void AddAsyncSuspension();
487 void AddAsyncAwaiterFrame(uword pc, const Code& code, const Closure& closure);
488
489 void AppendCodeFrames(StackFrame* frame, const Code& code);
490
491 Thread* thread_;
492 Zone* zone_;
493 Code& inlined_code_ = Code::Handle();
494 Array& deopt_frame_ = Array::Handle();
496 bool has_async_catch_error_ = false;
497
498 friend class Debugger;
499
501};
502
503// On which exceptions to pause.
504typedef enum {
510
512 public:
513 typedef const Debugger* Key;
514 typedef bool Value;
515
516 struct Pair {
519 Pair() : key(nullptr), value(false) {}
520 Pair(const Key key, const Value& value) : key(key), value(value) {}
521 Pair(const Pair& other) : key(other.key), value(other.value) {}
522 Pair& operator=(const Pair&) = default;
523 };
524
525 static Key KeyOf(Pair kv) { return kv.key; }
526 static Value ValueOf(Pair kv) { return kv.value; }
527 static uword Hash(Key key) {
528 return Utils::WordHash(reinterpret_cast<intptr_t>(key));
529 }
530 static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
531};
532
533class DebuggerSet : public MallocDirectChainedHashMap<DebuggerKeyValueTrait> {
534 public:
538
539 virtual ~DebuggerSet() { Clear(); }
540
541 void Insert(const Key& key) {
542 Pair pair(key, /*value=*/true);
544 }
545
546 void Remove(const Key& key) {
548 }
549};
550
551class BoolCallable : public ValueObject {
552 public:
554 virtual ~BoolCallable() {}
555
556 virtual bool Call() = 0;
557
558 private:
559 DISALLOW_COPY_AND_ASSIGN(BoolCallable);
560};
561
562template <typename T>
564 public:
565 explicit LambdaBoolCallable(T& lambda) : lambda_(lambda) {}
566 bool Call() { return lambda_(); }
567
568 private:
569 T& lambda_;
570 DISALLOW_COPY_AND_ASSIGN(LambdaBoolCallable);
571};
572
574 public:
577
578 void MakeCodeBreakpointAtUnsafe(const Function& func,
579 BreakpointLocation* bpt);
580 void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt);
581
582 // Returns [nullptr] if no breakpoint exists for the given address.
583 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
585 uword breakpoint_address,
586 CodeBreakpoint** pcbpt);
587 CodePtr GetPatchedStubAddress(uword breakpoint_address);
588
591
593 void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);
594
595 // Returns true if the call at address pc is patched to point to
596 // a debugger stub.
597 bool HasActiveBreakpoint(uword pc);
599 bool HasCodeBreakpointInFunction(const Function& func);
601
603 bool HasBreakpointInCode(const Code& code);
604
606
607 void Pause();
608
610 const Function& function,
611 BreakpointLocation* location);
612 void NotifyCompilation(const Function& func);
613
615
617 return code_breakpoints_lock_.get();
618 }
619
621 return breakpoint_locations_lock_.get();
622 }
623
624 RwLock* single_stepping_set_lock() { return single_stepping_set_lock_.get(); }
625
626 void RegisterSingleSteppingDebugger(Thread* thread, const Debugger* debugger);
628 const Debugger* debugger);
629
630 // Returns [true] if there is at least one breakpoint set in function or code.
631 // Checks for both user-defined and internal temporary breakpoints.
632 bool HasBreakpointUnsafe(Thread* thread, const Function& function);
633 bool HasBreakpoint(Thread* thread, const Function& function);
634 bool IsDebugging(Thread* thread, const Function& function);
635
636 IsolateGroup* isolate_group() { return isolate_group_; }
637
638 private:
639 IsolateGroup* isolate_group_;
640
641 std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
642 CodeBreakpoint* code_breakpoints_;
643
644 // Secondary list of all breakpoint_locations_(primary is in Debugger class).
645 // This list is kept in sync with all the lists in Isolate Debuggers and is
646 // used to quickly scan BreakpointLocations when new Function is compiled.
647 std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
648 MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
649
650 std::unique_ptr<RwLock> single_stepping_set_lock_;
651 DebuggerSet single_stepping_set_;
652
653 void RemoveUnlinkedCodeBreakpoints();
654 void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
655
656 bool needs_breakpoint_cleanup_;
657};
658
659class Debugger {
660 public:
668 };
669
670 explicit Debugger(Isolate* isolate);
671 ~Debugger();
672
673 Isolate* isolate() const { return isolate_; }
674
676 void Shutdown();
677
678 void NotifyDoneLoading();
679
680 // Set breakpoint at closest location to function entry.
681 Breakpoint* SetBreakpointAtEntry(const Function& target_function,
682 bool single_shot);
684 bool single_shot);
686
687 // TODO(turnidge): script_url may no longer be specific enough.
688 Breakpoint* SetBreakpointAtLine(const String& script_url,
689 intptr_t line_number);
690 Breakpoint* SetBreakpointAtLineCol(const String& script_url,
691 intptr_t line_number,
692 intptr_t column_number);
693
695 intptr_t line_number,
696 intptr_t column_number);
697
698 // Returns true if the breakpoint's state changed.
699 bool SetBreakpointState(Breakpoint* bpt, bool enable);
700
701 void RemoveBreakpoint(intptr_t bp_id);
702 Breakpoint* GetBreakpointById(intptr_t id);
703
704 void AsyncStepInto(const Closure& awaiter);
705
706 void Continue();
707
709 intptr_t frame_index = 1,
710 const char** error = nullptr);
711
712 bool IsStepping() const { return resume_action_ != kContinue; }
713
714 bool IsSingleStepping() const { return resume_action_ == kStepInto; }
715
716 bool IsPaused() const { return pause_event_ != nullptr; }
717
718 bool ignore_breakpoints() const { return ignore_breakpoints_; }
720 ignore_breakpoints_ = ignore_breakpoints;
721 }
722
723 // Put the isolate into single stepping mode when Dart code next runs.
724 //
725 // This is used by the vm service to allow the user to step while
726 // paused at isolate start.
727 void EnterSingleStepMode();
728
729 // Indicates why the debugger is currently paused. If the debugger
730 // is not paused, this returns nullptr. Note that the debugger can be
731 // paused for breakpoints, isolate interruption, and (sometimes)
732 // exceptions.
733 const ServiceEvent* PauseEvent() const { return pause_event_; }
734
737
739
740 // Returns a stack trace with frames corresponding to invisible functions
741 // omitted. CurrentStackTrace always returns a new trace on the current stack.
742 // The trace returned by StackTrace may have been cached; it is suitable for
743 // use when stepping, but otherwise may be out of sync with the current stack.
745
747
748 // Pause execution for a breakpoint. Called from generated code.
749 ErrorPtr PauseBreakpoint();
750
751 // Pause execution due to stepping. Called from generated code.
752 ErrorPtr PauseStepping();
753
754 // Pause execution due to isolate interrupt.
755 ErrorPtr PauseInterrupted();
756
757 // Pause after a reload request.
758 ErrorPtr PausePostRequest();
759
760 // Pause execution due to an uncaught exception.
761 void PauseException(const Instance& exc);
762
763 // Pause execution due to a call to the debugger() function from
764 // Dart.
765 void PauseDeveloper(const String& msg);
766
767 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
768 void PrintSettingsToJSONObject(JSONObject* jsobj) const;
769
770 static bool IsDebuggable(const Function& func);
771
772 intptr_t limitBreakpointId() { return next_id_; }
773
774 // Callback to the debugger to continue frame rewind, post-deoptimization.
775 void RewindPostDeopt();
776
777 // Sets breakpoint at resumption of a suspendable function
778 // with given function data (such as _Future or _AsyncStarStreamController).
779 void SetBreakpointAtResumption(const Object& function_data);
780
781 // Check breakpoints at frame resumption. Called from generated code.
783
784 private:
785 ErrorPtr PauseRequest(ServiceEvent::EventKind kind);
786
787 // Will return false if we are not at an await.
788 bool SetupStepOverAsyncSuspension(const char** error);
789
790 bool NeedsIsolateEvents();
791 bool NeedsDebugEvents();
792
793 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);
794
795 void FindCompiledFunctions(
797 TokenPosition start_pos,
798 TokenPosition end_pos,
799 GrowableObjectArray* code_function_list);
800 bool FindBestFit(const Script& script,
801 TokenPosition token_pos,
802 TokenPosition last_token_pos,
803 Function* best_fit);
804 void DeoptimizeWorld();
805 void RunWithStoppedDeoptimizedWorld(std::function<void()> fun);
806 void NotifySingleStepping(bool value);
807 BreakpointLocation* SetCodeBreakpoints(
809 TokenPosition token_pos,
810 TokenPosition last_token_pos,
811 intptr_t requested_line,
812 intptr_t requested_column,
813 TokenPosition exact_token_pos,
814 const GrowableObjectArray& functions);
815 BreakpointLocation* SetBreakpoint(const Script& script,
816 TokenPosition token_pos,
817 TokenPosition last_token_pos,
818 intptr_t requested_line,
819 intptr_t requested_column,
820 const Function& function);
821 BreakpointLocation* SetBreakpoint(
823 TokenPosition token_pos,
824 TokenPosition last_token_pos,
825 intptr_t requested_line,
826 intptr_t requested_column,
827 const Function& function);
828 bool RemoveBreakpointFromTheList(intptr_t bp_id, BreakpointLocation** list);
829 Breakpoint* GetBreakpointByIdInTheList(intptr_t id, BreakpointLocation* list);
830 BreakpointLocation* GetLatentBreakpoint(const String& url,
831 intptr_t line,
832 intptr_t column);
833 void RegisterBreakpointLocationUnsafe(BreakpointLocation* loc);
834 void RegisterBreakpointLocation(BreakpointLocation* bpt);
835 BreakpointLocation* GetResolvedBreakpointLocation(
836 const String& script_url,
837 TokenPosition code_token_pos);
838 BreakpointLocation* GetBreakpointLocation(
839 const String& script_url,
840 TokenPosition token_pos,
841 intptr_t requested_line,
842 intptr_t requested_column,
843 TokenPosition code_token_pos = TokenPosition::kNoSource);
844
845 void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
846 JSONArray* jsarr) const;
847
848 void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);
849
850 intptr_t nextId() { return next_id_++; }
851
852 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
853 const Instance& exc);
854
855 // Handles any events which pause vm execution. Breakpoints,
856 // interrupts, etc.
857 void Pause(ServiceEvent* event);
858
859 void HandleSteppingRequest(bool skip_next_step = false);
860
861 void CacheStackTraces(DebuggerStackTrace* stack_trace,
862 DebuggerStackTrace* async_awaiter_stack_trace);
863 void ClearCachedStackTraces();
864
865 void RewindToFrame(intptr_t frame_index);
866 void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code);
867 void RewindToOptimizedFrame(StackFrame* frame,
868 const Code& code,
869 intptr_t post_deopt_frame_index);
870
871 void ResetSteppingFramePointer();
872 void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
873
874 GroupDebugger* group_debugger() { return isolate_->group()->debugger(); }
875
876 Isolate* isolate_;
877
878 // ID number generator.
879 intptr_t next_id_;
880
881 BreakpointLocation* latent_locations_;
882 BreakpointLocation* breakpoint_locations_;
883
884 // Tells debugger what to do when resuming execution after a breakpoint.
885 ResumeAction resume_action_;
886 void set_resume_action(ResumeAction action);
887 intptr_t resume_frame_index_;
888 intptr_t post_deopt_frame_index_;
889
890 // Do not call back to breakpoint handler if this flag is set.
891 // Effectively this means ignoring breakpoints. Set when Dart code may
892 // be run as a side effect of getting values of fields.
893 bool ignore_breakpoints_;
894
895 // Indicates why the debugger is currently paused. If the debugger
896 // is not paused, this is nullptr. Note that the debugger can be
897 // paused for breakpoints, isolate interruption, and (sometimes)
898 // exceptions.
899 ServiceEvent* pause_event_;
900
901 // Current stack trace. Valid only while IsPaused().
902 DebuggerStackTrace* stack_trace_;
903 DebuggerStackTrace* async_awaiter_stack_trace_;
904
905 // When stepping through code, only pause the program if the top
906 // frame corresponds to this fp value, or if the top frame is
907 // lower on the stack.
908 uword stepping_fp_;
909
910 // When stepping through code, do not stop more than once in the same
911 // token position range.
912 uword last_stepping_fp_;
913 TokenPosition last_stepping_pos_;
914
915 // If we step while at a breakpoint, we would hit the same pc twice.
916 // We use this field to let us skip the next single-step after a
917 // breakpoint.
918 bool skip_next_step_;
919
920 Dart_ExceptionPauseInfo exc_pause_info_;
921
922 // Holds function data corresponding to suspendable
923 // function which should be stopped when resumed.
924 MallocGrowableArray<ObjectPtr> breakpoints_at_resumption_;
925
926 friend class Isolate;
927 friend class BreakpointLocation;
929};
930
932 public:
933 DisableBreakpointsScope(Debugger* debugger, bool disable)
934 : debugger_(debugger) {
935 ASSERT(debugger_ != nullptr);
936 initial_state_ = debugger_->ignore_breakpoints();
937 debugger_->set_ignore_breakpoints(disable);
938 }
939
941 debugger_->set_ignore_breakpoints(initial_state_);
942 }
943
944 private:
945 Debugger* debugger_;
946 bool initial_state_;
947
948 DISALLOW_COPY_AND_ASSIGN(DisableBreakpointsScope);
949};
950
951} // namespace dart
952
953#endif // !defined(PRODUCT)
954
955#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:316
const Function & function() const
Definition: debugger.h:318
ArrayPtr GetLocalVariables()
Definition: debugger.cc:1033
uword fp() const
Definition: debugger.h:309
ClosurePtr GetClosure()
Definition: debugger.cc:860
ActivationFrame(uword pc, uword fp, uword sp, const Code &code, const Array &deopt_frame, intptr_t deopt_frame_offset)
Definition: debugger.cc:227
uword sp() const
Definition: debugger.h:310
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:308
Kind kind() const
Definition: debugger.h:306
uword GetCallerSp() const
Definition: debugger.h:312
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:319
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:554
TokenPosition token_pos() const
Definition: debugger.h:128
bool AnyEnabled() const
Definition: debugger.cc:115
TokenPosition end_token_pos() const
Definition: debugger.h:130
Debugger * debugger()
Definition: debugger.h:158
intptr_t requested_column_number() const
Definition: debugger.h:141
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:138
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:152
ScriptPtr script() const
Definition: debugger.h:132
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:140
bool IsLatent() const
Definition: debugger.h:153
friend class Debugger
Definition: debugger.h:193
ClosurePtr closure() const
Definition: debugger.h:68
void Enable()
Definition: debugger.h:70
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 Disable()
Definition: debugger.h:75
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:224
bool IsEnabled() const
Definition: debugger.h:235
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:229
bool HasBreakpointLocation(BreakpointLocation *breakpoint_location)
Definition: debugger.cc:1360
bool FindAndDeleteBreakpointLocation(BreakpointLocation *breakpoint_location)
Definition: debugger.cc:1370
uword pc() const
Definition: debugger.h:226
static bool IsKeyEqual(Pair kv, Key key)
Definition: debugger.h:530
static Value ValueOf(Pair kv)
Definition: debugger.h:526
static uword Hash(Key key)
Definition: debugger.h:527
const Debugger * Key
Definition: debugger.h:513
static Key KeyOf(Pair kv)
Definition: debugger.h:525
void Remove(const Key &key)
Definition: debugger.h:546
virtual ~DebuggerSet()
Definition: debugger.h:539
DebuggerKeyValueTrait::Pair Pair
Definition: debugger.h:537
void Insert(const Key &key)
Definition: debugger.h:541
DebuggerKeyValueTrait::Value Value
Definition: debugger.h:536
DebuggerKeyValueTrait::Key Key
Definition: debugger.h:535
intptr_t Length() const
Definition: debugger.h:465
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:467
void set_has_async_catch_error(bool has_async_catch_error)
Definition: debugger.h:480
bool has_async_catch_error() const
Definition: debugger.h:479
DebuggerStackTrace(int capacity)
Definition: debugger.h:462
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:712
Breakpoint * SetBreakpointAtEntry(const Function &target_function, bool single_shot)
Definition: debugger.cc:2722
void AsyncStepInto(const Closure &awaiter)
Definition: debugger.cc:4165
Dart_ExceptionPauseInfo GetExceptionPauseInfo() const
Definition: debugger.cc:1867
bool SetBreakpointState(Breakpoint *bpt, bool enable)
Definition: debugger.cc:3950
void ResumptionBreakpoint()
Definition: debugger.cc:2783
Debugger(Isolate *isolate)
Definition: debugger.cc:1408
Breakpoint * SetBreakpointAtActivation(const Instance &closure, bool single_shot)
Definition: debugger.cc:2743
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:3967
void PrintBreakpointsToJSONArray(JSONArray *jsarr) const
Definition: debugger.cc:451
Isolate * isolate() const
Definition: debugger.h:673
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: debugger.cc:3037
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:3383
void Continue()
Definition: debugger.cc:4179
bool ignore_breakpoints() const
Definition: debugger.h:718
DebuggerStackTrace * AsyncAwaiterStackTrace()
Definition: debugger.cc:1802
BreakpointLocation * BreakpointLocationAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition: debugger.cc:2840
friend class BreakpointLocation
Definition: debugger.h:927
void NotifyIsolateCreated()
Definition: debugger.cc:3749
ErrorPtr PauseInterrupted()
Definition: debugger.cc:289
bool IsSingleStepping() const
Definition: debugger.h:714
ErrorPtr PausePostRequest()
Definition: debugger.cc:293
Breakpoint * SetBreakpointAtLine(const String &script_url, intptr_t line_number)
Definition: debugger.cc:2809
ErrorPtr PauseStepping()
Definition: debugger.cc:3547
const ServiceEvent * PauseEvent() const
Definition: debugger.h:733
void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info)
Definition: debugger.cc:1860
Breakpoint * GetBreakpointById(intptr_t id)
Definition: debugger.cc:4141
Breakpoint * BreakpointAtActivation(const Instance &closure)
Definition: debugger.cc:2756
bool IsPaused() const
Definition: debugger.h:716
void set_ignore_breakpoints(bool ignore_breakpoints)
Definition: debugger.h:719
void NotifyDoneLoading()
Definition: debugger.cc:3772
void PauseDeveloper(const String &msg)
Definition: debugger.cc:3728
@ kStepOverAsyncSuspension
Definition: debugger.h:667
void SetBreakpointAtResumption(const Object &function_data)
Definition: debugger.cc:2776
Breakpoint * SetBreakpointAtLineCol(const String &script_url, intptr_t line_number, intptr_t column_number)
Definition: debugger.cc:2824
intptr_t limitBreakpointId()
Definition: debugger.h:772
void EnterSingleStepMode()
Definition: debugger.cc:3102
friend class Isolate
Definition: debugger.h:926
void Shutdown()
Definition: debugger.cc:1434
static bool IsDebuggable(const Function &func)
Definition: debugger.cc:3426
ErrorPtr PauseBreakpoint()
Definition: debugger.cc:3633
static constexpr intptr_t kNone
Definition: deopt_id.h:27
DisableBreakpointsScope(Debugger *debugger, bool disable)
Definition: debugger.h:933
GroupDebugger(IsolateGroup *isolate_group)
Definition: debugger.cc:1391
RwLock * single_stepping_set_lock()
Definition: debugger.h:624
CodePtr GetPatchedStubAddress(uword breakpoint_address)
Definition: debugger.cc:3940
bool HasCodeBreakpointInFunction(const Function &func)
Definition: debugger.cc:427
void RegisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
Definition: debugger.cc:3435
void UnregisterBreakpointLocation(BreakpointLocation *location)
Definition: debugger.cc:4049
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:636
bool HasBreakpoint(Thread *thread, const Function &function)
Definition: debugger.cc:3464
void MakeCodeBreakpointAt(const Function &func, BreakpointLocation *bpt)
Definition: debugger.cc:2269
SafepointRwLock * code_breakpoints_lock()
Definition: debugger.h:616
bool IsDebugging(Thread *thread, const Function &function)
Definition: debugger.cc:3488
bool HasBreakpointInFunction(const Function &func)
bool EnsureLocationIsInFunction(Zone *zone, const Function &function, BreakpointLocation *location)
Definition: debugger.cc:2939
BreakpointLocation * GetBreakpointLocationFor(Debugger *debugger, uword breakpoint_address, CodeBreakpoint **pcbpt)
Definition: debugger.cc:3916
void VisitObjectPointers(ObjectPointerVisitor *visitor)
Definition: debugger.cc:3028
bool HasCodeBreakpointInCode(const Code &code)
bool HasActiveBreakpoint(uword pc)
Definition: debugger.cc:3899
void NotifyCompilation(const Function &func)
Definition: debugger.cc:2977
void MakeCodeBreakpointAtUnsafe(const Function &func, BreakpointLocation *bpt)
Definition: debugger.cc:2211
void RegisterBreakpointLocation(BreakpointLocation *location)
Definition: debugger.cc:4043
bool HasBreakpointUnsafe(Thread *thread, const Function &function)
Definition: debugger.cc:3447
CodeBreakpoint * GetCodeBreakpoint(uword breakpoint_address)
Definition: debugger.cc:3905
void SyncBreakpointLocation(BreakpointLocation *loc)
Definition: debugger.cc:2706
void UnregisterSingleSteppingDebugger(Thread *thread, const Debugger *debugger)
Definition: debugger.cc:3441
SafepointRwLock * breakpoint_locations_lock()
Definition: debugger.h:620
void UnlinkCodeBreakpoints(BreakpointLocation *bpt_location)
Definition: debugger.cc:4063
GroupDebugger * debugger() const
Definition: isolate.h:315
IsolateGroup * group() const
Definition: isolate.h:1037
LambdaBoolCallable(T &lambda)
Definition: debugger.h:565
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
DECLARE_FLAG(bool, verbose_debug)
#define ASSERT(E)
double frame
Definition: examples.cpp:31
FlKeyEvent * event
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
Dart_NativeFunction function
Definition: fuchsia.cc:51
Win32Message message
Definition: dart_vm.cc:33
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:504
@ kInvalidExceptionPauseInfo
Definition: debugger.h:508
@ kPauseOnUnhandledExceptions
Definition: debugger.h:506
@ kNoPauseOnExceptions
Definition: debugger.h:505
@ kPauseOnAllExceptions
Definition: debugger.h:507
std::function< void()> closure
Definition: closure.h:14
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:581
#define T
Definition: precompiler.cc:65
Pair(const Key key, const Value &value)
Definition: debugger.h:520
Pair & operator=(const Pair &)=default