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

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

Issue 2622253004: [inspector] introduced debug::SetBreakEventListener,SetExceptionEventListener (Closed)
Patch Set: ready for review 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
« no previous file with comments | « 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,
72 v8::External::New(m_isolate, this));
73 v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener, 71 v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener,
74 this); 72 this);
75 v8::debug::SetCompileEventListener(m_isolate, 73 v8::debug::SetCompileEventListener(m_isolate,
76 &V8Debugger::v8CompileEventListener, this); 74 &V8Debugger::v8CompileEventListener, this);
75 v8::debug::SetBreakEventListener(m_isolate, &V8Debugger::v8BreakEventListener,
76 this);
77 v8::debug::SetExceptionEventListener(
78 m_isolate, &V8Debugger::v8ExceptionEventListener, this);
77 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate)); 79 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate));
78 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException); 80 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException);
79 m_pauseOnExceptionsState = v8::debug::NoBreakOnException; 81 m_pauseOnExceptionsState = v8::debug::NoBreakOnException;
80 compileDebuggerScript(); 82 compileDebuggerScript();
81 } 83 }
82 84
83 void V8Debugger::disable() { 85 void V8Debugger::disable() {
84 if (--m_enableCount) return; 86 if (--m_enableCount) return;
85 DCHECK(enabled()); 87 DCHECK(enabled());
86 clearBreakpoints(); 88 clearBreakpoints();
87 m_debuggerScript.Reset(); 89 m_debuggerScript.Reset();
88 m_debuggerContext.Reset(); 90 m_debuggerContext.Reset();
89 allAsyncTasksCanceled(); 91 allAsyncTasksCanceled();
90 m_wasmTranslation.Clear(); 92 m_wasmTranslation.Clear();
91 v8::debug::SetDebugEventListener(m_isolate, nullptr);
92 v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr); 93 v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr);
93 v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr); 94 v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr);
95 v8::debug::SetBreakEventListener(m_isolate, nullptr, nullptr);
96 v8::debug::SetExceptionEventListener(m_isolate, nullptr, nullptr);
97 v8::debug::SetBreakEventListener(m_isolate, nullptr, nullptr);
jgruber 2017/01/17 08:55:11 Double copy-and-paste
98 v8::debug::SetExceptionEventListener(m_isolate, nullptr, nullptr);
94 } 99 }
95 100
96 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } 101 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
97 102
98 void V8Debugger::getCompiledScripts( 103 void V8Debugger::getCompiledScripts(
99 int contextGroupId, 104 int contextGroupId,
100 std::vector<std::unique_ptr<V8DebuggerScript>>& result) { 105 std::vector<std::unique_ptr<V8DebuggerScript>>& result) {
101 v8::HandleScope scope(m_isolate); 106 v8::HandleScope scope(m_isolate);
102 v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate); 107 v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate);
103 v8::debug::GetLoadedScripts(m_isolate, scripts); 108 v8::debug::GetLoadedScripts(m_isolate, scripts);
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
505 510
506 if (result == V8DebuggerAgentImpl::RequestStepFrame) { 511 if (result == V8DebuggerAgentImpl::RequestStepFrame) {
507 v8::debug::PrepareStep(m_isolate, v8::debug::StepFrame); 512 v8::debug::PrepareStep(m_isolate, v8::debug::StepFrame);
508 } else if (result == V8DebuggerAgentImpl::RequestStepInto) { 513 } else if (result == V8DebuggerAgentImpl::RequestStepInto) {
509 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); 514 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn);
510 } else if (result == V8DebuggerAgentImpl::RequestStepOut) { 515 } else if (result == V8DebuggerAgentImpl::RequestStepOut) {
511 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); 516 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
512 } 517 }
513 } 518 }
514 519
515 void V8Debugger::v8DebugEventCallback(
516 const v8::debug::EventDetails& eventDetails) {
517 V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData());
518 thisPtr->handleV8DebugEvent(eventDetails);
519 }
520
521 v8::Local<v8::Value> V8Debugger::callInternalGetterFunction(
522 v8::Local<v8::Object> object, const char* functionName) {
523 v8::MicrotasksScope microtasks(m_isolate,
524 v8::MicrotasksScope::kDoNotRunMicrotasks);
525 v8::Local<v8::Value> getterValue =
526 object
527 ->Get(m_isolate->GetCurrentContext(),
528 toV8StringInternalized(m_isolate, functionName))
529 .ToLocalChecked();
530 DCHECK(!getterValue.IsEmpty() && getterValue->IsFunction());
531 return v8::Local<v8::Function>::Cast(getterValue)
532 ->Call(m_isolate->GetCurrentContext(), object, 0, nullptr)
533 .ToLocalChecked();
534 }
535
536 void V8Debugger::handleV8DebugEvent(
537 const v8::debug::EventDetails& eventDetails) {
538 if (!enabled()) return;
539 v8::HandleScope scope(m_isolate);
540
541 v8::DebugEvent event = eventDetails.GetEvent();
542 if (event != v8::Break && event != v8::Exception) return;
543
544 v8::Local<v8::Context> eventContext = eventDetails.GetEventContext();
545 DCHECK(!eventContext.IsEmpty());
546 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
547 m_inspector->contextGroupId(eventContext));
548 if (!agent) return;
549
550 if (event == v8::Exception) {
551 v8::Local<v8::Context> context = debuggerContext();
552 v8::Local<v8::Object> eventData = eventDetails.GetEventData();
553 v8::Local<v8::Value> exception =
554 callInternalGetterFunction(eventData, "exception");
555 v8::Local<v8::Value> promise =
556 callInternalGetterFunction(eventData, "promise");
557 bool isPromiseRejection = !promise.IsEmpty() && promise->IsObject();
558 v8::Local<v8::Value> uncaught =
559 callInternalGetterFunction(eventData, "uncaught");
560 bool isUncaught = uncaught->BooleanValue(context).FromJust();
561 handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
562 exception, v8::Local<v8::Array>(), isPromiseRejection,
563 isUncaught);
564 } else if (event == v8::Break) {
565 v8::Local<v8::Value> argv[] = {eventDetails.GetEventData()};
566 v8::Local<v8::Value> hitBreakpoints;
567 if (!callDebuggerMethod("getBreakpointNumbers", 1, argv)
568 .ToLocal(&hitBreakpoints))
569 return;
570 DCHECK(hitBreakpoints->IsArray());
571 handleProgramBreak(eventContext, eventDetails.GetExecutionState(),
572 v8::Local<v8::Value>(), hitBreakpoints.As<v8::Array>());
573 }
574 }
575
576 void V8Debugger::v8CompileEventListener(v8::Local<v8::debug::Script> script, 520 void V8Debugger::v8CompileEventListener(v8::Local<v8::debug::Script> script,
577 bool has_compile_error, void* data) { 521 bool has_compile_error, void* data) {
578 V8Debugger* debugger = static_cast<V8Debugger*>(data); 522 V8Debugger* debugger = static_cast<V8Debugger*>(data);
579 v8::Local<v8::Value> contextData; 523 v8::Local<v8::Value> contextData;
580 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) { 524 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
581 return; 525 return;
582 } 526 }
583 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value()); 527 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
584 V8DebuggerAgentImpl* agent = 528 V8DebuggerAgentImpl* agent =
585 debugger->m_inspector->enabledDebuggerAgentForGroup(contextId); 529 debugger->m_inspector->enabledDebuggerAgentForGroup(contextId);
586 if (!agent) return; 530 if (!agent) return;
587 if (script->IsWasm()) { 531 if (script->IsWasm()) {
588 debugger->m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), 532 debugger->m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(),
589 agent); 533 agent);
590 } else if (debugger->m_ignoreScriptParsedEventsCounter == 0) { 534 } else if (debugger->m_ignoreScriptParsedEventsCounter == 0) {
591 agent->didParseSource( 535 agent->didParseSource(
592 V8DebuggerScript::Create(debugger->m_isolate, script, inLiveEditScope), 536 V8DebuggerScript::Create(debugger->m_isolate, script, inLiveEditScope),
593 !has_compile_error); 537 !has_compile_error);
594 } 538 }
595 } 539 }
596 540
541 void V8Debugger::v8BreakEventListener(v8::Local<v8::Context> pausedContext,
542 v8::Local<v8::Object> execState,
543 v8::Local<v8::Value> breakPointsHit,
544 void* data) {
545 V8Debugger* debugger = static_cast<V8Debugger*>(data);
546 v8::Local<v8::Value> argv[] = {breakPointsHit};
547 v8::Local<v8::Value> hitBreakpoints;
548 if (!debugger->callDebuggerMethod("getBreakpointNumbers", 1, argv)
549 .ToLocal(&hitBreakpoints)) {
550 return;
551 }
552 DCHECK(hitBreakpoints->IsArray());
553 debugger->handleProgramBreak(pausedContext, execState, v8::Local<v8::Value>(),
554 hitBreakpoints.As<v8::Array>());
555 }
556
557 void V8Debugger::v8ExceptionEventListener(v8::Local<v8::Context> pausedContext,
558 v8::Local<v8::Object> execState,
559 v8::Local<v8::Value> exception,
560 bool isPromiseRejection,
561 bool isUncaught, void* data) {
562 V8Debugger* debugger = static_cast<V8Debugger*>(data);
563 debugger->handleProgramBreak(pausedContext, execState, exception,
564 v8::Local<v8::Array>(), isPromiseRejection,
565 isUncaught);
566 }
567
597 void V8Debugger::v8AsyncTaskListener(v8::debug::PromiseDebugActionType type, 568 void V8Debugger::v8AsyncTaskListener(v8::debug::PromiseDebugActionType type,
598 int id, void* data) { 569 int id, void* data) {
599 V8Debugger* debugger = static_cast<V8Debugger*>(data); 570 V8Debugger* debugger = static_cast<V8Debugger*>(data);
600 if (!debugger->m_maxAsyncCallStackDepth) return; 571 if (!debugger->m_maxAsyncCallStackDepth) return;
601 // Async task events from Promises are given misaligned pointers to prevent 572 // Async task events from Promises are given misaligned pointers to prevent
602 // from overlapping with other Blink task identifiers. There is a single 573 // from overlapping with other Blink task identifiers. There is a single
603 // namespace of such ids, managed by src/js/promise.js. 574 // namespace of such ids, managed by src/js/promise.js.
604 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 575 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
605 switch (type) { 576 switch (type) {
606 case v8::debug::kDebugEnqueueAsyncFunction: 577 case v8::debug::kDebugEnqueueAsyncFunction:
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 966
996 size_t stackSize = 967 size_t stackSize =
997 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 968 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
998 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 969 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
999 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 970 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1000 971
1001 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 972 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
1002 } 973 }
1003 974
1004 } // namespace v8_inspector 975 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698