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

Side by Side Diff: src/debug/debug.h

Issue 2682593003: [debugger] implement legacy debug event listeners via debug delegate. (Closed)
Patch Set: asan fix 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_DEBUG_DEBUG_H_ 5 #ifndef V8_DEBUG_DEBUG_H_
6 #define V8_DEBUG_DEBUG_H_ 6 #define V8_DEBUG_DEBUG_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/assembler.h" 10 #include "src/assembler.h"
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); } 224 Handle<DebugInfo> debug_info() { return Handle<DebugInfo>(debug_info_); }
225 225
226 private: 226 private:
227 // Global (weak) handle to the debug info object. 227 // Global (weak) handle to the debug info object.
228 DebugInfo** debug_info_; 228 DebugInfo** debug_info_;
229 229
230 // Next pointer for linked list. 230 // Next pointer for linked list.
231 DebugInfoListNode* next_; 231 DebugInfoListNode* next_;
232 }; 232 };
233 233
234 // Details of the debug event delivered to the debug event listener.
235 class EventDetailsImpl : public v8::Debug::EventDetails {
236 public:
237 EventDetailsImpl(DebugEvent event, Handle<JSObject> exec_state,
238 Handle<JSObject> event_data, Handle<Object> callback_data);
239 virtual DebugEvent GetEvent() const;
240 virtual v8::Local<v8::Object> GetExecutionState() const;
241 virtual v8::Local<v8::Object> GetEventData() const;
242 virtual v8::Local<v8::Context> GetEventContext() const;
243 virtual v8::Local<v8::Value> GetCallbackData() const;
244 virtual v8::Debug::ClientData* GetClientData() const { return nullptr; }
245 virtual v8::Isolate* GetIsolate() const;
246
247 private:
248 DebugEvent event_; // Debug event causing the break.
249 Handle<JSObject> exec_state_; // Current execution state.
250 Handle<JSObject> event_data_; // Data associated with the event.
251 Handle<Object> callback_data_; // User data passed with the callback
252 // when it was registered.
253 };
254
255
256 class DebugFeatureTracker { 234 class DebugFeatureTracker {
257 public: 235 public:
258 enum Feature { 236 enum Feature {
259 kActive = 1, 237 kActive = 1,
260 kBreakPoint = 2, 238 kBreakPoint = 2,
261 kStepping = 3, 239 kStepping = 3,
262 kHeapSnapshot = 4, 240 kHeapSnapshot = 4,
263 kAllocationTracking = 5, 241 kAllocationTracking = 5,
264 kProfiler = 6, 242 kProfiler = 6,
265 kLiveEdit = 7, 243 kLiveEdit = 7,
(...skipping 18 matching lines...) Expand all
284 // DebugInfo. 262 // DebugInfo.
285 class Debug { 263 class Debug {
286 public: 264 public:
287 // Debug event triggers. 265 // Debug event triggers.
288 void OnDebugBreak(Handle<Object> break_points_hit); 266 void OnDebugBreak(Handle<Object> break_points_hit);
289 267
290 void OnThrow(Handle<Object> exception); 268 void OnThrow(Handle<Object> exception);
291 void OnPromiseReject(Handle<Object> promise, Handle<Object> value); 269 void OnPromiseReject(Handle<Object> promise, Handle<Object> value);
292 void OnCompileError(Handle<Script> script); 270 void OnCompileError(Handle<Script> script);
293 void OnAfterCompile(Handle<Script> script); 271 void OnAfterCompile(Handle<Script> script);
294 void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id); 272 void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id,
273 int parent_id);
295 274
296 // API facing.
297 void SetEventListener(Handle<Object> callback, Handle<Object> data);
298 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, 275 MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun,
299 Handle<Object> data); 276 Handle<Object> data);
300 Handle<Context> GetDebugContext(); 277 Handle<Context> GetDebugContext();
301 void HandleDebugBreak(); 278 void HandleDebugBreak();
302 279
303 // Internal logic 280 // Internal logic
304 bool Load(); 281 bool Load();
305 void Break(JavaScriptFrame* frame); 282 void Break(JavaScriptFrame* frame);
306 283
307 // Scripts handling. 284 // Scripts handling.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 317
341 void RecordGenerator(Handle<JSGeneratorObject> generator_object); 318 void RecordGenerator(Handle<JSGeneratorObject> generator_object);
342 319
343 void RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise, 320 void RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise,
344 Handle<Object> parent); 321 Handle<Object> parent);
345 322
346 int NextAsyncTaskId(Handle<JSObject> promise); 323 int NextAsyncTaskId(Handle<JSObject> promise);
347 324
348 bool IsBlackboxed(Handle<SharedFunctionInfo> shared); 325 bool IsBlackboxed(Handle<SharedFunctionInfo> shared);
349 326
350 void SetDebugDelegate(debug::DebugDelegate* delegate); 327 void SetDebugDelegate(debug::DebugDelegate* delegate, bool pass_ownership);
351 328
352 // Returns whether the operation succeeded. 329 // Returns whether the operation succeeded.
353 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); 330 bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
354 void CreateDebugInfo(Handle<SharedFunctionInfo> shared); 331 void CreateDebugInfo(Handle<SharedFunctionInfo> shared);
355 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); 332 static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
356 333
357 template <typename C> 334 template <typename C>
358 bool CompileToRevealInnerFunctions(C* compilable); 335 bool CompileToRevealInnerFunctions(C* compilable);
359 336
360 // This function is used in FunctionNameUsing* tests. 337 // This function is used in FunctionNameUsing* tests.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 Address restart_fp_address() { 417 Address restart_fp_address() {
441 return reinterpret_cast<Address>(&thread_local_.restart_fp_); 418 return reinterpret_cast<Address>(&thread_local_.restart_fp_);
442 } 419 }
443 420
444 StepAction last_step_action() { return thread_local_.last_step_action_; } 421 StepAction last_step_action() { return thread_local_.last_step_action_; }
445 422
446 DebugFeatureTracker* feature_tracker() { return &feature_tracker_; } 423 DebugFeatureTracker* feature_tracker() { return &feature_tracker_; }
447 424
448 private: 425 private:
449 explicit Debug(Isolate* isolate); 426 explicit Debug(Isolate* isolate);
427 ~Debug() { DCHECK_NULL(debug_delegate_); }
450 428
451 void UpdateState(); 429 void UpdateState();
452 void UpdateHookOnFunctionCall(); 430 void UpdateHookOnFunctionCall();
431 void RemoveDebugDelegate();
453 void Unload(); 432 void Unload();
454 void SetNextBreakId() { 433 void SetNextBreakId() {
455 thread_local_.break_id_ = ++thread_local_.break_count_; 434 thread_local_.break_id_ = ++thread_local_.break_count_;
456 } 435 }
457 436
458 // Return the number of virtual frames below debugger entry. 437 // Return the number of virtual frames below debugger entry.
459 int CurrentFrameCount(); 438 int CurrentFrameCount();
460 439
461 inline bool ignore_events() const { 440 inline bool ignore_events() const {
462 return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check(); 441 return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check();
463 } 442 }
464 inline bool break_disabled() const { 443 inline bool break_disabled() const { return break_disabled_; }
465 return break_disabled_ || in_debug_event_listener_;
466 }
467 444
468 void clear_suspended_generator() { 445 void clear_suspended_generator() {
469 thread_local_.suspended_generator_ = Smi::kZero; 446 thread_local_.suspended_generator_ = Smi::kZero;
470 } 447 }
471 448
472 bool has_suspended_generator() const { 449 bool has_suspended_generator() const {
473 return thread_local_.suspended_generator_ != Smi::kZero; 450 return thread_local_.suspended_generator_ != Smi::kZero;
474 } 451 }
475 452
476 // There are three types of event listeners: C++ message_handler,
477 // JavaScript event listener and C++ event listener.
478 // Currently inspector still uses C++ event listener and installs
479 // more specific event listeners for part of events. Calling of
480 // C++ event listener is redundant when more specific event listener
481 // is presented. Other clients can install JavaScript event listener
482 // (e.g. some of NodeJS module).
483 bool non_inspector_listener_exists() const {
484 return !event_listener_.is_null() && !event_listener_->IsForeign();
485 }
486
487 bool IsExceptionBlackboxed(bool uncaught); 453 bool IsExceptionBlackboxed(bool uncaught);
488 454
489 void OnException(Handle<Object> exception, Handle<Object> promise); 455 void OnException(Handle<Object> exception, Handle<Object> promise);
490 456
491 // Constructors for debug event objects. 457 // Constructors for debug event objects.
492 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState(); 458 MUST_USE_RESULT MaybeHandle<Object> MakeExecutionState();
493 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent( 459 MUST_USE_RESULT MaybeHandle<Object> MakeBreakEvent(
494 Handle<Object> break_points_hit); 460 Handle<Object> break_points_hit);
495 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent( 461 MUST_USE_RESULT MaybeHandle<Object> MakeExceptionEvent(
496 Handle<Object> exception, 462 Handle<Object> exception,
497 bool uncaught, 463 bool uncaught,
498 Handle<Object> promise); 464 Handle<Object> promise);
499 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( 465 MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent(
500 Handle<Script> script, v8::DebugEvent type); 466 Handle<Script> script, v8::DebugEvent type);
501 MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type, 467 MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(
502 Handle<Smi> id); 468 v8::debug::PromiseDebugActionType type, int id);
503 469
504 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); 470 void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script);
505 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); 471 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data);
506 472
507 // Find the closest source position for a break point for a given position. 473 // Find the closest source position for a break point for a given position.
508 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position, 474 int FindBreakablePosition(Handle<DebugInfo> debug_info, int source_position,
509 BreakPositionAlignment alignment); 475 BreakPositionAlignment alignment);
510 // Instrument code to break at break points. 476 // Instrument code to break at break points.
511 void ApplyBreakPoints(Handle<DebugInfo> debug_info); 477 void ApplyBreakPoints(Handle<DebugInfo> debug_info);
512 // Clear code from instrumentation. 478 // Clear code from instrumentation.
(...skipping 20 matching lines...) Expand all
533 DCHECK(in_debug_scope()); 499 DCHECK(in_debug_scope());
534 } 500 }
535 501
536 void ThreadInit(); 502 void ThreadInit();
537 503
538 void PrintBreakLocation(); 504 void PrintBreakLocation();
539 505
540 // Global handles. 506 // Global handles.
541 Handle<Context> debug_context_; 507 Handle<Context> debug_context_;
542 Handle<Object> event_listener_; 508 Handle<Object> event_listener_;
543 Handle<Object> event_listener_data_; 509 Handle<Object> event_listener_data_;
jgruber 2017/02/09 10:33:28 Can we remove event_listener{,_data}_?
544 510
545 debug::DebugDelegate* debug_delegate_ = nullptr; 511 debug::DebugDelegate* debug_delegate_ = nullptr;
512 bool owns_debug_delegate_ = false;
546 513
547 // Debugger is active, i.e. there is a debug event listener attached. 514 // Debugger is active, i.e. there is a debug event listener attached.
548 bool is_active_; 515 bool is_active_;
549 // Debugger needs to be notified on every new function call. 516 // Debugger needs to be notified on every new function call.
550 // Used for stepping and read-only checks 517 // Used for stepping and read-only checks
551 bool hook_on_function_call_; 518 bool hook_on_function_call_;
552 // Suppress debug events. 519 // Suppress debug events.
553 bool is_suppressed_; 520 bool is_suppressed_;
554 // LiveEdit is enabled. 521 // LiveEdit is enabled.
555 bool live_edit_enabled_; 522 bool live_edit_enabled_;
556 // Do not trigger debug break events. 523 // Do not trigger debug break events.
557 bool break_disabled_; 524 bool break_disabled_;
558 // Do not break on break points. 525 // Do not break on break points.
559 bool break_points_active_; 526 bool break_points_active_;
560 // Nested inside a debug event listener.
561 bool in_debug_event_listener_;
562 // Trigger debug break events for all exceptions. 527 // Trigger debug break events for all exceptions.
563 bool break_on_exception_; 528 bool break_on_exception_;
564 // Trigger debug break events for uncaught exceptions. 529 // Trigger debug break events for uncaught exceptions.
565 bool break_on_uncaught_exception_; 530 bool break_on_uncaught_exception_;
566 // Termination exception because side effect check has failed. 531 // Termination exception because side effect check has failed.
567 bool side_effect_check_failed_; 532 bool side_effect_check_failed_;
568 533
569 // List of active debug info objects. 534 // List of active debug info objects.
570 DebugInfoListNode* debug_info_list_; 535 DebugInfoListNode* debug_info_list_;
571 536
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 ThreadLocal thread_local_; 580 ThreadLocal thread_local_;
616 581
617 Isolate* isolate_; 582 Isolate* isolate_;
618 583
619 friend class Isolate; 584 friend class Isolate;
620 friend class DebugScope; 585 friend class DebugScope;
621 friend class DisableBreak; 586 friend class DisableBreak;
622 friend class LiveEdit; 587 friend class LiveEdit;
623 friend class SuppressDebug; 588 friend class SuppressDebug;
624 friend class NoSideEffectScope; 589 friend class NoSideEffectScope;
590 friend class LegacyDebugDelegate;
625 591
626 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc 592 friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc
627 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc 593 friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc
628 594
629 DISALLOW_COPY_AND_ASSIGN(Debug); 595 DISALLOW_COPY_AND_ASSIGN(Debug);
630 }; 596 };
631 597
598 class LegacyDebugDelegate : public v8::debug::DebugDelegate {
599 public:
600 explicit LegacyDebugDelegate(Isolate* isolate) : isolate_(isolate) {}
601 void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id,
602 int parent_id) override;
603 void ScriptCompiled(v8::Local<v8::debug::Script> script,
604 bool has_compile_error) override;
605 void BreakProgramRequested(v8::Local<v8::Context> paused_context,
606 v8::Local<v8::Object> exec_state,
607 v8::Local<v8::Value> break_points_hit) override;
608 void ExceptionThrown(v8::Local<v8::Context> paused_context,
609 v8::Local<v8::Object> exec_state,
610 v8::Local<v8::Value> exception,
611 v8::Local<v8::Value> promise, bool is_uncaught) override;
612 bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
613 const v8::debug::Location& start,
614 const v8::debug::Location& end) override {
615 return false;
616 }
617
618 protected:
619 Isolate* isolate_;
620
621 private:
622 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data);
623 virtual void ProcessDebugEvent(v8::DebugEvent event,
624 Handle<JSObject> event_data,
625 Handle<JSObject> exec_state) = 0;
626 };
627
628 class JavaScriptDebugDelegate : public LegacyDebugDelegate {
629 public:
630 JavaScriptDebugDelegate(Isolate* isolate, Handle<JSFunction> listener,
631 Handle<Object> data);
632 virtual ~JavaScriptDebugDelegate();
633
634 private:
635 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
636 Handle<JSObject> exec_state) override;
637
638 Handle<JSFunction> listener_;
639 Handle<Object> data_;
640 };
641
642 class NativeDebugDelegate : public LegacyDebugDelegate {
643 public:
644 NativeDebugDelegate(Isolate* isolate, v8::Debug::EventCallback callback,
645 Handle<Object> data);
646 virtual ~NativeDebugDelegate();
647
648 private:
649 // Details of the debug event delivered to the debug event listener.
650 class EventDetails : public v8::Debug::EventDetails {
651 public:
652 EventDetails(DebugEvent event, Handle<JSObject> exec_state,
653 Handle<JSObject> event_data, Handle<Object> callback_data);
654 virtual DebugEvent GetEvent() const;
655 virtual v8::Local<v8::Object> GetExecutionState() const;
656 virtual v8::Local<v8::Object> GetEventData() const;
657 virtual v8::Local<v8::Context> GetEventContext() const;
658 virtual v8::Local<v8::Value> GetCallbackData() const;
659 virtual v8::Debug::ClientData* GetClientData() const { return nullptr; }
660 virtual v8::Isolate* GetIsolate() const;
661
662 private:
663 DebugEvent event_; // Debug event causing the break.
664 Handle<JSObject> exec_state_; // Current execution state.
665 Handle<JSObject> event_data_; // Data associated with the event.
666 Handle<Object> callback_data_; // User data passed with the callback
667 // when it was registered.
668 };
669
670 void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data,
671 Handle<JSObject> exec_state) override;
672
673 v8::Debug::EventCallback callback_;
674 Handle<Object> data_;
675 };
632 676
633 // This scope is used to load and enter the debug context and create a new 677 // This scope is used to load and enter the debug context and create a new
634 // break state. Leaving the scope will restore the previous state. 678 // break state. Leaving the scope will restore the previous state.
635 // On failure to load, FailedToEnter returns true. 679 // On failure to load, FailedToEnter returns true.
636 class DebugScope BASE_EMBEDDED { 680 class DebugScope BASE_EMBEDDED {
637 public: 681 public:
638 explicit DebugScope(Debug* debug); 682 explicit DebugScope(Debug* debug);
639 ~DebugScope(); 683 ~DebugScope();
640 684
641 // Check whether loading was successful. 685 // Check whether loading was successful.
(...skipping 13 matching lines...) Expand all
655 bool failed_; // Did the debug context fail to load? 699 bool failed_; // Did the debug context fail to load?
656 SaveContext save_; // Saves previous context. 700 SaveContext save_; // Saves previous context.
657 PostponeInterruptsScope no_termination_exceptons_; 701 PostponeInterruptsScope no_termination_exceptons_;
658 }; 702 };
659 703
660 704
661 // Stack allocated class for disabling break. 705 // Stack allocated class for disabling break.
662 class DisableBreak BASE_EMBEDDED { 706 class DisableBreak BASE_EMBEDDED {
663 public: 707 public:
664 explicit DisableBreak(Debug* debug) 708 explicit DisableBreak(Debug* debug)
665 : debug_(debug), 709 : debug_(debug), previous_break_disabled_(debug->break_disabled_) {
666 previous_break_disabled_(debug->break_disabled_),
667 previous_in_debug_event_listener_(debug->in_debug_event_listener_) {
668 debug_->break_disabled_ = true; 710 debug_->break_disabled_ = true;
669 debug_->in_debug_event_listener_ = true;
670 } 711 }
671 ~DisableBreak() { 712 ~DisableBreak() {
672 debug_->break_disabled_ = previous_break_disabled_; 713 debug_->break_disabled_ = previous_break_disabled_;
673 debug_->in_debug_event_listener_ = previous_in_debug_event_listener_;
674 } 714 }
675 715
676 private: 716 private:
677 Debug* debug_; 717 Debug* debug_;
678 bool previous_break_disabled_; 718 bool previous_break_disabled_;
679 bool previous_in_debug_event_listener_;
680 DISALLOW_COPY_AND_ASSIGN(DisableBreak); 719 DISALLOW_COPY_AND_ASSIGN(DisableBreak);
681 }; 720 };
682 721
683 722
684 class SuppressDebug BASE_EMBEDDED { 723 class SuppressDebug BASE_EMBEDDED {
685 public: 724 public:
686 explicit SuppressDebug(Debug* debug) 725 explicit SuppressDebug(Debug* debug)
687 : debug_(debug), old_state_(debug->is_suppressed_) { 726 : debug_(debug), old_state_(debug->is_suppressed_) {
688 debug_->is_suppressed_ = true; 727 debug_->is_suppressed_ = true;
689 } 728 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 Handle<Code> code); 776 Handle<Code> code);
738 static bool DebugBreakSlotIsPatched(Address pc); 777 static bool DebugBreakSlotIsPatched(Address pc);
739 static void ClearDebugBreakSlot(Isolate* isolate, Address pc); 778 static void ClearDebugBreakSlot(Isolate* isolate, Address pc);
740 }; 779 };
741 780
742 781
743 } // namespace internal 782 } // namespace internal
744 } // namespace v8 783 } // namespace v8
745 784
746 #endif // V8_DEBUG_DEBUG_H_ 785 #endif // V8_DEBUG_DEBUG_H_
OLDNEW
« no previous file with comments | « src/api.cc ('k') | src/debug/debug.cc » ('j') | src/debug/debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698