| 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" |
| 11 #include "vm/port.h" | 11 #include "vm/port.h" |
| 12 #include "vm/service_event.h" |
| 12 | 13 |
| 13 namespace dart { | 14 namespace dart { |
| 14 | 15 |
| 15 class CodeBreakpoint; | 16 class CodeBreakpoint; |
| 16 class Isolate; | 17 class Isolate; |
| 17 class JSONArray; | 18 class JSONArray; |
| 18 class JSONStream; | 19 class JSONStream; |
| 19 class ObjectPointerVisitor; | 20 class ObjectPointerVisitor; |
| 20 class RemoteObjectCache; | 21 class RemoteObjectCache; |
| 21 class BreakpointLocation; | 22 class BreakpointLocation; |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 | 363 |
| 363 private: | 364 private: |
| 364 void AddActivation(ActivationFrame* frame); | 365 void AddActivation(ActivationFrame* frame); |
| 365 ZoneGrowableArray<ActivationFrame*> trace_; | 366 ZoneGrowableArray<ActivationFrame*> trace_; |
| 366 | 367 |
| 367 friend class Debugger; | 368 friend class Debugger; |
| 368 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace); | 369 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace); |
| 369 }; | 370 }; |
| 370 | 371 |
| 371 | 372 |
| 372 class DebuggerEvent { | |
| 373 public: | |
| 374 enum EventType { | |
| 375 kBreakpointReached = 1, | |
| 376 kBreakpointResolved = 2, | |
| 377 kExceptionThrown = 3, | |
| 378 kIsolateCreated = 4, | |
| 379 kIsolateShutdown = 5, | |
| 380 kIsolateInterrupted = 6, | |
| 381 }; | |
| 382 | |
| 383 explicit DebuggerEvent(Isolate* isolate, EventType event_type) | |
| 384 : isolate_(isolate), | |
| 385 type_(event_type), | |
| 386 top_frame_(NULL), | |
| 387 breakpoint_(NULL), | |
| 388 exception_(NULL), | |
| 389 async_continuation_(NULL), | |
| 390 at_async_jump_(false), | |
| 391 timestamp_(-1) {} | |
| 392 | |
| 393 Isolate* isolate() const { return isolate_; } | |
| 394 | |
| 395 EventType type() const { return type_; } | |
| 396 | |
| 397 bool IsPauseEvent() const { | |
| 398 return (type_ == kBreakpointReached || | |
| 399 type_ == kIsolateInterrupted || | |
| 400 type_ == kExceptionThrown); | |
| 401 } | |
| 402 | |
| 403 ActivationFrame* top_frame() const { | |
| 404 ASSERT(IsPauseEvent()); | |
| 405 return top_frame_; | |
| 406 } | |
| 407 void set_top_frame(ActivationFrame* frame) { | |
| 408 ASSERT(IsPauseEvent()); | |
| 409 top_frame_ = frame; | |
| 410 } | |
| 411 | |
| 412 Breakpoint* breakpoint() const { | |
| 413 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); | |
| 414 return breakpoint_; | |
| 415 } | |
| 416 void set_breakpoint(Breakpoint* bpt) { | |
| 417 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); | |
| 418 breakpoint_ = bpt; | |
| 419 } | |
| 420 | |
| 421 const Object* exception() const { | |
| 422 ASSERT(type_ == kExceptionThrown); | |
| 423 return exception_; | |
| 424 } | |
| 425 void set_exception(const Object* exception) { | |
| 426 ASSERT(type_ == kExceptionThrown); | |
| 427 exception_ = exception; | |
| 428 } | |
| 429 | |
| 430 const Object* async_continuation() const { | |
| 431 ASSERT(type_ == kBreakpointReached); | |
| 432 return async_continuation_; | |
| 433 } | |
| 434 void set_async_continuation(const Object* closure) { | |
| 435 ASSERT(type_ == kBreakpointReached); | |
| 436 async_continuation_ = closure; | |
| 437 } | |
| 438 | |
| 439 bool at_async_jump() const { | |
| 440 return at_async_jump_; | |
| 441 } | |
| 442 void set_at_async_jump(bool value) { | |
| 443 at_async_jump_ = value; | |
| 444 } | |
| 445 | |
| 446 Dart_Port isolate_id() const { | |
| 447 return isolate_->main_port(); | |
| 448 } | |
| 449 | |
| 450 void UpdateTimestamp(); | |
| 451 | |
| 452 int64_t timestamp() const { | |
| 453 return timestamp_; | |
| 454 } | |
| 455 | |
| 456 private: | |
| 457 Isolate* isolate_; | |
| 458 EventType type_; | |
| 459 ActivationFrame* top_frame_; | |
| 460 Breakpoint* breakpoint_; | |
| 461 const Object* exception_; | |
| 462 const Object* async_continuation_; | |
| 463 bool at_async_jump_; | |
| 464 int64_t timestamp_; | |
| 465 }; | |
| 466 | |
| 467 | |
| 468 class Debugger { | 373 class Debugger { |
| 469 public: | 374 public: |
| 470 typedef void EventHandler(DebuggerEvent* event); | 375 typedef void EventHandler(ServiceEvent* event); |
| 471 | 376 |
| 472 Debugger(); | 377 Debugger(); |
| 473 ~Debugger(); | 378 ~Debugger(); |
| 474 | 379 |
| 475 void Initialize(Isolate* isolate); | 380 void Initialize(Isolate* isolate); |
| 476 void NotifyIsolateCreated(); | 381 void NotifyIsolateCreated(); |
| 477 void Shutdown(); | 382 void Shutdown(); |
| 478 | 383 |
| 479 void NotifyCompilation(const Function& func); | 384 void NotifyCompilation(const Function& func); |
| 480 void NotifyDoneLoading(); | 385 void NotifyDoneLoading(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 // Put the isolate into single stepping mode when Dart code next runs. | 423 // Put the isolate into single stepping mode when Dart code next runs. |
| 519 // | 424 // |
| 520 // This is used by the vm service to allow the user to step while | 425 // This is used by the vm service to allow the user to step while |
| 521 // paused at isolate start. | 426 // paused at isolate start. |
| 522 void EnterSingleStepMode(); | 427 void EnterSingleStepMode(); |
| 523 | 428 |
| 524 // Indicates why the debugger is currently paused. If the debugger | 429 // Indicates why the debugger is currently paused. If the debugger |
| 525 // is not paused, this returns NULL. Note that the debugger can be | 430 // is not paused, this returns NULL. Note that the debugger can be |
| 526 // paused for breakpoints, isolate interruption, and (sometimes) | 431 // paused for breakpoints, isolate interruption, and (sometimes) |
| 527 // exceptions. | 432 // exceptions. |
| 528 const DebuggerEvent* PauseEvent() const { return pause_event_; } | 433 const ServiceEvent* PauseEvent() const { return pause_event_; } |
| 529 | 434 |
| 530 void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info); | 435 void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info); |
| 531 Dart_ExceptionPauseInfo GetExceptionPauseInfo() const; | 436 Dart_ExceptionPauseInfo GetExceptionPauseInfo() const; |
| 532 | 437 |
| 533 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 438 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 534 | 439 |
| 535 // Called from Runtime when a breakpoint in Dart code is reached. | 440 // Called from Runtime when a breakpoint in Dart code is reached. |
| 536 void BreakpointCallback(); | 441 void BreakpointCallback(); |
| 537 | 442 |
| 538 // Returns true if there is at least one breakpoint set in func or code. | 443 // Returns true if there is at least one breakpoint set in func or code. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 | 478 |
| 574 // Utility functions. | 479 // Utility functions. |
| 575 static const char* QualifiedFunctionName(const Function& func); | 480 static const char* QualifiedFunctionName(const Function& func); |
| 576 | 481 |
| 577 RawObject* GetInstanceField(const Class& cls, | 482 RawObject* GetInstanceField(const Class& cls, |
| 578 const String& field_name, | 483 const String& field_name, |
| 579 const Instance& object); | 484 const Instance& object); |
| 580 RawObject* GetStaticField(const Class& cls, | 485 RawObject* GetStaticField(const Class& cls, |
| 581 const String& field_name); | 486 const String& field_name); |
| 582 | 487 |
| 583 RawError* SignalBpReached(); | 488 // Pause execution for a breakpoint. Called from generated code. |
| 584 RawError* DebuggerStepCallback(); | 489 RawError* PauseBreakpoint(); |
| 585 RawError* SignalIsolateInterrupted(); | |
| 586 | 490 |
| 587 void BreakHere(const String& msg); | 491 // Pause execution due to stepping. Called from generated code. |
| 492 RawError* PauseStepping(); |
| 588 | 493 |
| 589 void SignalExceptionThrown(const Instance& exc); | 494 // Pause execution due to isolate interrupt. |
| 590 void SignalIsolateEvent(DebuggerEvent::EventType type); | 495 RawError* PauseInterrupted(); |
| 496 |
| 497 // Pause execution due to an uncaught exception. |
| 498 void PauseException(const Instance& exc); |
| 499 |
| 500 // Pause execution due to a call to the debugger() function from |
| 501 // Dart. |
| 502 void PauseDeveloper(const String& msg); |
| 591 | 503 |
| 592 RawCode* GetPatchedStubAddress(uword breakpoint_address); | 504 RawCode* GetPatchedStubAddress(uword breakpoint_address); |
| 593 | 505 |
| 594 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const; | 506 void PrintBreakpointsToJSONArray(JSONArray* jsarr) const; |
| 595 void PrintSettingsToJSONObject(JSONObject* jsobj) const; | 507 void PrintSettingsToJSONObject(JSONObject* jsobj) const; |
| 596 | 508 |
| 597 static bool IsDebuggable(const Function& func); | 509 static bool IsDebuggable(const Function& func); |
| 598 | 510 |
| 599 intptr_t limitBreakpointId() { return next_id_; } | 511 intptr_t limitBreakpointId() { return next_id_; } |
| 600 | 512 |
| 601 private: | 513 private: |
| 602 enum ResumeAction { | 514 enum ResumeAction { |
| 603 kContinue, | 515 kContinue, |
| 604 kStepOver, | 516 kStepOver, |
| 605 kStepOut, | 517 kStepOut, |
| 606 kSingleStep | 518 kSingleStep |
| 607 }; | 519 }; |
| 608 | 520 |
| 609 static bool HasAnyEventHandler(); | 521 bool NeedsIsolateEvents(); |
| 610 static bool HasDebugEventHandler(); | 522 bool NeedsDebugEvents(); |
| 611 void InvokeEventHandler(DebuggerEvent* event); | 523 void InvokeEventHandler(ServiceEvent* event); |
| 524 |
| 525 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt); |
| 526 |
| 612 bool IsAtAsyncJump(ActivationFrame* top_frame); | 527 bool IsAtAsyncJump(ActivationFrame* top_frame); |
| 613 void FindCompiledFunctions(const Script& script, | 528 void FindCompiledFunctions(const Script& script, |
| 614 TokenPosition start_pos, | 529 TokenPosition start_pos, |
| 615 TokenPosition end_pos, | 530 TokenPosition end_pos, |
| 616 GrowableObjectArray* function_list); | 531 GrowableObjectArray* function_list); |
| 617 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); | 532 RawFunction* FindBestFit(const Script& script, TokenPosition token_pos); |
| 618 RawFunction* FindInnermostClosure(const Function& function, | 533 RawFunction* FindInnermostClosure(const Function& function, |
| 619 TokenPosition token_pos); | 534 TokenPosition token_pos); |
| 620 TokenPosition ResolveBreakpointPos(const Function& func, | 535 TokenPosition ResolveBreakpointPos(const Function& func, |
| 621 TokenPosition requested_token_pos, | 536 TokenPosition requested_token_pos, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 648 static ActivationFrame* CollectDartFrame(Isolate* isolate, | 563 static ActivationFrame* CollectDartFrame(Isolate* isolate, |
| 649 uword pc, | 564 uword pc, |
| 650 StackFrame* frame, | 565 StackFrame* frame, |
| 651 const Code& code, | 566 const Code& code, |
| 652 const Array& deopt_frame, | 567 const Array& deopt_frame, |
| 653 intptr_t deopt_frame_offset); | 568 intptr_t deopt_frame_offset); |
| 654 static RawArray* DeoptimizeToArray(Thread* thread, | 569 static RawArray* DeoptimizeToArray(Thread* thread, |
| 655 StackFrame* frame, | 570 StackFrame* frame, |
| 656 const Code& code); | 571 const Code& code); |
| 657 static DebuggerStackTrace* CollectStackTrace(); | 572 static DebuggerStackTrace* CollectStackTrace(); |
| 658 void SignalBpResolved(Breakpoint *bpt); | |
| 659 void SignalPausedEvent(ActivationFrame* top_frame, | 573 void SignalPausedEvent(ActivationFrame* top_frame, |
| 660 Breakpoint* bpt); | 574 Breakpoint* bpt); |
| 661 | 575 |
| 662 intptr_t nextId() { return next_id_++; } | 576 intptr_t nextId() { return next_id_++; } |
| 663 | 577 |
| 664 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, | 578 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
| 665 const Instance& exc); | 579 const Instance& exc); |
| 666 | 580 |
| 667 void CollectLibraryFields(const GrowableObjectArray& field_list, | 581 void CollectLibraryFields(const GrowableObjectArray& field_list, |
| 668 const Library& lib, | 582 const Library& lib, |
| 669 const String& prefix, | 583 const String& prefix, |
| 670 bool include_private_fields); | 584 bool include_private_fields); |
| 671 | 585 |
| 672 // Handles any events which pause vm execution. Breakpoints, | 586 // Handles any events which pause vm execution. Breakpoints, |
| 673 // interrupts, etc. | 587 // interrupts, etc. |
| 674 void Pause(DebuggerEvent* event); | 588 void Pause(ServiceEvent* event); |
| 675 | 589 |
| 676 void HandleSteppingRequest(DebuggerStackTrace* stack_trace, | 590 void HandleSteppingRequest(DebuggerStackTrace* stack_trace, |
| 677 bool skip_next_step = false); | 591 bool skip_next_step = false); |
| 678 | 592 |
| 679 Isolate* isolate_; | 593 Isolate* isolate_; |
| 680 Dart_Port isolate_id_; // A unique ID for the isolate in the debugger. | 594 Dart_Port isolate_id_; // A unique ID for the isolate in the debugger. |
| 681 bool initialized_; | 595 bool initialized_; |
| 682 bool creation_message_sent_; // The creation message has been sent. | |
| 683 | 596 |
| 684 // ID number generator. | 597 // ID number generator. |
| 685 intptr_t next_id_; | 598 intptr_t next_id_; |
| 686 | 599 |
| 687 BreakpointLocation* latent_locations_; | 600 BreakpointLocation* latent_locations_; |
| 688 BreakpointLocation* breakpoint_locations_; | 601 BreakpointLocation* breakpoint_locations_; |
| 689 CodeBreakpoint* code_breakpoints_; | 602 CodeBreakpoint* code_breakpoints_; |
| 690 | 603 |
| 691 // Tells debugger what to do when resuming execution after a breakpoint. | 604 // Tells debugger what to do when resuming execution after a breakpoint. |
| 692 ResumeAction resume_action_; | 605 ResumeAction resume_action_; |
| 693 | 606 |
| 694 // Do not call back to breakpoint handler if this flag is set. | 607 // Do not call back to breakpoint handler if this flag is set. |
| 695 // Effectively this means ignoring breakpoints. Set when Dart code may | 608 // Effectively this means ignoring breakpoints. Set when Dart code may |
| 696 // be run as a side effect of getting values of fields. | 609 // be run as a side effect of getting values of fields. |
| 697 bool ignore_breakpoints_; | 610 bool ignore_breakpoints_; |
| 698 | 611 |
| 699 // Indicates why the debugger is currently paused. If the debugger | 612 // Indicates why the debugger is currently paused. If the debugger |
| 700 // is not paused, this is NULL. Note that the debugger can be | 613 // is not paused, this is NULL. Note that the debugger can be |
| 701 // paused for breakpoints, isolate interruption, and (sometimes) | 614 // paused for breakpoints, isolate interruption, and (sometimes) |
| 702 // exceptions. | 615 // exceptions. |
| 703 DebuggerEvent* pause_event_; | 616 ServiceEvent* pause_event_; |
| 704 | 617 |
| 705 // An id -> object map. Valid only while IsPaused(). | 618 // An id -> object map. Valid only while IsPaused(). |
| 706 RemoteObjectCache* obj_cache_; | 619 RemoteObjectCache* obj_cache_; |
| 707 | 620 |
| 708 // Current stack trace. Valid only while IsPaused(). | 621 // Current stack trace. Valid only while IsPaused(). |
| 709 DebuggerStackTrace* stack_trace_; | 622 DebuggerStackTrace* stack_trace_; |
| 710 | 623 |
| 711 // When stepping through code, only pause the program if the top | 624 // When stepping through code, only pause the program if the top |
| 712 // frame corresponds to this fp value, or if the top frame is | 625 // frame corresponds to this fp value, or if the top frame is |
| 713 // lower on the stack. | 626 // lower on the stack. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 729 | 642 |
| 730 friend class Isolate; | 643 friend class Isolate; |
| 731 friend class BreakpointLocation; | 644 friend class BreakpointLocation; |
| 732 DISALLOW_COPY_AND_ASSIGN(Debugger); | 645 DISALLOW_COPY_AND_ASSIGN(Debugger); |
| 733 }; | 646 }; |
| 734 | 647 |
| 735 | 648 |
| 736 } // namespace dart | 649 } // namespace dart |
| 737 | 650 |
| 738 #endif // VM_DEBUGGER_H_ | 651 #endif // VM_DEBUGGER_H_ |
| OLD | NEW |