Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(836)

Side by Side Diff: runtime/vm/debugger.h

Issue 2646443005: Track async causal stack traces (Closed)
Patch Set: rebase Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/dart_api_impl.cc ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 DECLARE_FLAG(bool, verbose_debug);
15
16 // 'Trace Debugger' TD_Print.
17 #if defined(_MSC_VER)
18 #define TD_Print(format, ...) \
19 if (FLAG_verbose_debug) Log::Current()->Print(format, __VA_ARGS__)
20 #else
21 #define TD_Print(format, ...) \
22 if (FLAG_verbose_debug) Log::Current()->Print(format, ##__VA_ARGS__)
23 #endif
24
25
14 namespace dart { 26 namespace dart {
15 27
16 class CodeBreakpoint; 28 class CodeBreakpoint;
17 class Isolate; 29 class Isolate;
18 class JSONArray; 30 class JSONArray;
19 class JSONStream; 31 class JSONStream;
20 class ObjectPointerVisitor; 32 class ObjectPointerVisitor;
21 class RemoteObjectCache; 33 class RemoteObjectCache;
22 class BreakpointLocation; 34 class BreakpointLocation;
23 class StackFrame; 35 class StackFrame;
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 250
239 friend class Debugger; 251 friend class Debugger;
240 DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint); 252 DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint);
241 }; 253 };
242 254
243 255
244 // ActivationFrame represents one dart function activation frame 256 // ActivationFrame represents one dart function activation frame
245 // on the call stack. 257 // on the call stack.
246 class ActivationFrame : public ZoneAllocated { 258 class ActivationFrame : public ZoneAllocated {
247 public: 259 public:
260 enum Kind {
261 kRegular,
262 kAsyncSuspensionMarker,
263 kAsyncCausal,
264 };
265
248 ActivationFrame(uword pc, 266 ActivationFrame(uword pc,
249 uword fp, 267 uword fp,
250 uword sp, 268 uword sp,
251 const Code& code, 269 const Code& code,
252 const Array& deopt_frame, 270 const Array& deopt_frame,
253 intptr_t deopt_frame_offset); 271 intptr_t deopt_frame_offset,
272 Kind kind = kRegular);
273
274 ActivationFrame(uword pc, const Code& code);
275
276 explicit ActivationFrame(Kind kind);
254 277
255 uword pc() const { return pc_; } 278 uword pc() const { return pc_; }
256 uword fp() const { return fp_; } 279 uword fp() const { return fp_; }
257 uword sp() const { return sp_; } 280 uword sp() const { return sp_; }
258 const Function& function() const { 281 const Function& function() const {
259 ASSERT(!function_.IsNull()); 282 ASSERT(!function_.IsNull());
260 return function_; 283 return function_;
261 } 284 }
262 const Code& code() const { 285 const Code& code() const {
263 ASSERT(!code_.IsNull()); 286 ASSERT(!code_.IsNull());
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 RawObject* GetAsyncOperation(); 327 RawObject* GetAsyncOperation();
305 328
306 RawObject* Evaluate(const String& expr); 329 RawObject* Evaluate(const String& expr);
307 330
308 // Print the activation frame into |jsobj|. if |full| is false, script 331 // Print the activation frame into |jsobj|. if |full| is false, script
309 // and local variable objects are only references. if |full| is true, 332 // and local variable objects are only references. if |full| is true,
310 // the complete script, function, and, local variable objects are included. 333 // the complete script, function, and, local variable objects are included.
311 void PrintToJSONObject(JSONObject* jsobj, bool full = false); 334 void PrintToJSONObject(JSONObject* jsobj, bool full = false);
312 335
313 private: 336 private:
337 void PrintToJSONObjectRegular(JSONObject* jsobj, bool full);
338 void PrintToJSONObjectAsyncCausal(JSONObject* jsobj, bool full);
339 void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, bool full);
340
314 void PrintContextMismatchError(intptr_t ctx_slot, 341 void PrintContextMismatchError(intptr_t ctx_slot,
315 intptr_t frame_ctx_level, 342 intptr_t frame_ctx_level,
316 intptr_t var_ctx_level); 343 intptr_t var_ctx_level);
317 344
318 intptr_t TryIndex(); 345 intptr_t TryIndex();
319 void GetPcDescriptors(); 346 void GetPcDescriptors();
320 void GetVarDescriptors(); 347 void GetVarDescriptors();
321 void GetDescIndices(); 348 void GetDescIndices();
322 349
350 static const char* KindToCString(Kind kind) {
351 switch (kind) {
352 case kRegular:
353 return "kRegular";
354 case kAsyncCausal:
355 return "kAsyncCausal";
356 case kAsyncSuspensionMarker:
357 return "kAsyncSuspensionMarker";
358 default:
359 UNREACHABLE();
360 return "";
361 }
362 }
363
323 RawObject* GetStackVar(intptr_t slot_index); 364 RawObject* GetStackVar(intptr_t slot_index);
324 RawObject* GetContextVar(intptr_t ctxt_level, intptr_t slot_index); 365 RawObject* GetContextVar(intptr_t ctxt_level, intptr_t slot_index);
325 366
326 uword pc_; 367 uword pc_;
327 uword fp_; 368 uword fp_;
328 uword sp_; 369 uword sp_;
329 370
330 // The anchor of the context chain for this function. 371 // The anchor of the context chain for this function.
331 Context& ctx_; 372 Context& ctx_;
332 const Code& code_; 373 Code& code_;
333 const Function& function_; 374 Function& function_;
375 bool live_frame_; // Is this frame a live frame?
334 bool token_pos_initialized_; 376 bool token_pos_initialized_;
335 TokenPosition token_pos_; 377 TokenPosition token_pos_;
336 intptr_t try_index_; 378 intptr_t try_index_;
337 379
338 intptr_t line_number_; 380 intptr_t line_number_;
339 intptr_t column_number_; 381 intptr_t column_number_;
340 intptr_t context_level_; 382 intptr_t context_level_;
341 383
342 // Some frames are deoptimized into a side array in order to inspect them. 384 // Some frames are deoptimized into a side array in order to inspect them.
343 const Array& deopt_frame_; 385 const Array& deopt_frame_;
344 const intptr_t deopt_frame_offset_; 386 const intptr_t deopt_frame_offset_;
345 387
388 Kind kind_;
389
346 bool vars_initialized_; 390 bool vars_initialized_;
347 LocalVarDescriptors& var_descriptors_; 391 LocalVarDescriptors& var_descriptors_;
348 ZoneGrowableArray<intptr_t> desc_indices_; 392 ZoneGrowableArray<intptr_t> desc_indices_;
349 PcDescriptors& pc_desc_; 393 PcDescriptors& pc_desc_;
350 394
351 friend class Debugger; 395 friend class Debugger;
352 friend class DebuggerStackTrace; 396 friend class DebuggerStackTrace;
353 DISALLOW_COPY_AND_ASSIGN(ActivationFrame); 397 DISALLOW_COPY_AND_ASSIGN(ActivationFrame);
354 }; 398 };
355 399
356 400
357 // Array of function activations on the call stack. 401 // Array of function activations on the call stack.
358 class DebuggerStackTrace : public ZoneAllocated { 402 class DebuggerStackTrace : public ZoneAllocated {
359 public: 403 public:
360 explicit DebuggerStackTrace(int capacity) : trace_(capacity) {} 404 explicit DebuggerStackTrace(int capacity) : trace_(capacity) {}
361 405
362 intptr_t Length() const { return trace_.length(); } 406 intptr_t Length() const { return trace_.length(); }
363 407
364 ActivationFrame* FrameAt(int i) const { return trace_[i]; } 408 ActivationFrame* FrameAt(int i) const { return trace_[i]; }
365 409
366 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const; 410 ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;
367 411
368 private: 412 private:
369 void AddActivation(ActivationFrame* frame); 413 void AddActivation(ActivationFrame* frame);
414 void AddMarker(ActivationFrame::Kind marker);
415 void AddAsyncCausalFrame(uword pc, const Code& code);
416
370 ZoneGrowableArray<ActivationFrame*> trace_; 417 ZoneGrowableArray<ActivationFrame*> trace_;
371 418
372 friend class Debugger; 419 friend class Debugger;
373 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace); 420 DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace);
374 }; 421 };
375 422
376 423
377 class Debugger { 424 class Debugger {
378 public: 425 public:
379 enum ResumeAction { 426 enum ResumeAction {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 // a debugger stub. 510 // a debugger stub.
464 bool HasActiveBreakpoint(uword pc); 511 bool HasActiveBreakpoint(uword pc);
465 512
466 // Returns a stack trace with frames corresponding to invisible functions 513 // Returns a stack trace with frames corresponding to invisible functions
467 // omitted. CurrentStackTrace always returns a new trace on the current stack. 514 // omitted. CurrentStackTrace always returns a new trace on the current stack.
468 // The trace returned by StackTrace may have been cached; it is suitable for 515 // The trace returned by StackTrace may have been cached; it is suitable for
469 // use when stepping, but otherwise may be out of sync with the current stack. 516 // use when stepping, but otherwise may be out of sync with the current stack.
470 DebuggerStackTrace* StackTrace(); 517 DebuggerStackTrace* StackTrace();
471 DebuggerStackTrace* CurrentStackTrace(); 518 DebuggerStackTrace* CurrentStackTrace();
472 519
520 DebuggerStackTrace* AsyncCausalStackTrace();
521 DebuggerStackTrace* CurrentAsyncCausalStackTrace();
522
473 // Returns a debugger stack trace corresponding to a dart.core.StackTrace. 523 // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
474 // Frames corresponding to invisible functions are omitted. It is not valid 524 // Frames corresponding to invisible functions are omitted. It is not valid
475 // to query local variables in the returned stack. 525 // to query local variables in the returned stack.
476 DebuggerStackTrace* StackTraceFrom(const class StackTrace& dart_stacktrace); 526 DebuggerStackTrace* StackTraceFrom(const class StackTrace& dart_stacktrace);
477 527
478 RawArray* GetInstanceFields(const Instance& obj); 528 RawArray* GetInstanceFields(const Instance& obj);
479 RawArray* GetStaticFields(const Class& cls); 529 RawArray* GetStaticFields(const Class& cls);
480 RawArray* GetLibraryFields(const Library& lib); 530 RawArray* GetLibraryFields(const Library& lib);
481 RawArray* GetGlobalFields(const Library& lib); 531 RawArray* GetGlobalFields(const Library& lib);
482 532
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 static bool IsDebuggable(const Function& func); 573 static bool IsDebuggable(const Function& func);
524 574
525 intptr_t limitBreakpointId() { return next_id_; } 575 intptr_t limitBreakpointId() { return next_id_; }
526 576
527 // Callback to the debugger to continue frame rewind, post-deoptimization. 577 // Callback to the debugger to continue frame rewind, post-deoptimization.
528 void RewindPostDeopt(); 578 void RewindPostDeopt();
529 579
530 private: 580 private:
531 RawError* PauseRequest(ServiceEvent::EventKind kind); 581 RawError* PauseRequest(ServiceEvent::EventKind kind);
532 582
583 // Finds the breakpoint we hit at |location|.
584 Breakpoint* FindHitBreakpoint(BreakpointLocation* location,
585 ActivationFrame* top_frame);
586
533 // Will return false if we are not at an await. 587 // Will return false if we are not at an await.
534 bool SetupStepOverAsyncSuspension(const char** error); 588 bool SetupStepOverAsyncSuspension(const char** error);
535 589
536 bool NeedsIsolateEvents(); 590 bool NeedsIsolateEvents();
537 bool NeedsDebugEvents(); 591 bool NeedsDebugEvents();
538 void InvokeEventHandler(ServiceEvent* event); 592 void InvokeEventHandler(ServiceEvent* event);
539 593
540 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt); 594 void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);
541 595
542 bool IsAtAsyncJump(ActivationFrame* top_frame); 596 bool IsAtAsyncJump(ActivationFrame* top_frame);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
576 ActivationFrame* TopDartFrame() const; 630 ActivationFrame* TopDartFrame() const;
577 static ActivationFrame* CollectDartFrame(Isolate* isolate, 631 static ActivationFrame* CollectDartFrame(Isolate* isolate,
578 uword pc, 632 uword pc,
579 StackFrame* frame, 633 StackFrame* frame,
580 const Code& code, 634 const Code& code,
581 const Array& deopt_frame, 635 const Array& deopt_frame,
582 intptr_t deopt_frame_offset); 636 intptr_t deopt_frame_offset);
583 static RawArray* DeoptimizeToArray(Thread* thread, 637 static RawArray* DeoptimizeToArray(Thread* thread,
584 StackFrame* frame, 638 StackFrame* frame,
585 const Code& code); 639 const Code& code);
640 // Appends at least one stack frame. Multiple frames will be appended
641 // if |code| at the frame's pc contains inlined functions.
642 static void AppendCodeFrames(Thread* thread,
643 Isolate* isolate,
644 Zone* zone,
645 DebuggerStackTrace* stack_trace,
646 StackFrame* frame,
647 Code* code,
648 Code* inlined_code,
649 Array* deopt_frame);
586 static DebuggerStackTrace* CollectStackTrace(); 650 static DebuggerStackTrace* CollectStackTrace();
651 static DebuggerStackTrace* CollectAsyncCausalStackTrace();
587 void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt); 652 void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);
588 653
589 intptr_t nextId() { return next_id_++; } 654 intptr_t nextId() { return next_id_++; }
590 655
591 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace, 656 bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
592 const Instance& exc); 657 const Instance& exc);
593 658
594 void CollectLibraryFields(const GrowableObjectArray& field_list, 659 void CollectLibraryFields(const GrowableObjectArray& field_list,
595 const Library& lib, 660 const Library& lib,
596 const String& prefix, 661 const String& prefix,
597 bool include_private_fields); 662 bool include_private_fields);
598 663
599 // Handles any events which pause vm execution. Breakpoints, 664 // Handles any events which pause vm execution. Breakpoints,
600 // interrupts, etc. 665 // interrupts, etc.
601 void Pause(ServiceEvent* event); 666 void Pause(ServiceEvent* event);
602 667
603 void HandleSteppingRequest(DebuggerStackTrace* stack_trace, 668 void HandleSteppingRequest(DebuggerStackTrace* stack_trace,
604 bool skip_next_step = false); 669 bool skip_next_step = false);
605 670
671 void CacheStackTraces(DebuggerStackTrace* stack_trace,
672 DebuggerStackTrace* async_causal_stack_trace);
673 void ClearCachedStackTraces();
674
675
606 // Can we rewind to the indicated frame? 676 // Can we rewind to the indicated frame?
607 bool CanRewindFrame(intptr_t frame_index, const char** error) const; 677 bool CanRewindFrame(intptr_t frame_index, const char** error) const;
608 678
609 void RewindToFrame(intptr_t frame_index); 679 void RewindToFrame(intptr_t frame_index);
610 void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code); 680 void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code);
611 void RewindToOptimizedFrame(StackFrame* frame, 681 void RewindToOptimizedFrame(StackFrame* frame,
612 const Code& code, 682 const Code& code,
613 intptr_t post_deopt_frame_index); 683 intptr_t post_deopt_frame_index);
614 684
615 Isolate* isolate_; 685 Isolate* isolate_;
(...skipping 21 matching lines...) Expand all
637 // is not paused, this is NULL. Note that the debugger can be 707 // is not paused, this is NULL. Note that the debugger can be
638 // paused for breakpoints, isolate interruption, and (sometimes) 708 // paused for breakpoints, isolate interruption, and (sometimes)
639 // exceptions. 709 // exceptions.
640 ServiceEvent* pause_event_; 710 ServiceEvent* pause_event_;
641 711
642 // An id -> object map. Valid only while IsPaused(). 712 // An id -> object map. Valid only while IsPaused().
643 RemoteObjectCache* obj_cache_; 713 RemoteObjectCache* obj_cache_;
644 714
645 // Current stack trace. Valid only while IsPaused(). 715 // Current stack trace. Valid only while IsPaused().
646 DebuggerStackTrace* stack_trace_; 716 DebuggerStackTrace* stack_trace_;
717 DebuggerStackTrace* async_causal_stack_trace_;
647 718
648 // When stepping through code, only pause the program if the top 719 // When stepping through code, only pause the program if the top
649 // frame corresponds to this fp value, or if the top frame is 720 // frame corresponds to this fp value, or if the top frame is
650 // lower on the stack. 721 // lower on the stack.
651 uword stepping_fp_; 722 uword stepping_fp_;
652 723
653 // If we step while at a breakpoint, we would hit the same pc twice. 724 // If we step while at a breakpoint, we would hit the same pc twice.
654 // We use this field to let us skip the next single-step after a 725 // We use this field to let us skip the next single-step after a
655 // breakpoint. 726 // breakpoint.
656 bool skip_next_step_; 727 bool skip_next_step_;
657 728
658 // We keep this breakpoint alive until after the debugger does the step over 729 // We keep this breakpoint alive until after the debugger does the step over
659 // async continuation machinery so that we can report that we've stopped 730 // async continuation machinery so that we can report that we've stopped
660 // at the breakpoint. 731 // at the breakpoint.
661 Breakpoint* synthetic_async_breakpoint_; 732 Breakpoint* synthetic_async_breakpoint_;
662 733
663 Dart_ExceptionPauseInfo exc_pause_info_; 734 Dart_ExceptionPauseInfo exc_pause_info_;
664 735
665 static EventHandler* event_handler_; 736 static EventHandler* event_handler_;
666 737
667 friend class Isolate; 738 friend class Isolate;
668 friend class BreakpointLocation; 739 friend class BreakpointLocation;
669 DISALLOW_COPY_AND_ASSIGN(Debugger); 740 DISALLOW_COPY_AND_ASSIGN(Debugger);
670 }; 741 };
671 742
672 743
673 } // namespace dart 744 } // namespace dart
674 745
675 #endif // RUNTIME_VM_DEBUGGER_H_ 746 #endif // RUNTIME_VM_DEBUGGER_H_
OLDNEW
« no previous file with comments | « runtime/vm/dart_api_impl.cc ('k') | runtime/vm/debugger.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698