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 ActiveVariables; | 15 class ActiveVariables; |
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 SourceBreakpoint; | 22 class SourceBreakpoint; |
23 class StackFrame; | 23 class StackFrame; |
24 | 24 |
25 // SourceBreakpoint represents a user-specified breakpoint location in | 25 // SourceBreakpoint represents a user-specified breakpoint location in |
26 // Dart source. There may be more than one CodeBreakpoint object per | 26 // Dart source. There may be more than one CodeBreakpoint object per |
27 // SourceBreakpoint. | 27 // SourceBreakpoint. |
28 class SourceBreakpoint { | 28 class SourceBreakpoint { |
29 public: | 29 public: |
30 SourceBreakpoint(intptr_t id, const Function& func, intptr_t token_pos); | 30 SourceBreakpoint(intptr_t id, const Script& script, intptr_t token_pos); |
31 | 31 |
32 RawFunction* function() const { return function_; } | 32 RawFunction* function() const { return function_; } |
33 intptr_t token_pos() const { return token_pos_; } | 33 intptr_t token_pos() const { return token_pos_; } |
34 void set_token_pos(intptr_t value) { token_pos_ = value; } | |
35 intptr_t id() const { return id_; } | 34 intptr_t id() const { return id_; } |
36 | 35 |
37 RawScript* SourceCode(); | 36 RawScript* script() { return script_; } |
38 RawString* SourceUrl(); | 37 RawString* SourceUrl(); |
39 intptr_t LineNumber(); | 38 intptr_t LineNumber(); |
40 | 39 |
41 void GetCodeLocation(Library* lib, | 40 void GetCodeLocation(Library* lib, Script* script, intptr_t* token_pos); |
42 Script* script, | |
43 intptr_t* token_pos) const; | |
44 | 41 |
45 void Enable(); | 42 void Enable(); |
46 void Disable(); | 43 void Disable(); |
47 bool IsEnabled() const { return is_enabled_; } | 44 bool IsEnabled() const { return is_enabled_; } |
| 45 bool IsResolved() { return is_resolved_; } |
48 | 46 |
49 void PrintToJSONStream(JSONStream* stream) const; | 47 void PrintToJSONStream(JSONStream* stream); |
50 | 48 |
51 private: | 49 private: |
52 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 50 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
53 | 51 |
54 void set_function(const Function& func); | 52 void SetResolved(const Function& func, intptr_t token_pos); |
55 void set_next(SourceBreakpoint* value) { next_ = value; } | 53 void set_next(SourceBreakpoint* value) { next_ = value; } |
56 SourceBreakpoint* next() const { return this->next_; } | 54 SourceBreakpoint* next() const { return this->next_; } |
57 | 55 |
58 const intptr_t id_; | 56 const intptr_t id_; |
| 57 RawScript* script_; |
| 58 intptr_t token_pos_; |
| 59 bool is_resolved_; |
| 60 bool is_enabled_; |
| 61 SourceBreakpoint* next_; |
| 62 |
| 63 // Valid for resolved breakpoints: |
59 RawFunction* function_; | 64 RawFunction* function_; |
60 intptr_t token_pos_; | |
61 intptr_t line_number_; | 65 intptr_t line_number_; |
62 bool is_enabled_; | |
63 | |
64 SourceBreakpoint* next_; | |
65 | 66 |
66 friend class Debugger; | 67 friend class Debugger; |
67 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint); | 68 DISALLOW_COPY_AND_ASSIGN(SourceBreakpoint); |
68 }; | 69 }; |
69 | 70 |
70 | 71 |
71 // CodeBreakpoint represents a location in compiled code. There may be | 72 // CodeBreakpoint represents a location in compiled code. There may be |
72 // more than one CodeBreakpoint for one SourceBreakpoint, e.g. when a | 73 // more than one CodeBreakpoint for one SourceBreakpoint, e.g. when a |
73 // function gets compiled as a regular function and as a closure. | 74 // function gets compiled as a regular function and as a closure. |
74 class CodeBreakpoint { | 75 class CodeBreakpoint { |
(...skipping 19 matching lines...) Expand all Loading... |
94 | 95 |
95 SourceBreakpoint* src_bpt() const { return src_bpt_; } | 96 SourceBreakpoint* src_bpt() const { return src_bpt_; } |
96 void set_src_bpt(SourceBreakpoint* value) { src_bpt_ = value; } | 97 void set_src_bpt(SourceBreakpoint* value) { src_bpt_ = value; } |
97 | 98 |
98 void set_next(CodeBreakpoint* value) { next_ = value; } | 99 void set_next(CodeBreakpoint* value) { next_ = value; } |
99 CodeBreakpoint* next() const { return this->next_; } | 100 CodeBreakpoint* next() const { return this->next_; } |
100 intptr_t pc_desc_index() const { return pc_desc_index_; } | 101 intptr_t pc_desc_index() const { return pc_desc_index_; } |
101 | 102 |
102 void PatchCode(); | 103 void PatchCode(); |
103 void RestoreCode(); | 104 void RestoreCode(); |
104 void PatchFunctionReturn(); | |
105 void RestoreFunctionReturn(); | |
106 | 105 |
107 RawFunction* function_; | 106 RawFunction* function_; |
108 intptr_t pc_desc_index_; | 107 intptr_t pc_desc_index_; |
109 intptr_t token_pos_; | 108 intptr_t token_pos_; |
110 uword pc_; | 109 uword pc_; |
111 intptr_t line_number_; | 110 intptr_t line_number_; |
112 bool is_enabled_; | 111 bool is_enabled_; |
113 | 112 |
114 SourceBreakpoint* src_bpt_; | 113 SourceBreakpoint* src_bpt_; |
115 CodeBreakpoint* next_; | 114 CodeBreakpoint* next_; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 void OneTimeBreakAtEntry(const Function& target_function); | 296 void OneTimeBreakAtEntry(const Function& target_function); |
298 | 297 |
299 void RemoveBreakpoint(intptr_t bp_id); | 298 void RemoveBreakpoint(intptr_t bp_id); |
300 SourceBreakpoint* GetBreakpointById(intptr_t id); | 299 SourceBreakpoint* GetBreakpointById(intptr_t id); |
301 | 300 |
302 void SetStepOver(); | 301 void SetStepOver(); |
303 void SetSingleStep(); | 302 void SetSingleStep(); |
304 void SetStepOut(); | 303 void SetStepOut(); |
305 bool IsStepping() const { return resume_action_ != kContinue; } | 304 bool IsStepping() const { return resume_action_ != kContinue; } |
306 | 305 |
| 306 bool IsPaused() const { return pause_event_ != NULL; } |
| 307 |
| 308 // Indicates why the debugger is currently paused. If the debugger |
| 309 // is not paused, this returns NULL. Note that the debugger can be |
| 310 // paused for breakpoints, isolate interruption, and (sometimes) |
| 311 // exceptions. |
| 312 const DebuggerEvent* PauseEvent() const { return pause_event_; } |
| 313 |
307 void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info); | 314 void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info); |
308 Dart_ExceptionPauseInfo GetExceptionPauseInfo(); | 315 Dart_ExceptionPauseInfo GetExceptionPauseInfo(); |
309 | 316 |
310 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 317 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
311 | 318 |
312 // Called from Runtime when a breakpoint in Dart code is reached. | 319 // Called from Runtime when a breakpoint in Dart code is reached. |
313 void BreakpointCallback(); | 320 void BreakpointCallback(); |
314 | 321 |
315 // Returns true if there is at least one breakpoint set in func. | 322 // Returns true if there is at least one breakpoint set in func. |
316 // Checks for both user-defined and internal temporary breakpoints. | 323 // Checks for both user-defined and internal temporary breakpoints. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 static bool IsDebuggable(const Function& func); | 370 static bool IsDebuggable(const Function& func); |
364 | 371 |
365 private: | 372 private: |
366 enum ResumeAction { | 373 enum ResumeAction { |
367 kContinue, | 374 kContinue, |
368 kStepOver, | 375 kStepOver, |
369 kStepOut, | 376 kStepOut, |
370 kSingleStep | 377 kSingleStep |
371 }; | 378 }; |
372 | 379 |
| 380 void FindEquivalentFunctions(const Script& script, |
| 381 intptr_t start_pos, |
| 382 intptr_t end_pos, |
| 383 GrowableObjectArray* function_list); |
| 384 RawFunction* FindBestFit(const Script& script, intptr_t token_pos); |
| 385 RawFunction* FindInnermostClosure(const Function& function, |
| 386 intptr_t token_pos); |
373 intptr_t ResolveBreakpointPos(const Function& func, | 387 intptr_t ResolveBreakpointPos(const Function& func, |
374 intptr_t first_token_pos, | 388 intptr_t requested_token_pos); |
375 intptr_t last_token_pos); | |
376 void DeoptimizeWorld(); | 389 void DeoptimizeWorld(); |
377 void InstrumentForStepping(const Function& target_function); | 390 void InstrumentForStepping(const Function& target_function); |
| 391 SourceBreakpoint* SetBreakpoint(const Script& script, intptr_t token_pos); |
378 SourceBreakpoint* SetBreakpoint(const Function& target_function, | 392 SourceBreakpoint* SetBreakpoint(const Function& target_function, |
379 intptr_t first_token_pos, | 393 intptr_t first_token_pos, |
380 intptr_t last_token_pos); | 394 intptr_t last_token_pos); |
381 void RemoveInternalBreakpoints(); | 395 void RemoveInternalBreakpoints(); |
382 void UnlinkCodeBreakpoints(SourceBreakpoint* src_bpt); | 396 void UnlinkCodeBreakpoints(SourceBreakpoint* src_bpt); |
383 void RegisterSourceBreakpoint(SourceBreakpoint* bpt); | 397 void RegisterSourceBreakpoint(SourceBreakpoint* bpt); |
384 void RegisterCodeBreakpoint(CodeBreakpoint* bpt); | 398 void RegisterCodeBreakpoint(CodeBreakpoint* bpt); |
385 SourceBreakpoint* GetSourceBreakpoint(const Function& func, | 399 SourceBreakpoint* GetSourceBreakpoint(const Script& script, |
386 intptr_t token_pos); | 400 intptr_t token_pos); |
387 void MakeCodeBreakpointsAt(const Function& func, | 401 void MakeCodeBreakpointsAt(const Function& func, |
388 intptr_t token_pos, | |
389 SourceBreakpoint* bpt); | 402 SourceBreakpoint* bpt); |
390 // Returns NULL if no breakpoint exists for the given address. | 403 // Returns NULL if no breakpoint exists for the given address. |
391 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address); | 404 CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address); |
392 | 405 |
393 void SyncBreakpoint(SourceBreakpoint* bpt); | 406 void SyncBreakpoint(SourceBreakpoint* bpt); |
394 | 407 |
395 ActivationFrame* TopDartFrame() const; | 408 ActivationFrame* TopDartFrame() const; |
396 static ActivationFrame* CollectDartFrame(Isolate* isolate, | 409 static ActivationFrame* CollectDartFrame(Isolate* isolate, |
397 uword pc, | 410 uword pc, |
398 StackFrame* frame, | 411 StackFrame* frame, |
(...skipping 13 matching lines...) Expand all Loading... |
412 intptr_t nextId() { return next_id_++; } | 425 intptr_t nextId() { return next_id_++; } |
413 | 426 |
414 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, | 427 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, |
415 const Instance& exc); | 428 const Instance& exc); |
416 | 429 |
417 void CollectLibraryFields(const GrowableObjectArray& field_list, | 430 void CollectLibraryFields(const GrowableObjectArray& field_list, |
418 const Library& lib, | 431 const Library& lib, |
419 const String& prefix, | 432 const String& prefix, |
420 bool include_private_fields); | 433 bool include_private_fields); |
421 | 434 |
| 435 // Handles any events which pause vm execution. Breakpoints, |
| 436 // interrupts, etc. |
| 437 void Pause(DebuggerEvent* event); |
| 438 |
422 Isolate* isolate_; | 439 Isolate* isolate_; |
423 Dart_Port isolate_id_; // A unique ID for the isolate in the debugger. | 440 Dart_Port isolate_id_; // A unique ID for the isolate in the debugger. |
424 bool initialized_; | 441 bool initialized_; |
425 | 442 |
426 // ID number generator. | 443 // ID number generator. |
427 intptr_t next_id_; | 444 intptr_t next_id_; |
428 | 445 |
429 // Current stack trace. Valid while executing breakpoint callback code. | |
430 DebuggerStackTrace* stack_trace_; | |
431 | |
432 RemoteObjectCache* obj_cache_; | |
433 | 446 |
434 SourceBreakpoint* src_breakpoints_; | 447 SourceBreakpoint* src_breakpoints_; |
435 CodeBreakpoint* code_breakpoints_; | 448 CodeBreakpoint* code_breakpoints_; |
436 | 449 |
437 // Tells debugger what to do when resuming execution after a breakpoint. | 450 // Tells debugger what to do when resuming execution after a breakpoint. |
438 ResumeAction resume_action_; | 451 ResumeAction resume_action_; |
439 | 452 |
440 // Do not call back to breakpoint handler if this flag is set. | 453 // Do not call back to breakpoint handler if this flag is set. |
441 // Effectively this means ignoring breakpoints. Set when Dart code may | 454 // Effectively this means ignoring breakpoints. Set when Dart code may |
442 // be run as a side effect of getting values of fields. | 455 // be run as a side effect of getting values of fields. |
443 bool ignore_breakpoints_; | 456 bool ignore_breakpoints_; |
444 | 457 |
445 // True while debugger calls event_handler_. Used to prevent recursive | 458 // Indicates why the debugger is currently paused. If the debugger |
446 // debugger events. | 459 // is not paused, this is NULL. Note that the debugger can be |
447 bool in_event_notification_; | 460 // paused for breakpoints, isolate interruption, and (sometimes) |
| 461 // exceptions. |
| 462 DebuggerEvent* pause_event_; |
| 463 |
| 464 // An id -> object map. Valid only while IsPaused(). |
| 465 RemoteObjectCache* obj_cache_; |
| 466 |
| 467 // Current stack trace. Valid only while IsPaused(). |
| 468 DebuggerStackTrace* stack_trace_; |
448 | 469 |
449 Dart_ExceptionPauseInfo exc_pause_info_; | 470 Dart_ExceptionPauseInfo exc_pause_info_; |
450 | 471 |
451 static EventHandler* event_handler_; | 472 static EventHandler* event_handler_; |
452 | 473 |
453 friend class Isolate; | 474 friend class Isolate; |
454 friend class SourceBreakpoint; | 475 friend class SourceBreakpoint; |
455 DISALLOW_COPY_AND_ASSIGN(Debugger); | 476 DISALLOW_COPY_AND_ASSIGN(Debugger); |
456 }; | 477 }; |
457 | 478 |
458 | 479 |
459 } // namespace dart | 480 } // namespace dart |
460 | 481 |
461 #endif // VM_DEBUGGER_H_ | 482 #endif // VM_DEBUGGER_H_ |
OLD | NEW |