Chromium Code Reviews| 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_debugger_api.h" | 8 #include "include/dart_debugger_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 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 class CodeBreakpoint; | 15 class CodeBreakpoint; |
| 16 class Isolate; | 16 class Isolate; |
| 17 class JSONArray; | 17 class JSONArray; |
| 18 class JSONStream; | 18 class JSONStream; |
| 19 class ObjectPointerVisitor; | 19 class ObjectPointerVisitor; |
| 20 class RemoteObjectCache; | 20 class RemoteObjectCache; |
| 21 class SourceBreakpoint; | 21 class SourceBreakpoint; |
| 22 class StackFrame; | 22 class StackFrame; |
| 23 | 23 |
| 24 // SourceBreakpoint represents a user-specified breakpoint location in | 24 // A user-defined breakpoint, which either fires once, for a particular closure, |
| 25 // Dart source. There may be more than one CodeBreakpoint object per | 25 // or always. The API's notion of a breakpoint corresponds to this object. |
| 26 // SourceBreakpoint. | 26 class BreakpointCondition { |
|
hausner
2015/05/21 18:23:55
I am struggling with the name. Maybe we just call
rmacnak
2015/05/21 21:59:35
Done.
| |
| 27 public: | |
| 28 BreakpointCondition(intptr_t id, SourceBreakpoint* src_bpt) | |
| 29 : id_(id), | |
| 30 kind_(BreakpointCondition::kNone), | |
| 31 next_(NULL), | |
| 32 closure_(Instance::null()), | |
| 33 src_bpt_(src_bpt) {} | |
| 34 | |
| 35 intptr_t id() const { return id_; } | |
| 36 BreakpointCondition* next() const { return next_; } | |
| 37 void set_next(BreakpointCondition* n) { next_ = n; } | |
| 38 | |
| 39 SourceBreakpoint* src_bpt() const { return src_bpt_; } | |
| 40 void set_src_bpt(SourceBreakpoint* new_src_bpt); | |
| 41 | |
| 42 bool IsRepeated() const { return kind_ == kRepeated; } | |
| 43 bool IsSingleShot() const { return kind_ == kSingleShot; } | |
| 44 bool IsPerClosure() const { return kind_ == kPerClosure; } | |
| 45 RawInstance* closure() const { return closure_; } | |
| 46 | |
| 47 void SetIsRepeated() { | |
| 48 ASSERT(kind_ == kNone); | |
| 49 kind_ = kRepeated; | |
| 50 } | |
| 51 | |
| 52 void SetIsSingleShot() { | |
| 53 ASSERT(kind_ == kNone); | |
| 54 kind_ = kSingleShot; | |
| 55 } | |
| 56 | |
| 57 void SetIsPerClosure(const Instance& closure) { | |
| 58 ASSERT(kind_ == kNone); | |
| 59 kind_ = kPerClosure; | |
| 60 closure_ = closure.raw(); | |
| 61 } | |
| 62 | |
| 63 void PrintJSON(JSONStream* stream); | |
| 64 | |
| 65 private: | |
| 66 void VisitObjectPointers(ObjectPointerVisitor* visitor); | |
| 67 | |
| 68 enum ConditionKind { | |
| 69 kNone, | |
| 70 kRepeated, | |
|
hausner
2015/05/21 18:23:55
What if you want to set a one-shopt breakpoint in
| |
| 71 kSingleShot, | |
| 72 kPerClosure, | |
| 73 }; | |
| 74 | |
| 75 intptr_t id_; | |
| 76 ConditionKind kind_; | |
| 77 BreakpointCondition* next_; | |
| 78 RawInstance* closure_; | |
| 79 SourceBreakpoint* src_bpt_; | |
| 80 | |
| 81 friend class SourceBreakpoint; | |
| 82 DISALLOW_COPY_AND_ASSIGN(BreakpointCondition); | |
| 83 }; | |
| 84 | |
| 85 | |
| 86 // SourceBreakpoint represents a collection of breakpoint conditions at the same | |
| 87 // token position in Dart source. There may be more than one CodeBreakpoint | |
| 88 // object per SourceBreakpoint. | |
| 27 // An unresolved breakpoint is one where the underlying code has not | 89 // An unresolved breakpoint is one where the underlying code has not |
| 28 // been compiled yet. Since the code has not been compiled, we don't know | 90 // been compiled yet. Since the code has not been compiled, we don't know |
| 29 // the definitive source location yet. The requested source location may | 91 // the definitive source location yet. The requested source location may |
| 30 // change when the underlying code gets compiled. | 92 // change when the underlying code gets compiled. |
| 31 // A latent breakpoint represents a breakpoint location in Dart source | 93 // A latent breakpoint represents a breakpoint location in Dart source |
| 32 // that is not loaded in the VM when the breakpoint is requested. | 94 // that is not loaded in the VM when the breakpoint is requested. |
| 33 // When a script with matching url is loaded, a latent breakpoint | 95 // When a script with matching url is loaded, a latent breakpoint |
| 34 // becomes an unresolved breakpoint. | 96 // becomes an unresolved breakpoint. |
| 35 class SourceBreakpoint { | 97 class SourceBreakpoint { |
| 36 public: | 98 public: |
| 37 // Create a new unresolved breakpoint. | 99 // Create a new unresolved breakpoint. |
| 38 SourceBreakpoint(intptr_t id, | 100 SourceBreakpoint(const Script& script, |
| 39 const Script& script, | |
| 40 intptr_t token_pos, | 101 intptr_t token_pos, |
| 41 intptr_t end_token_pos); | 102 intptr_t end_token_pos); |
| 42 // Create a new latent breakpoint. | 103 // Create a new latent breakpoint. |
| 43 SourceBreakpoint(intptr_t id, | 104 SourceBreakpoint(const String& url, |
| 44 const String& url, | |
| 45 intptr_t line_number); | 105 intptr_t line_number); |
| 46 | 106 |
| 107 ~SourceBreakpoint() { | |
| 108 BreakpointCondition* cond = conditions(); | |
|
hausner
2015/05/21 18:23:55
Does the body for the destructor need to be inline
rmacnak
2015/05/21 21:59:35
No, moved to cc.
| |
| 109 while (cond != NULL) { | |
| 110 BreakpointCondition* temp = cond; | |
| 111 cond = cond->next(); | |
| 112 delete temp; | |
| 113 } | |
| 114 } | |
| 115 | |
| 47 RawFunction* function() const { return function_; } | 116 RawFunction* function() const { return function_; } |
| 48 intptr_t token_pos() const { return token_pos_; } | 117 intptr_t token_pos() const { return token_pos_; } |
| 49 intptr_t end_token_pos() const { return end_token_pos_; } | 118 intptr_t end_token_pos() const { return end_token_pos_; } |
| 50 intptr_t id() const { return id_; } | |
| 51 | 119 |
| 52 RawScript* script() const { return script_; } | 120 RawScript* script() const { return script_; } |
| 53 RawString* url() const { return url_; } | 121 RawString* url() const { return url_; } |
| 54 intptr_t LineNumber(); | 122 intptr_t LineNumber(); |
| 55 | 123 |
| 56 void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos); | 124 void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos); |
| 57 | 125 |
| 126 BreakpointCondition* AddRepeated(Debugger* dbg); | |
| 127 BreakpointCondition* AddSingleShot(Debugger* dbg); | |
| 128 BreakpointCondition* AddPerClosure(Debugger* dbg, const Instance& closure); | |
| 129 | |
| 58 void Enable(); | 130 void Enable(); |
|
hausner
2015/05/21 18:23:55
The enabled/disabled property should be part of th
rmacnak
2015/05/21 21:59:35
Actually, no one calls Disable(), so deleted this.
| |
| 59 void Disable(); | 131 void Disable(); |
| 60 bool IsEnabled() const { return is_enabled_; } | 132 bool IsEnabled() const { return is_enabled_; } |
| 61 bool IsResolved() const { return is_resolved_; } | 133 bool IsResolved() const { return is_resolved_; } |
| 62 bool IsLatent() const { return token_pos_ < 0; } | 134 bool IsLatent() const { return token_pos_ < 0; } |
| 63 | 135 |
| 64 bool IsOneShot() const { return is_one_shot_; } | |
| 65 void SetIsOneShot() { is_one_shot_ = true; } | |
| 66 | |
| 67 void PrintJSON(JSONStream* stream); | |
| 68 | |
| 69 private: | 136 private: |
| 70 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 137 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 71 | 138 |
| 72 void SetResolved(const Function& func, intptr_t token_pos); | 139 void SetResolved(const Function& func, intptr_t token_pos); |
| 140 | |
| 141 SourceBreakpoint* next() const { return this->next_; } | |
| 73 void set_next(SourceBreakpoint* value) { next_ = value; } | 142 void set_next(SourceBreakpoint* value) { next_ = value; } |
| 74 SourceBreakpoint* next() const { return this->next_; } | |
| 75 | 143 |
| 76 const intptr_t id_; | 144 BreakpointCondition* conditions() const { return this->conditions_; } |
| 145 void set_conditions(BreakpointCondition* c) { this->conditions_ = c; } | |
| 146 | |
| 77 RawScript* script_; | 147 RawScript* script_; |
| 78 RawString* url_; | 148 RawString* url_; |
| 79 intptr_t token_pos_; | 149 intptr_t token_pos_; |
| 80 intptr_t end_token_pos_; | 150 intptr_t end_token_pos_; |
| 81 bool is_resolved_; | 151 bool is_resolved_; |
| 82 bool is_enabled_; | 152 bool is_enabled_; |
| 83 bool is_one_shot_; | |
| 84 SourceBreakpoint* next_; | 153 SourceBreakpoint* next_; |
| 154 BreakpointCondition* conditions_; | |
| 85 | 155 |
| 86 // Valid for resolved breakpoints: | 156 // Valid for resolved breakpoints: |
| 87 RawFunction* function_; | 157 RawFunction* function_; |
| 88 intptr_t line_number_; | 158 intptr_t line_number_; |
| 89 | 159 |
| 90 friend class Debugger; | 160 friend class Debugger; |
| 91 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint); | 161 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint); |
| 92 }; | 162 }; |
| 93 | 163 |
| 94 | 164 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 187 | 257 |
| 188 intptr_t NumLocalVariables(); | 258 intptr_t NumLocalVariables(); |
| 189 | 259 |
| 190 void VariableAt(intptr_t i, | 260 void VariableAt(intptr_t i, |
| 191 String* name, | 261 String* name, |
| 192 intptr_t* token_pos, | 262 intptr_t* token_pos, |
| 193 intptr_t* end_pos, | 263 intptr_t* end_pos, |
| 194 Object* value); | 264 Object* value); |
| 195 | 265 |
| 196 RawArray* GetLocalVariables(); | 266 RawArray* GetLocalVariables(); |
| 267 RawObject* GetParameter(intptr_t index); | |
| 268 RawObject* GetClosure(); | |
| 197 RawObject* GetReceiver(); | 269 RawObject* GetReceiver(); |
| 198 | 270 |
| 199 const Context& GetSavedCurrentContext(); | 271 const Context& GetSavedCurrentContext(); |
| 200 | 272 |
| 201 RawObject* Evaluate(const String& expr); | 273 RawObject* Evaluate(const String& expr); |
| 202 | 274 |
| 203 // Print the activation frame into |jsobj|. if |full| is false, script | 275 // Print the activation frame into |jsobj|. if |full| is false, script |
| 204 // and local variable objects are only references. if |full| is true, | 276 // and local variable objects are only references. if |full| is true, |
| 205 // the complete script, function, and, local variable objects are included. | 277 // the complete script, function, and, local variable objects are included. |
| 206 void PrintToJSONObject(JSONObject* jsobj, bool full = false); | 278 void PrintToJSONObject(JSONObject* jsobj, bool full = false); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 308 | 380 |
| 309 ActivationFrame* top_frame() const { | 381 ActivationFrame* top_frame() const { |
| 310 ASSERT(IsPauseEvent()); | 382 ASSERT(IsPauseEvent()); |
| 311 return top_frame_; | 383 return top_frame_; |
| 312 } | 384 } |
| 313 void set_top_frame(ActivationFrame* frame) { | 385 void set_top_frame(ActivationFrame* frame) { |
| 314 ASSERT(IsPauseEvent()); | 386 ASSERT(IsPauseEvent()); |
| 315 top_frame_ = frame; | 387 top_frame_ = frame; |
| 316 } | 388 } |
| 317 | 389 |
| 318 SourceBreakpoint* breakpoint() const { | 390 BreakpointCondition* breakpoint() const { |
| 319 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); | 391 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); |
| 320 return breakpoint_; | 392 return breakpoint_; |
| 321 } | 393 } |
| 322 void set_breakpoint(SourceBreakpoint* bpt) { | 394 void set_breakpoint(BreakpointCondition* bpt) { |
| 323 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); | 395 ASSERT(type_ == kBreakpointReached || type_ == kBreakpointResolved); |
| 324 breakpoint_ = bpt; | 396 breakpoint_ = bpt; |
| 325 } | 397 } |
| 326 | 398 |
| 327 const Object* exception() const { | 399 const Object* exception() const { |
| 328 ASSERT(type_ == kExceptionThrown); | 400 ASSERT(type_ == kExceptionThrown); |
| 329 return exception_; | 401 return exception_; |
| 330 } | 402 } |
| 331 void set_exception(const Object* exception) { | 403 void set_exception(const Object* exception) { |
| 332 ASSERT(type_ == kExceptionThrown); | 404 ASSERT(type_ == kExceptionThrown); |
| 333 exception_ = exception; | 405 exception_ = exception; |
| 334 } | 406 } |
| 335 | 407 |
| 336 Dart_Port isolate_id() const { | 408 Dart_Port isolate_id() const { |
| 337 return isolate_->main_port(); | 409 return isolate_->main_port(); |
| 338 } | 410 } |
| 339 | 411 |
| 340 private: | 412 private: |
| 341 Isolate* isolate_; | 413 Isolate* isolate_; |
| 342 EventType type_; | 414 EventType type_; |
| 343 ActivationFrame* top_frame_; | 415 ActivationFrame* top_frame_; |
| 344 SourceBreakpoint* breakpoint_; | 416 BreakpointCondition* breakpoint_; |
| 345 const Object* exception_; | 417 const Object* exception_; |
| 346 }; | 418 }; |
| 347 | 419 |
| 348 | 420 |
| 349 class Debugger { | 421 class Debugger { |
| 350 public: | 422 public: |
| 351 typedef void EventHandler(DebuggerEvent* event); | 423 typedef void EventHandler(DebuggerEvent* event); |
| 352 | 424 |
| 353 Debugger(); | 425 Debugger(); |
| 354 ~Debugger(); | 426 ~Debugger(); |
| 355 | 427 |
| 356 void Initialize(Isolate* isolate); | 428 void Initialize(Isolate* isolate); |
| 357 void NotifyIsolateCreated(); | 429 void NotifyIsolateCreated(); |
| 358 void Shutdown(); | 430 void Shutdown(); |
| 359 | 431 |
| 360 void NotifyCompilation(const Function& func); | 432 void NotifyCompilation(const Function& func); |
| 361 void NotifyDoneLoading(); | 433 void NotifyDoneLoading(); |
| 362 | 434 |
| 363 RawFunction* ResolveFunction(const Library& library, | 435 RawFunction* ResolveFunction(const Library& library, |
| 364 const String& class_name, | 436 const String& class_name, |
| 365 const String& function_name); | 437 const String& function_name); |
| 366 | 438 |
| 367 // Set breakpoint at closest location to function entry. | 439 // Set breakpoint at closest location to function entry. |
| 368 SourceBreakpoint* SetBreakpointAtEntry(const Function& target_function); | 440 BreakpointCondition* SetBreakpointAtEntry(const Function& target_function, |
| 441 bool single_shot); | |
| 442 BreakpointCondition* SetBreakpointAtActivation(const Instance& closure); | |
| 369 | 443 |
| 370 // TODO(turnidge): script_url may no longer be specific enough. | 444 // TODO(turnidge): script_url may no longer be specific enough. |
| 371 SourceBreakpoint* SetBreakpointAtLine(const String& script_url, | 445 BreakpointCondition* SetBreakpointAtLine(const String& script_url, |
| 372 intptr_t line_number); | 446 intptr_t line_number); |
| 373 RawError* OneTimeBreakAtEntry(const Function& target_function); | 447 RawError* OneTimeBreakAtEntry(const Function& target_function); |
| 374 | 448 |
| 449 SourceBreakpoint* SourceBreakpointAtLine(const String& script_url, | |
| 450 intptr_t line_number); | |
| 451 | |
| 452 | |
| 375 void RemoveBreakpoint(intptr_t bp_id); | 453 void RemoveBreakpoint(intptr_t bp_id); |
| 376 SourceBreakpoint* GetBreakpointById(intptr_t id); | 454 BreakpointCondition* GetBreakpointById(intptr_t id); |
| 377 | 455 |
| 378 void SetStepOver(); | 456 void SetStepOver(); |
| 379 void SetSingleStep(); | 457 void SetSingleStep(); |
| 380 void SetStepOut(); | 458 void SetStepOut(); |
| 381 bool IsStepping() const { return resume_action_ != kContinue; } | 459 bool IsStepping() const { return resume_action_ != kContinue; } |
| 382 | 460 |
| 383 bool IsPaused() const { return pause_event_ != NULL; } | 461 bool IsPaused() const { return pause_event_ != NULL; } |
| 384 | 462 |
| 385 // Indicates why the debugger is currently paused. If the debugger | 463 // Indicates why the debugger is currently paused. If the debugger |
| 386 // is not paused, this returns NULL. Note that the debugger can be | 464 // is not paused, this returns NULL. Note that the debugger can be |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 497 static ActivationFrame* CollectDartFrame(Isolate* isolate, | 575 static ActivationFrame* CollectDartFrame(Isolate* isolate, |
| 498 uword pc, | 576 uword pc, |
| 499 StackFrame* frame, | 577 StackFrame* frame, |
| 500 const Code& code, | 578 const Code& code, |
| 501 const Array& deopt_frame, | 579 const Array& deopt_frame, |
| 502 intptr_t deopt_frame_offset); | 580 intptr_t deopt_frame_offset); |
| 503 static RawArray* DeoptimizeToArray(Isolate* isolate, | 581 static RawArray* DeoptimizeToArray(Isolate* isolate, |
| 504 StackFrame* frame, | 582 StackFrame* frame, |
| 505 const Code& code); | 583 const Code& code); |
| 506 static DebuggerStackTrace* CollectStackTrace(); | 584 static DebuggerStackTrace* CollectStackTrace(); |
| 507 void SignalBpResolved(SourceBreakpoint *bpt); | 585 void SignalBpResolved(BreakpointCondition *bpt); |
| 508 void SignalPausedEvent(ActivationFrame* top_frame, | 586 void SignalPausedEvent(ActivationFrame* top_frame, |
| 509 SourceBreakpoint* bpt); | 587 BreakpointCondition* bpt); |
| 510 | 588 |
| 511 intptr_t nextId() { return next_id_++; } | 589 intptr_t nextId() { return next_id_++; } |
| 512 | 590 |
| 513 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, | 591 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
| 514 const Instance& exc); | 592 const Instance& exc); |
| 515 | 593 |
| 516 void CollectLibraryFields(const GrowableObjectArray& field_list, | 594 void CollectLibraryFields(const GrowableObjectArray& field_list, |
| 517 const Library& lib, | 595 const Library& lib, |
| 518 const String& prefix, | 596 const String& prefix, |
| 519 bool include_private_fields); | 597 bool include_private_fields); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 566 | 644 |
| 567 friend class Isolate; | 645 friend class Isolate; |
| 568 friend class SourceBreakpoint; | 646 friend class SourceBreakpoint; |
| 569 DISALLOW_COPY_AND_ASSIGN(Debugger); | 647 DISALLOW_COPY_AND_ASSIGN(Debugger); |
| 570 }; | 648 }; |
| 571 | 649 |
| 572 | 650 |
| 573 } // namespace dart | 651 } // namespace dart |
| 574 | 652 |
| 575 #endif // VM_DEBUGGER_H_ | 653 #endif // VM_DEBUGGER_H_ |
| OLD | NEW |