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 RUNTIME_VM_DEBUGGER_H_ | 5 #ifndef RUNTIME_VM_DEBUGGER_H_ |
6 #define RUNTIME_VM_DEBUGGER_H_ | 6 #define RUNTIME_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" |
11 #include "vm/port.h" | 11 #include "vm/port.h" |
12 #include "vm/service_event.h" | 12 #include "vm/service_event.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 class CodeBreakpoint; | 16 class CodeBreakpoint; |
17 class Isolate; | 17 class Isolate; |
18 class JSONArray; | 18 class JSONArray; |
19 class JSONStream; | 19 class JSONStream; |
20 class ObjectPointerVisitor; | 20 class ObjectPointerVisitor; |
21 class RemoteObjectCache; | 21 class RemoteObjectCache; |
22 class BreakpointLocation; | 22 class BreakpointLocation; |
23 class StackFrame; | 23 class StackFrame; |
24 | 24 |
25 // A user-defined breakpoint, which either fires once, for a particular closure, | 25 // A user-defined breakpoint, which either fires once, for a particular closure, |
26 // or always. The API's notion of a breakpoint corresponds to this object. | 26 // or always. The API's notion of a breakpoint corresponds to this object. |
27 class Breakpoint { | 27 class Breakpoint { |
28 public: | 28 public: |
29 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) | 29 Breakpoint(intptr_t id, BreakpointLocation* bpt_location) |
30 : id_(id), | 30 : id_(id), |
31 kind_(Breakpoint::kNone), | 31 kind_(Breakpoint::kNone), |
32 next_(NULL), | 32 next_(NULL), |
33 closure_(Instance::null()), | 33 closure_(Instance::null()), |
34 bpt_location_(bpt_location), | 34 bpt_location_(bpt_location), |
35 is_synthetic_async_(false) {} | 35 is_synthetic_async_(false) {} |
36 | 36 |
37 intptr_t id() const { return id_; } | 37 intptr_t id() const { return id_; } |
38 Breakpoint* next() const { return next_; } | 38 Breakpoint* next() const { return next_; } |
39 void set_next(Breakpoint* n) { next_ = n; } | 39 void set_next(Breakpoint* n) { next_ = n; } |
40 | 40 |
41 BreakpointLocation* bpt_location() const { return bpt_location_; } | 41 BreakpointLocation* bpt_location() const { return bpt_location_; } |
42 void set_bpt_location(BreakpointLocation* new_bpt_location); | 42 void set_bpt_location(BreakpointLocation* new_bpt_location); |
43 | 43 |
44 bool IsRepeated() const { return kind_ == kRepeated; } | 44 bool IsRepeated() const { return kind_ == kRepeated; } |
45 bool IsSingleShot() const { return kind_ == kSingleShot; } | 45 bool IsSingleShot() const { return kind_ == kSingleShot; } |
(...skipping 13 matching lines...) Expand all Loading... |
59 void SetIsPerClosure(const Instance& closure) { | 59 void SetIsPerClosure(const Instance& closure) { |
60 ASSERT(kind_ == kNone); | 60 ASSERT(kind_ == kNone); |
61 kind_ = kPerClosure; | 61 kind_ = kPerClosure; |
62 closure_ = closure.raw(); | 62 closure_ = closure.raw(); |
63 } | 63 } |
64 | 64 |
65 // Mark that this breakpoint is a result of a step OverAwait request. | 65 // Mark that this breakpoint is a result of a step OverAwait request. |
66 void set_is_synthetic_async(bool is_synthetic_async) { | 66 void set_is_synthetic_async(bool is_synthetic_async) { |
67 is_synthetic_async_ = is_synthetic_async; | 67 is_synthetic_async_ = is_synthetic_async; |
68 } | 68 } |
69 bool is_synthetic_async() const { | 69 bool is_synthetic_async() const { return is_synthetic_async_; } |
70 return is_synthetic_async_; | |
71 } | |
72 | 70 |
73 void PrintJSON(JSONStream* stream); | 71 void PrintJSON(JSONStream* stream); |
74 | 72 |
75 private: | 73 private: |
76 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 74 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
77 | 75 |
78 enum ConditionKind { | 76 enum ConditionKind { |
79 kNone, | 77 kNone, |
80 kRepeated, | 78 kRepeated, |
81 kSingleShot, | 79 kSingleShot, |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 | 238 |
241 friend class Debugger; | 239 friend class Debugger; |
242 DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint); | 240 DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint); |
243 }; | 241 }; |
244 | 242 |
245 | 243 |
246 // ActivationFrame represents one dart function activation frame | 244 // ActivationFrame represents one dart function activation frame |
247 // on the call stack. | 245 // on the call stack. |
248 class ActivationFrame : public ZoneAllocated { | 246 class ActivationFrame : public ZoneAllocated { |
249 public: | 247 public: |
250 ActivationFrame(uword pc, uword fp, uword sp, const Code& code, | 248 ActivationFrame(uword pc, |
251 const Array& deopt_frame, intptr_t deopt_frame_offset); | 249 uword fp, |
| 250 uword sp, |
| 251 const Code& code, |
| 252 const Array& deopt_frame, |
| 253 intptr_t deopt_frame_offset); |
252 | 254 |
253 uword pc() const { return pc_; } | 255 uword pc() const { return pc_; } |
254 uword fp() const { return fp_; } | 256 uword fp() const { return fp_; } |
255 uword sp() const { return sp_; } | 257 uword sp() const { return sp_; } |
256 const Function& function() const { | 258 const Function& function() const { |
257 ASSERT(!function_.IsNull()); | 259 ASSERT(!function_.IsNull()); |
258 return function_; | 260 return function_; |
259 } | 261 } |
260 const Code& code() const { | 262 const Code& code() const { |
261 ASSERT(!code_.IsNull()); | 263 ASSERT(!code_.IsNull()); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 | 347 |
346 friend class Debugger; | 348 friend class Debugger; |
347 friend class DebuggerStackTrace; | 349 friend class DebuggerStackTrace; |
348 DISALLOW_COPY_AND_ASSIGN(ActivationFrame); | 350 DISALLOW_COPY_AND_ASSIGN(ActivationFrame); |
349 }; | 351 }; |
350 | 352 |
351 | 353 |
352 // Array of function activations on the call stack. | 354 // Array of function activations on the call stack. |
353 class DebuggerStackTrace : public ZoneAllocated { | 355 class DebuggerStackTrace : public ZoneAllocated { |
354 public: | 356 public: |
355 explicit DebuggerStackTrace(int capacity) | 357 explicit DebuggerStackTrace(int capacity) : trace_(capacity) {} |
356 : trace_(capacity) { } | |
357 | 358 |
358 intptr_t Length() const { return trace_.length(); } | 359 intptr_t Length() const { return trace_.length(); } |
359 | 360 |
360 ActivationFrame* FrameAt(int i) const { | 361 ActivationFrame* FrameAt(int i) const { return trace_[i]; } |
361 return trace_[i]; | |
362 } | |
363 | 362 |
364 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const; | 363 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const; |
365 | 364 |
366 private: | 365 private: |
367 void AddActivation(ActivationFrame* frame); | 366 void AddActivation(ActivationFrame* frame); |
368 ZoneGrowableArray<ActivationFrame*> trace_; | 367 ZoneGrowableArray<ActivationFrame*> trace_; |
369 | 368 |
370 friend class Debugger; | 369 friend class Debugger; |
371 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace); | 370 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace); |
372 }; | 371 }; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 Dart_Port GetIsolateId() { return isolate_id_; } | 476 Dart_Port GetIsolateId() { return isolate_id_; } |
478 | 477 |
479 static void SetEventHandler(EventHandler* handler); | 478 static void SetEventHandler(EventHandler* handler); |
480 | 479 |
481 // Utility functions. | 480 // Utility functions. |
482 static const char* QualifiedFunctionName(const Function& func); | 481 static const char* QualifiedFunctionName(const Function& func); |
483 | 482 |
484 RawObject* GetInstanceField(const Class& cls, | 483 RawObject* GetInstanceField(const Class& cls, |
485 const String& field_name, | 484 const String& field_name, |
486 const Instance& object); | 485 const Instance& object); |
487 RawObject* GetStaticField(const Class& cls, | 486 RawObject* GetStaticField(const Class& cls, const String& field_name); |
488 const String& field_name); | |
489 | 487 |
490 // Pause execution for a breakpoint. Called from generated code. | 488 // Pause execution for a breakpoint. Called from generated code. |
491 RawError* PauseBreakpoint(); | 489 RawError* PauseBreakpoint(); |
492 | 490 |
493 // Pause execution due to stepping. Called from generated code. | 491 // Pause execution due to stepping. Called from generated code. |
494 RawError* PauseStepping(); | 492 RawError* PauseStepping(); |
495 | 493 |
496 // Pause execution due to isolate interrupt. | 494 // Pause execution due to isolate interrupt. |
497 RawError* PauseInterrupted(); | 495 RawError* PauseInterrupted(); |
498 | 496 |
(...skipping 10 matching lines...) Expand all Loading... |
509 RawCode* GetPatchedStubAddress(uword breakpoint_address); | 507 RawCode* GetPatchedStubAddress(uword breakpoint_address); |
510 | 508 |
511 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const; | 509 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const; |
512 void PrintSettingsToJSONObject(JSONObject* jsobj) const; | 510 void PrintSettingsToJSONObject(JSONObject* jsobj) const; |
513 | 511 |
514 static bool IsDebuggable(const Function& func); | 512 static bool IsDebuggable(const Function& func); |
515 | 513 |
516 intptr_t limitBreakpointId() { return next_id_; } | 514 intptr_t limitBreakpointId() { return next_id_; } |
517 | 515 |
518 private: | 516 private: |
519 enum ResumeAction { | 517 enum ResumeAction { kContinue, kStepOver, kStepOut, kSingleStep }; |
520 kContinue, | |
521 kStepOver, | |
522 kStepOut, | |
523 kSingleStep | |
524 }; | |
525 | 518 |
526 RawError* PauseRequest(ServiceEvent::EventKind kind); | 519 RawError* PauseRequest(ServiceEvent::EventKind kind); |
527 | 520 |
528 bool NeedsIsolateEvents(); | 521 bool NeedsIsolateEvents(); |
529 bool NeedsDebugEvents(); | 522 bool NeedsDebugEvents(); |
530 void InvokeEventHandler(ServiceEvent* event); | 523 void InvokeEventHandler(ServiceEvent* event); |
531 | 524 |
532 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt); | 525 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt); |
533 | 526 |
534 bool IsAtAsyncJump(ActivationFrame* top_frame); | 527 bool IsAtAsyncJump(ActivationFrame* top_frame); |
535 void FindCompiledFunctions(const Script& script, | 528 void FindCompiledFunctions(const Script& script, |
536 TokenPosition start_pos, | 529 TokenPosition start_pos, |
537 TokenPosition end_pos, | 530 TokenPosition end_pos, |
538 GrowableObjectArray* function_list); | 531 GrowableObjectArray* function_list); |
539 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); | 532 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); |
540 RawFunction* FindInnermostClosure(const Function& function, | 533 RawFunction* FindInnermostClosure(const Function& function, |
541 TokenPosition token_pos); | 534 TokenPosition token_pos); |
542 TokenPosition ResolveBreakpointPos(const Function& func, | 535 TokenPosition ResolveBreakpointPos(const Function& func, |
543 TokenPosition requested_token_pos, | 536 TokenPosition requested_token_pos, |
544 TokenPosition last_token_pos, | 537 TokenPosition last_token_pos, |
545 intptr_t requested_column); | 538 intptr_t requested_column); |
546 void DeoptimizeWorld(); | 539 void DeoptimizeWorld(); |
547 BreakpointLocation* SetBreakpoint(const Script& script, | 540 BreakpointLocation* SetBreakpoint(const Script& script, |
548 TokenPosition token_pos, | 541 TokenPosition token_pos, |
549 TokenPosition last_token_pos, | 542 TokenPosition last_token_pos, |
550 intptr_t requested_line, | 543 intptr_t requested_line, |
551 intptr_t requested_column); | 544 intptr_t requested_column); |
552 void RemoveInternalBreakpoints(); | 545 void RemoveInternalBreakpoints(); |
553 void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location); | 546 void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location); |
554 BreakpointLocation* GetLatentBreakpoint(const String& url, | 547 BreakpointLocation* GetLatentBreakpoint(const String& url, |
555 intptr_t line, | 548 intptr_t line, |
556 intptr_t column); | 549 intptr_t column); |
557 void RegisterBreakpointLocation(BreakpointLocation* bpt); | 550 void RegisterBreakpointLocation(BreakpointLocation* bpt); |
558 void RegisterCodeBreakpoint(CodeBreakpoint* bpt); | 551 void RegisterCodeBreakpoint(CodeBreakpoint* bpt); |
559 BreakpointLocation* GetBreakpointLocation(const Script& script, | 552 BreakpointLocation* GetBreakpointLocation(const Script& script, |
560 TokenPosition token_pos, | 553 TokenPosition token_pos, |
561 intptr_t requested_column); | 554 intptr_t requested_column); |
562 void MakeCodeBreakpointAt(const Function& func, | 555 void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt); |
563 BreakpointLocation* bpt); | |
564 // Returns NULL if no breakpoint exists for the given address. | 556 // Returns NULL if no breakpoint exists for the given address. |
565 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address); | 557 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address); |
566 | 558 |
567 void SyncBreakpointLocation(BreakpointLocation* loc); | 559 void SyncBreakpointLocation(BreakpointLocation* loc); |
568 | 560 |
569 ActivationFrame* TopDartFrame() const; | 561 ActivationFrame* TopDartFrame() const; |
570 static ActivationFrame* CollectDartFrame(Isolate* isolate, | 562 static ActivationFrame* CollectDartFrame(Isolate* isolate, |
571 uword pc, | 563 uword pc, |
572 StackFrame* frame, | 564 StackFrame* frame, |
573 const Code& code, | 565 const Code& code, |
574 const Array& deopt_frame, | 566 const Array& deopt_frame, |
575 intptr_t deopt_frame_offset); | 567 intptr_t deopt_frame_offset); |
576 static RawArray* DeoptimizeToArray(Thread* thread, | 568 static RawArray* DeoptimizeToArray(Thread* thread, |
577 StackFrame* frame, | 569 StackFrame* frame, |
578 const Code& code); | 570 const Code& code); |
579 static DebuggerStackTrace* CollectStackTrace(); | 571 static DebuggerStackTrace* CollectStackTrace(); |
580 void SignalPausedEvent(ActivationFrame* top_frame, | 572 void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt); |
581 Breakpoint* bpt); | |
582 | 573 |
583 intptr_t nextId() { return next_id_++; } | 574 intptr_t nextId() { return next_id_++; } |
584 | 575 |
585 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, | 576 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
586 const Instance& exc); | 577 const Instance& exc); |
587 | 578 |
588 void CollectLibraryFields(const GrowableObjectArray& field_list, | 579 void CollectLibraryFields(const GrowableObjectArray& field_list, |
589 const Library& lib, | 580 const Library& lib, |
590 const String& prefix, | 581 const String& prefix, |
591 bool include_private_fields); | 582 bool include_private_fields); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 | 640 |
650 friend class Isolate; | 641 friend class Isolate; |
651 friend class BreakpointLocation; | 642 friend class BreakpointLocation; |
652 DISALLOW_COPY_AND_ASSIGN(Debugger); | 643 DISALLOW_COPY_AND_ASSIGN(Debugger); |
653 }; | 644 }; |
654 | 645 |
655 | 646 |
656 } // namespace dart | 647 } // namespace dart |
657 | 648 |
658 #endif // RUNTIME_VM_DEBUGGER_H_ | 649 #endif // RUNTIME_VM_DEBUGGER_H_ |
OLD | NEW |