| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_DEBUGGER_H_ | 5 #ifndef VM_DEBUGGER_H_ |
| 6 #define VM_DEBUGGER_H_ | 6 #define VM_DEBUGGER_H_ |
| 7 | 7 |
| 8 #include "include/dart_tools_api.h" | 8 #include "include/dart_tools_api.h" |
| 9 | 9 |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 // A user-defined breakpoint, which either fires once, for a particular closure, | 24 // A user-defined breakpoint, which either fires once, for a particular closure, |
| 25 // or always. The API's notion of a breakpoint corresponds to this object. | 25 // or always. The API's notion of a breakpoint corresponds to this object. |
| 26 class Breakpoint { | 26 class Breakpoint { |
| 27 public: | 27 public: |
| 28 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) | 28 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) |
| 29 : id_(id), | 29 : id_(id), |
| 30 kind_(Breakpoint::kNone), | 30 kind_(Breakpoint::kNone), |
| 31 next_(NULL), | 31 next_(NULL), |
| 32 closure_(Instance::null()), | 32 closure_(Instance::null()), |
| 33 bpt_location_(bpt_location) {} | 33 bpt_location_(bpt_location), |
| 34 is_synthetic_async_(false) {} |
| 34 | 35 |
| 35 intptr_t id() const { return id_; } | 36 intptr_t id() const { return id_; } |
| 36 Breakpoint* next() const { return next_; } | 37 Breakpoint* next() const { return next_; } |
| 37 void set_next(Breakpoint* n) { next_ = n; } | 38 void set_next(Breakpoint* n) { next_ = n; } |
| 38 | 39 |
| 39 BreakpointLocation* bpt_location() const { return bpt_location_; } | 40 BreakpointLocation* bpt_location() const { return bpt_location_; } |
| 40 void set_bpt_location(BreakpointLocation* new_bpt_location); | 41 void set_bpt_location(BreakpointLocation* new_bpt_location); |
| 41 | 42 |
| 42 bool IsRepeated() const { return kind_ == kRepeated; } | 43 bool IsRepeated() const { return kind_ == kRepeated; } |
| 43 bool IsSingleShot() const { return kind_ == kSingleShot; } | 44 bool IsSingleShot() const { return kind_ == kSingleShot; } |
| 44 bool IsPerClosure() const { return kind_ == kPerClosure; } | 45 bool IsPerClosure() const { return kind_ == kPerClosure; } |
| 45 RawInstance* closure() const { return closure_; } | 46 RawInstance* closure() const { return closure_; } |
| 46 | 47 |
| 47 void SetIsRepeated() { | 48 void SetIsRepeated() { |
| 48 ASSERT(kind_ == kNone); | 49 ASSERT(kind_ == kNone); |
| 49 kind_ = kRepeated; | 50 kind_ = kRepeated; |
| 50 } | 51 } |
| 51 | 52 |
| 52 void SetIsSingleShot() { | 53 void SetIsSingleShot() { |
| 53 ASSERT(kind_ == kNone); | 54 ASSERT(kind_ == kNone); |
| 54 kind_ = kSingleShot; | 55 kind_ = kSingleShot; |
| 55 } | 56 } |
| 56 | 57 |
| 57 void SetIsPerClosure(const Instance& closure) { | 58 void SetIsPerClosure(const Instance& closure) { |
| 58 ASSERT(kind_ == kNone); | 59 ASSERT(kind_ == kNone); |
| 59 kind_ = kPerClosure; | 60 kind_ = kPerClosure; |
| 60 closure_ = closure.raw(); | 61 closure_ = closure.raw(); |
| 61 } | 62 } |
| 62 | 63 |
| 64 // Mark that this breakpoint is a result of a step OverAwait request. |
| 65 void set_is_synthetic_async(bool is_synthetic_async) { |
| 66 is_synthetic_async_ = is_synthetic_async; |
| 67 } |
| 68 bool is_synthetic_async() const { |
| 69 return is_synthetic_async_; |
| 70 } |
| 71 |
| 63 void PrintJSON(JSONStream* stream); | 72 void PrintJSON(JSONStream* stream); |
| 64 | 73 |
| 65 private: | 74 private: |
| 66 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 75 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 67 | 76 |
| 68 enum ConditionKind { | 77 enum ConditionKind { |
| 69 kNone, | 78 kNone, |
| 70 kRepeated, | 79 kRepeated, |
| 71 kSingleShot, | 80 kSingleShot, |
| 72 kPerClosure, | 81 kPerClosure, |
| 73 }; | 82 }; |
| 74 | 83 |
| 75 intptr_t id_; | 84 intptr_t id_; |
| 76 ConditionKind kind_; | 85 ConditionKind kind_; |
| 77 Breakpoint* next_; | 86 Breakpoint* next_; |
| 78 RawInstance* closure_; | 87 RawInstance* closure_; |
| 79 BreakpointLocation* bpt_location_; | 88 BreakpointLocation* bpt_location_; |
| 89 bool is_synthetic_async_; |
| 80 | 90 |
| 81 friend class BreakpointLocation; | 91 friend class BreakpointLocation; |
| 82 DISALLOW_COPY_AND_ASSIGN(Breakpoint); | 92 DISALLOW_COPY_AND_ASSIGN(Breakpoint); |
| 83 }; | 93 }; |
| 84 | 94 |
| 85 | 95 |
| 86 // BreakpointLocation represents a collection of breakpoint conditions at the | 96 // BreakpointLocation represents a collection of breakpoint conditions at the |
| 87 // same token position in Dart source. There may be more than one CodeBreakpoint | 97 // same token position in Dart source. There may be more than one CodeBreakpoint |
| 88 // object per BreakpointLocation. | 98 // object per BreakpointLocation. |
| 89 // An unresolved breakpoint is one where the underlying code has not | 99 // An unresolved breakpoint is one where the underlying code has not |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 | 131 |
| 122 intptr_t LineNumber(); | 132 intptr_t LineNumber(); |
| 123 intptr_t ColumnNumber(); | 133 intptr_t ColumnNumber(); |
| 124 | 134 |
| 125 void GetCodeLocation(Library* lib, | 135 void GetCodeLocation(Library* lib, |
| 126 Script* script, | 136 Script* script, |
| 127 TokenPosition* token_pos) const; | 137 TokenPosition* token_pos) const; |
| 128 | 138 |
| 129 Breakpoint* AddRepeated(Debugger* dbg); | 139 Breakpoint* AddRepeated(Debugger* dbg); |
| 130 Breakpoint* AddSingleShot(Debugger* dbg); | 140 Breakpoint* AddSingleShot(Debugger* dbg); |
| 131 Breakpoint* AddPerClosure(Debugger* dbg, const Instance& closure); | 141 Breakpoint* AddPerClosure(Debugger* dbg, |
| 142 const Instance& closure, |
| 143 bool for_over_await); |
| 132 | 144 |
| 133 bool AnyEnabled() const; | 145 bool AnyEnabled() const; |
| 134 bool IsResolved() const { return is_resolved_; } | 146 bool IsResolved() const { return is_resolved_; } |
| 135 bool IsLatent() const { return !token_pos_.IsReal(); } | 147 bool IsLatent() const { return !token_pos_.IsReal(); } |
| 136 | 148 |
| 137 private: | 149 private: |
| 138 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 150 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 139 | 151 |
| 140 void SetResolved(const Function& func, TokenPosition token_pos); | 152 void SetResolved(const Function& func, TokenPosition token_pos); |
| 141 | 153 |
| (...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 void NotifyCompilation(const Function& func); | 472 void NotifyCompilation(const Function& func); |
| 461 void NotifyDoneLoading(); | 473 void NotifyDoneLoading(); |
| 462 | 474 |
| 463 RawFunction* ResolveFunction(const Library& library, | 475 RawFunction* ResolveFunction(const Library& library, |
| 464 const String& class_name, | 476 const String& class_name, |
| 465 const String& function_name); | 477 const String& function_name); |
| 466 | 478 |
| 467 // Set breakpoint at closest location to function entry. | 479 // Set breakpoint at closest location to function entry. |
| 468 Breakpoint* SetBreakpointAtEntry(const Function& target_function, | 480 Breakpoint* SetBreakpointAtEntry(const Function& target_function, |
| 469 bool single_shot); | 481 bool single_shot); |
| 470 Breakpoint* SetBreakpointAtActivation(const Instance& closure); | 482 Breakpoint* SetBreakpointAtActivation(const Instance& closure, |
| 483 bool for_over_await); |
| 471 Breakpoint* BreakpointAtActivation(const Instance& closure); | 484 Breakpoint* BreakpointAtActivation(const Instance& closure); |
| 472 | 485 |
| 473 // TODO(turnidge): script_url may no longer be specific enough. | 486 // TODO(turnidge): script_url may no longer be specific enough. |
| 474 Breakpoint* SetBreakpointAtLine(const String& script_url, | 487 Breakpoint* SetBreakpointAtLine(const String& script_url, |
| 475 intptr_t line_number); | 488 intptr_t line_number); |
| 476 Breakpoint* SetBreakpointAtLineCol(const String& script_url, | 489 Breakpoint* SetBreakpointAtLineCol(const String& script_url, |
| 477 intptr_t line_number, | 490 intptr_t line_number, |
| 478 intptr_t column_number); | 491 intptr_t column_number); |
| 479 RawError* OneTimeBreakAtEntry(const Function& target_function); | 492 RawError* OneTimeBreakAtEntry(const Function& target_function); |
| 480 | 493 |
| 481 BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url, | 494 BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url, |
| 482 intptr_t line_number, | 495 intptr_t line_number, |
| 483 intptr_t column_number); | 496 intptr_t column_number); |
| 484 | 497 |
| 485 | 498 |
| 486 void RemoveBreakpoint(intptr_t bp_id); | 499 void RemoveBreakpoint(intptr_t bp_id); |
| 487 Breakpoint* GetBreakpointById(intptr_t id); | 500 Breakpoint* GetBreakpointById(intptr_t id); |
| 488 | 501 |
| 502 // Will return false if we are not at an await. |
| 503 bool SetupStepOverAsyncSuspension(); |
| 489 void SetStepOver(); | 504 void SetStepOver(); |
| 490 void SetSingleStep(); | 505 void SetSingleStep(); |
| 491 void SetStepOut(); | 506 void SetStepOut(); |
| 492 bool IsStepping() const { return resume_action_ != kContinue; } | 507 bool IsStepping() const { return resume_action_ != kContinue; } |
| 493 | 508 |
| 494 bool IsPaused() const { return pause_event_ != NULL; } | 509 bool IsPaused() const { return pause_event_ != NULL; } |
| 495 | 510 |
| 496 // Put the isolate into single stepping mode when Dart code next runs. | 511 // Put the isolate into single stepping mode when Dart code next runs. |
| 497 // | 512 // |
| 498 // This is used by the vm service to allow the user to step while | 513 // This is used by the vm service to allow the user to step while |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 enum ResumeAction { | 595 enum ResumeAction { |
| 581 kContinue, | 596 kContinue, |
| 582 kStepOver, | 597 kStepOver, |
| 583 kStepOut, | 598 kStepOut, |
| 584 kSingleStep | 599 kSingleStep |
| 585 }; | 600 }; |
| 586 | 601 |
| 587 static bool HasAnyEventHandler(); | 602 static bool HasAnyEventHandler(); |
| 588 static bool HasDebugEventHandler(); | 603 static bool HasDebugEventHandler(); |
| 589 void InvokeEventHandler(DebuggerEvent* event); | 604 void InvokeEventHandler(DebuggerEvent* event); |
| 590 | 605 bool IsAtAsyncJump(ActivationFrame* top_frame); |
| 591 void FindCompiledFunctions(const Script& script, | 606 void FindCompiledFunctions(const Script& script, |
| 592 TokenPosition start_pos, | 607 TokenPosition start_pos, |
| 593 TokenPosition end_pos, | 608 TokenPosition end_pos, |
| 594 GrowableObjectArray* function_list); | 609 GrowableObjectArray* function_list); |
| 595 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); | 610 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); |
| 596 RawFunction* FindInnermostClosure(const Function& function, | 611 RawFunction* FindInnermostClosure(const Function& function, |
| 597 TokenPosition token_pos); | 612 TokenPosition token_pos); |
| 598 TokenPosition ResolveBreakpointPos(const Function& func, | 613 TokenPosition ResolveBreakpointPos(const Function& func, |
| 599 TokenPosition requested_token_pos, | 614 TokenPosition requested_token_pos, |
| 600 TokenPosition last_token_pos, | 615 TokenPosition last_token_pos, |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 // When stepping through code, only pause the program if the top | 704 // When stepping through code, only pause the program if the top |
| 690 // frame corresponds to this fp value, or if the top frame is | 705 // frame corresponds to this fp value, or if the top frame is |
| 691 // lower on the stack. | 706 // lower on the stack. |
| 692 uword stepping_fp_; | 707 uword stepping_fp_; |
| 693 | 708 |
| 694 // If we step while at a breakpoint, we would hit the same pc twice. | 709 // If we step while at a breakpoint, we would hit the same pc twice. |
| 695 // We use this field to let us skip the next single-step after a | 710 // We use this field to let us skip the next single-step after a |
| 696 // breakpoint. | 711 // breakpoint. |
| 697 bool skip_next_step_; | 712 bool skip_next_step_; |
| 698 | 713 |
| 714 // We keep this breakpoint alive until after the debugger does the step over |
| 715 // async continuation machinery so that we can report that we've stopped |
| 716 // at the breakpoint. |
| 717 Breakpoint* synthetic_async_breakpoint_; |
| 718 |
| 699 Dart_ExceptionPauseInfo exc_pause_info_; | 719 Dart_ExceptionPauseInfo exc_pause_info_; |
| 700 | 720 |
| 701 static EventHandler* event_handler_; | 721 static EventHandler* event_handler_; |
| 702 | 722 |
| 703 friend class Isolate; | 723 friend class Isolate; |
| 704 friend class BreakpointLocation; | 724 friend class BreakpointLocation; |
| 705 DISALLOW_COPY_AND_ASSIGN(Debugger); | 725 DISALLOW_COPY_AND_ASSIGN(Debugger); |
| 706 }; | 726 }; |
| 707 | 727 |
| 708 | 728 |
| 709 } // namespace dart | 729 } // namespace dart |
| 710 | 730 |
| 711 #endif // VM_DEBUGGER_H_ | 731 #endif // VM_DEBUGGER_H_ |
| OLD | NEW |