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

Side by Side Diff: src/inspector/v8-debugger.cc

Issue 2622253004: [inspector] introduced debug::SetBreakEventListener,SetExceptionEventListener (Closed)
Patch Set: addressed comments Created 3 years, 11 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
« src/debug/debug.cc ('K') | « src/inspector/v8-debugger.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 #include "src/inspector/v8-debugger.h" 5 #include "src/inspector/v8-debugger.h"
6 6
7 #include "src/inspector/debugger-script.h" 7 #include "src/inspector/debugger-script.h"
8 #include "src/inspector/inspected-context.h" 8 #include "src/inspector/inspected-context.h"
9 #include "src/inspector/protocol/Protocol.h" 9 #include "src/inspector/protocol/Protocol.h"
10 #include "src/inspector/script-breakpoint.h" 10 #include "src/inspector/script-breakpoint.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 m_maxAsyncCallStackDepth(0), 61 m_maxAsyncCallStackDepth(0),
62 m_pauseOnExceptionsState(v8::debug::NoBreakOnException), 62 m_pauseOnExceptionsState(v8::debug::NoBreakOnException),
63 m_wasmTranslation(isolate) {} 63 m_wasmTranslation(isolate) {}
64 64
65 V8Debugger::~V8Debugger() {} 65 V8Debugger::~V8Debugger() {}
66 66
67 void V8Debugger::enable() { 67 void V8Debugger::enable() {
68 if (m_enableCount++) return; 68 if (m_enableCount++) return;
69 DCHECK(!enabled()); 69 DCHECK(!enabled());
70 v8::HandleScope scope(m_isolate); 70 v8::HandleScope scope(m_isolate);
71 v8::debug::SetDebugEventListener(m_isolate, &V8Debugger::v8DebugEventCallback, 71 v8::debug::SetDebugEventListener(m_isolate, this);
72 v8::External::New(m_isolate, this));
73 v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener,
74 this);
75 v8::debug::SetCompileEventListener(m_isolate,
76 &V8Debugger::v8CompileEventListener, this);
77 v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback, 72 v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback,
78 this); 73 this);
79 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate)); 74 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate));
80 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException); 75 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException);
81 m_pauseOnExceptionsState = v8::debug::NoBreakOnException; 76 m_pauseOnExceptionsState = v8::debug::NoBreakOnException;
82 compileDebuggerScript(); 77 compileDebuggerScript();
83 } 78 }
84 79
85 void V8Debugger::disable() { 80 void V8Debugger::disable() {
86 if (--m_enableCount) return; 81 if (--m_enableCount) return;
87 DCHECK(enabled()); 82 DCHECK(enabled());
88 clearBreakpoints(); 83 clearBreakpoints();
89 m_debuggerScript.Reset(); 84 m_debuggerScript.Reset();
90 m_debuggerContext.Reset(); 85 m_debuggerContext.Reset();
91 allAsyncTasksCanceled(); 86 allAsyncTasksCanceled();
92 m_wasmTranslation.Clear(); 87 m_wasmTranslation.Clear();
93 v8::debug::SetDebugEventListener(m_isolate, nullptr); 88 v8::debug::SetDebugEventListener(m_isolate, nullptr);
94 v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr);
95 v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr);
96 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr); 89 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
97 m_isolate->RestoreOriginalHeapLimit(); 90 m_isolate->RestoreOriginalHeapLimit();
98 } 91 }
99 92
100 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } 93 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
101 94
102 void V8Debugger::getCompiledScripts( 95 void V8Debugger::getCompiledScripts(
103 int contextGroupId, 96 int contextGroupId,
104 std::vector<std::unique_ptr<V8DebuggerScript>>& result) { 97 std::vector<std::unique_ptr<V8DebuggerScript>>& result) {
105 v8::HandleScope scope(m_isolate); 98 v8::HandleScope scope(m_isolate);
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 } 512 }
520 } 513 }
521 514
522 void V8Debugger::v8OOMCallback(void* data) { 515 void V8Debugger::v8OOMCallback(void* data) {
523 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); 516 V8Debugger* thisPtr = static_cast<V8Debugger*>(data);
524 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); 517 thisPtr->m_isolate->IncreaseHeapLimitForDebugging();
525 thisPtr->m_scheduledOOMBreak = true; 518 thisPtr->m_scheduledOOMBreak = true;
526 thisPtr->setPauseOnNextStatement(true); 519 thisPtr->setPauseOnNextStatement(true);
527 } 520 }
528 521
529 void V8Debugger::v8DebugEventCallback( 522 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
530 const v8::debug::EventDetails& eventDetails) { 523 bool has_compile_error) {
531 V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData());
532 thisPtr->handleV8DebugEvent(eventDetails);
533 }
534
535 v8::Local<v8::Value> V8Debugger::callInternalGetterFunction(
536 v8::Local<v8::Object> object, const char* functionName) {
537 v8::MicrotasksScope microtasks(m_isolate,
538 v8::MicrotasksScope::kDoNotRunMicrotasks);
539 v8::Local<v8::Value> getterValue =
540 object
541 ->Get(m_isolate->GetCurrentContext(),
542 toV8StringInternalized(m_isolate, functionName))
543 .ToLocalChecked();
544 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction());
545 return v8::Local<v8::Function>::Cast(getterValue)
546 ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr)
547 .ToLocalChecked();
548 }
549
550 void V8Debugger::handleV8DebugEvent(
551 const v8::debug::EventDetails& eventDetails) {
552 if (!enabled()) return;
553 v8::HandleScope scope(m_isolate);
554
555 v8::DebugEvent event = eventDetails.GetEvent();
556 if (event != v8::Break && event != v8::Exception) return;
557
558 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext();
559 DCHECK(!eventContext.IsEmpty());
560 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
561 m_inspector->contextGroupId(eventContext));
562 if (!agent) return;
563
564 if (event == v8::Exception) {
565 v8::Local<v8::Context> context = debuggerContext();
566 v8::Local<v8::Object> eventData = eventDetails.GetEventData();
567 v8::Local<v8::Value> exception =
568 callInternalGetterFunction(eventData, "exception");
569 v8::Local<v8::Value> promise =
570 callInternalGetterFunction(eventData, "promise");
571 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject();
572 v8::Local<v8::Value> uncaught =
573 callInternalGetterFunction(eventData, "uncaught");
574 bool isUncaught = uncaught->BooleanValue(context).FromJust();
575 handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
576 exception, v8::Local<v8::Array>(), isPromiseRejection,
577 isUncaught);
578 } else if (event == v8::Break) {
579 v8::Local<v8::Value> argv[] = {eventDetails.GetEventData()};
580 v8::Local<v8::Value> hitBreakpoints;
581 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv)
582 .ToLocal(&hitBreakpoints))
583 return;
584 DCHECK(hitBreakpoints->IsArray());
585 handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
586 v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>());
587 }
588 }
589
590 void V8Debugger::v8CompileEventListener(v8::Local<v8::debug::Script> script,
591 bool has_compile_error, void* data) {
592 V8Debugger* debugger = static_cast<V8Debugger*>(data);
593 v8::Local<v8::Value> contextData; 524 v8::Local<v8::Value> contextData;
594 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) { 525 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
595 return; 526 return;
596 } 527 }
597 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value()); 528 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
598 int contextGroupId = debugger->m_inspector->contextGroupId(contextId); 529 int contextGroupId = m_inspector->contextGroupId(contextId);
599 if (!contextGroupId) return; 530 if (!contextGroupId) return;
600 V8DebuggerAgentImpl* agent = 531 V8DebuggerAgentImpl* agent =
601 debugger->m_inspector->enabledDebuggerAgentForGroup(contextGroupId); 532 m_inspector->enabledDebuggerAgentForGroup(contextGroupId);
602 if (!agent) return; 533 if (!agent) return;
603 if (script->IsWasm()) { 534 if (script->IsWasm()) {
604 debugger->m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), 535 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent);
605 agent); 536 } else if (m_ignoreScriptParsedEventsCounter == 0) {
606 } else if (debugger->m_ignoreScriptParsedEventsCounter == 0) {
607 agent->didParseSource( 537 agent->didParseSource(
608 V8DebuggerScript::Create(debugger->m_isolate, script, inLiveEditScope), 538 V8DebuggerScript::Create(m_isolate, script, inLiveEditScope),
609 !has_compile_error); 539 !has_compile_error);
610 } 540 }
611 } 541 }
612 542
613 void V8Debugger::v8AsyncTaskListener(v8::debug::PromiseDebugActionType type, 543 void V8Debugger::BreakProgramRequested(v8::Local<v8::Context> pausedContext,
614 int id, void* data) { 544 v8::Local<v8::Object> execState,
615 V8Debugger* debugger = static_cast<V8Debugger*>(data); 545 v8::Local<v8::Value> breakPointsHit) {
616 if (!debugger->m_maxAsyncCallStackDepth) return; 546 v8::Local<v8::Value> argv[] = {breakPointsHit};
547 v8::Local<v8::Value> hitBreakpoints;
548 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv)
549 .ToLocal(&hitBreakpoints)) {
550 return;
551 }
552 DCHECK(hitBreakpoints->IsArray());
553 handleProgramBreak(pausedContext, execState, v8::Local<v8::Value>(),
554 hitBreakpoints.As<v8::Array>());
555 }
556
557 void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
558 v8::Local<v8::Object> execState,
559 v8::Local<v8::Value> exception,
560 bool isPromiseRejection, bool isUncaught) {
561 handleProgramBreak(pausedContext, execState, exception,
562 v8::Local<v8::Array>(), isPromiseRejection, isUncaught);
563 }
564
565 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type,
566 int id) {
567 if (!m_maxAsyncCallStackDepth) return;
617 // Async task events from Promises are given misaligned pointers to prevent 568 // Async task events from Promises are given misaligned pointers to prevent
618 // from overlapping with other Blink task identifiers. There is a single 569 // from overlapping with other Blink task identifiers. There is a single
619 // namespace of such ids, managed by src/js/promise.js. 570 // namespace of such ids, managed by src/js/promise.js.
620 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 571 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
621 switch (type) { 572 switch (type) {
622 case v8::debug::kDebugEnqueueAsyncFunction: 573 case v8::debug::kDebugEnqueueAsyncFunction:
623 debugger->asyncTaskScheduled("async function", ptr, true); 574 asyncTaskScheduled("async function", ptr, true);
624 break; 575 break;
625 case v8::debug::kDebugEnqueuePromiseResolve: 576 case v8::debug::kDebugEnqueuePromiseResolve:
626 debugger->asyncTaskScheduled("Promise.resolve", ptr, true); 577 asyncTaskScheduled("Promise.resolve", ptr, true);
627 break; 578 break;
628 case v8::debug::kDebugEnqueuePromiseReject: 579 case v8::debug::kDebugEnqueuePromiseReject:
629 debugger->asyncTaskScheduled("Promise.reject", ptr, true); 580 asyncTaskScheduled("Promise.reject", ptr, true);
630 break; 581 break;
631 case v8::debug::kDebugEnqueuePromiseResolveThenableJob: 582 case v8::debug::kDebugEnqueuePromiseResolveThenableJob:
632 debugger->asyncTaskScheduled("PromiseResolveThenableJob", ptr, true); 583 asyncTaskScheduled("PromiseResolveThenableJob", ptr, true);
633 break; 584 break;
634 case v8::debug::kDebugPromiseCollected: 585 case v8::debug::kDebugPromiseCollected:
635 debugger->asyncTaskCanceled(ptr); 586 asyncTaskCanceled(ptr);
636 break; 587 break;
637 case v8::debug::kDebugWillHandle: 588 case v8::debug::kDebugWillHandle:
638 debugger->asyncTaskStarted(ptr); 589 asyncTaskStarted(ptr);
639 break; 590 break;
640 case v8::debug::kDebugDidHandle: 591 case v8::debug::kDebugDidHandle:
641 debugger->asyncTaskFinished(ptr); 592 asyncTaskFinished(ptr);
642 break; 593 break;
643 } 594 }
644 } 595 }
645 596
646 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { 597 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
647 if (!m_currentStacks.size()) return nullptr; 598 if (!m_currentStacks.size()) return nullptr;
648 return m_currentStacks.back().get(); 599 return m_currentStacks.back().get();
649 } 600 }
650 601
651 void V8Debugger::compileDebuggerScript() { 602 void V8Debugger::compileDebuggerScript() {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
1011 962
1012 size_t stackSize = 963 size_t stackSize =
1013 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 964 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
1014 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 965 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
1015 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 966 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1016 967
1017 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 968 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
1018 } 969 }
1019 970
1020 } // namespace v8_inspector 971 } // namespace v8_inspector
OLDNEW
« src/debug/debug.cc ('K') | « src/inspector/v8-debugger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698