| 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 |