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

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

Issue 2633803002: [inspector] implemented blackboxing inside v8 (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
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('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 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 12 matching lines...) Expand all
23 23
24 // Based on DevTools frontend measurement, with asyncCallStackDepth = 4, 24 // Based on DevTools frontend measurement, with asyncCallStackDepth = 4,
25 // average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb 25 // average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb
26 // for async stacks. 26 // for async stacks.
27 static const int kMaxAsyncTaskStacks = 128 * 1024; 27 static const int kMaxAsyncTaskStacks = 128 * 1024;
28 28
29 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) { 29 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
30 return value ? v8::True(isolate) : v8::False(isolate); 30 return value ? v8::True(isolate) : v8::False(isolate);
31 } 31 }
32 32
33 V8DebuggerAgentImpl* agentForScript(V8InspectorImpl* inspector,
34 v8::Local<v8::debug::Script> script) {
35 v8::Local<v8::Value> contextData;
36 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
37 return nullptr;
38 }
39 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
40 int contextGroupId = inspector->contextGroupId(contextId);
41 if (!contextGroupId) return nullptr;
42 return inspector->enabledDebuggerAgentForGroup(contextGroupId);
43 }
44
33 } // namespace 45 } // namespace
34 46
35 static bool inLiveEditScope = false; 47 static bool inLiveEditScope = false;
36 48
37 v8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod( 49 v8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod(
38 const char* functionName, int argc, v8::Local<v8::Value> argv[]) { 50 const char* functionName, int argc, v8::Local<v8::Value> argv[]) {
39 v8::MicrotasksScope microtasks(m_isolate, 51 v8::MicrotasksScope microtasks(m_isolate,
40 v8::MicrotasksScope::kDoNotRunMicrotasks); 52 v8::MicrotasksScope::kDoNotRunMicrotasks);
41 DCHECK(m_isolate->InContext()); 53 DCHECK(m_isolate->InContext());
42 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); 54 v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
(...skipping 18 matching lines...) Expand all
61 m_maxAsyncCallStackDepth(0), 73 m_maxAsyncCallStackDepth(0),
62 m_pauseOnExceptionsState(v8::debug::NoBreakOnException), 74 m_pauseOnExceptionsState(v8::debug::NoBreakOnException),
63 m_wasmTranslation(isolate) {} 75 m_wasmTranslation(isolate) {}
64 76
65 V8Debugger::~V8Debugger() {} 77 V8Debugger::~V8Debugger() {}
66 78
67 void V8Debugger::enable() { 79 void V8Debugger::enable() {
68 if (m_enableCount++) return; 80 if (m_enableCount++) return;
69 DCHECK(!enabled()); 81 DCHECK(!enabled());
70 v8::HandleScope scope(m_isolate); 82 v8::HandleScope scope(m_isolate);
71 v8::debug::SetDebugEventListener(m_isolate, this); 83 v8::debug::SetDebugDelegate(m_isolate, this);
72 v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback, 84 v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback,
73 this); 85 this);
74 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate)); 86 m_debuggerContext.Reset(m_isolate, v8::debug::GetDebugContext(m_isolate));
75 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException); 87 v8::debug::ChangeBreakOnException(m_isolate, v8::debug::NoBreakOnException);
76 m_pauseOnExceptionsState = v8::debug::NoBreakOnException; 88 m_pauseOnExceptionsState = v8::debug::NoBreakOnException;
77 compileDebuggerScript(); 89 compileDebuggerScript();
78 } 90 }
79 91
80 void V8Debugger::disable() { 92 void V8Debugger::disable() {
81 if (--m_enableCount) return; 93 if (--m_enableCount) return;
82 DCHECK(enabled()); 94 DCHECK(enabled());
83 clearBreakpoints(); 95 clearBreakpoints();
84 m_debuggerScript.Reset(); 96 m_debuggerScript.Reset();
85 m_debuggerContext.Reset(); 97 m_debuggerContext.Reset();
86 allAsyncTasksCanceled(); 98 allAsyncTasksCanceled();
87 m_wasmTranslation.Clear(); 99 m_wasmTranslation.Clear();
88 v8::debug::SetDebugEventListener(m_isolate, nullptr); 100 v8::debug::SetDebugDelegate(m_isolate, nullptr);
89 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr); 101 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
90 m_isolate->RestoreOriginalHeapLimit(); 102 m_isolate->RestoreOriginalHeapLimit();
91 } 103 }
92 104
93 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } 105 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
94 106
95 void V8Debugger::getCompiledScripts( 107 void V8Debugger::getCompiledScripts(
96 int contextGroupId, 108 int contextGroupId,
97 std::vector<std::unique_ptr<V8DebuggerScript>>& result) { 109 std::vector<std::unique_ptr<V8DebuggerScript>>& result) {
98 v8::HandleScope scope(m_isolate); 110 v8::HandleScope scope(m_isolate);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 void V8Debugger::setPauseOnNextStatement(bool pause) { 248 void V8Debugger::setPauseOnNextStatement(bool pause) {
237 if (m_runningNestedMessageLoop) return; 249 if (m_runningNestedMessageLoop) return;
238 if (pause) 250 if (pause)
239 v8::debug::DebugBreak(m_isolate); 251 v8::debug::DebugBreak(m_isolate);
240 else 252 else
241 v8::debug::CancelDebugBreak(m_isolate); 253 v8::debug::CancelDebugBreak(m_isolate);
242 } 254 }
243 255
244 bool V8Debugger::canBreakProgram() { 256 bool V8Debugger::canBreakProgram() {
245 if (!m_breakpointsActivated) return false; 257 if (!m_breakpointsActivated) return false;
246 return m_isolate->InContext(); 258 return v8::debug::HasNonBlackboxedFrameOnStack(m_isolate);
247 } 259 }
248 260
249 void V8Debugger::breakProgram() { 261 void V8Debugger::breakProgram() {
250 if (isPaused()) { 262 if (isPaused()) {
251 DCHECK(!m_runningNestedMessageLoop); 263 DCHECK(!m_runningNestedMessageLoop);
252 v8::Local<v8::Value> exception; 264 v8::Local<v8::Value> exception;
253 v8::Local<v8::Array> hitBreakpoints; 265 v8::Local<v8::Array> hitBreakpoints;
254 handleProgramBreak(m_pausedContext, m_executionState, exception, 266 handleProgramBreak(m_pausedContext, m_executionState, exception,
255 hitBreakpoints); 267 hitBreakpoints);
256 return; 268 return;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 continueProgram(); 301 continueProgram();
290 } 302 }
291 303
292 void V8Debugger::stepOutOfFunction() { 304 void V8Debugger::stepOutOfFunction() {
293 DCHECK(isPaused()); 305 DCHECK(isPaused());
294 DCHECK(!m_executionState.IsEmpty()); 306 DCHECK(!m_executionState.IsEmpty());
295 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); 307 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
296 continueProgram(); 308 continueProgram();
297 } 309 }
298 310
299 void V8Debugger::clearStepping() {
300 DCHECK(enabled());
301 v8::debug::ClearStepping(m_isolate);
302 }
303
304 Response V8Debugger::setScriptSource( 311 Response V8Debugger::setScriptSource(
305 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, 312 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun,
306 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, 313 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails,
307 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged, 314 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged,
308 bool* compileError) { 315 bool* compileError) {
309 class EnableLiveEditScope { 316 class EnableLiveEditScope {
310 public: 317 public:
311 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) { 318 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) {
312 v8::debug::SetLiveEditEnabled(m_isolate, true); 319 v8::debug::SetLiveEditEnabled(m_isolate, true);
313 inLiveEditScope = true; 320 inLiveEditScope = true;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 v8::Local<v8::Value> hitBreakpointNumber = 480 v8::Local<v8::Value> hitBreakpointNumber =
474 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); 481 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked();
475 DCHECK(hitBreakpointNumber->IsInt32()); 482 DCHECK(hitBreakpointNumber->IsInt32());
476 breakpointIds.push_back(String16::fromInteger( 483 breakpointIds.push_back(String16::fromInteger(
477 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); 484 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust()));
478 } 485 }
479 } 486 }
480 487
481 m_pausedContext = pausedContext; 488 m_pausedContext = pausedContext;
482 m_executionState = executionState; 489 m_executionState = executionState;
483 V8DebuggerAgentImpl::SkipPauseRequest result = 490 bool shouldPause =
484 agent->didPause(pausedContext, exception, breakpointIds, 491 agent->didPause(pausedContext, exception, breakpointIds,
485 isPromiseRejection, isUncaught, m_scheduledOOMBreak); 492 isPromiseRejection, isUncaught, m_scheduledOOMBreak);
486 if (result == V8DebuggerAgentImpl::RequestNoSkip) { 493 if (shouldPause) {
487 m_runningNestedMessageLoop = true; 494 m_runningNestedMessageLoop = true;
488 int groupId = m_inspector->contextGroupId(pausedContext); 495 int groupId = m_inspector->contextGroupId(pausedContext);
489 DCHECK(groupId); 496 DCHECK(groupId);
490 v8::Context::Scope scope(pausedContext); 497 v8::Context::Scope scope(pausedContext);
491 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); 498 v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
492 CHECK(!context.IsEmpty() && 499 CHECK(!context.IsEmpty() &&
493 context != v8::debug::GetDebugContext(m_isolate)); 500 context != v8::debug::GetDebugContext(m_isolate));
494 m_inspector->client()->runMessageLoopOnPause(groupId); 501 m_inspector->client()->runMessageLoopOnPause(groupId);
495 // The agent may have been removed in the nested loop. 502 // The agent may have been removed in the nested loop.
496 agent = m_inspector->enabledDebuggerAgentForGroup( 503 agent = m_inspector->enabledDebuggerAgentForGroup(
497 m_inspector->contextGroupId(pausedContext)); 504 m_inspector->contextGroupId(pausedContext));
498 if (agent) agent->didContinue(); 505 if (agent) agent->didContinue();
499 m_runningNestedMessageLoop = false; 506 m_runningNestedMessageLoop = false;
500 } 507 }
501 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit(); 508 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
502 m_scheduledOOMBreak = false; 509 m_scheduledOOMBreak = false;
503 m_pausedContext.Clear(); 510 m_pausedContext.Clear();
504 m_executionState.Clear(); 511 m_executionState.Clear();
505
506 if (result == V8DebuggerAgentImpl::RequestStepFrame) {
507 v8::debug::PrepareStep(m_isolate, v8::debug::StepFrame);
508 } else if (result == V8DebuggerAgentImpl::RequestStepInto) {
509 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn);
510 } else if (result == V8DebuggerAgentImpl::RequestStepOut) {
511 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut);
512 }
513 } 512 }
514 513
515 void V8Debugger::v8OOMCallback(void* data) { 514 void V8Debugger::v8OOMCallback(void* data) {
516 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); 515 V8Debugger* thisPtr = static_cast<V8Debugger*>(data);
517 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); 516 thisPtr->m_isolate->IncreaseHeapLimitForDebugging();
518 thisPtr->m_scheduledOOMBreak = true; 517 thisPtr->m_scheduledOOMBreak = true;
519 thisPtr->setPauseOnNextStatement(true); 518 thisPtr->setPauseOnNextStatement(true);
520 } 519 }
521 520
522 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, 521 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
523 bool has_compile_error) { 522 bool has_compile_error) {
524 v8::Local<v8::Value> contextData; 523 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
525 if (!script->ContextData().ToLocal(&contextData) || !contextData->IsInt32()) {
526 return;
527 }
528 int contextId = static_cast<int>(contextData.As<v8::Int32>()->Value());
529 int contextGroupId = m_inspector->contextGroupId(contextId);
530 if (!contextGroupId) return;
531 V8DebuggerAgentImpl* agent =
532 m_inspector->enabledDebuggerAgentForGroup(contextGroupId);
533 if (!agent) return; 524 if (!agent) return;
534 if (script->IsWasm()) { 525 if (script->IsWasm()) {
535 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); 526 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent);
536 } else if (m_ignoreScriptParsedEventsCounter == 0) { 527 } else if (m_ignoreScriptParsedEventsCounter == 0) {
537 agent->didParseSource( 528 agent->didParseSource(
538 V8DebuggerScript::Create(m_isolate, script, inLiveEditScope), 529 V8DebuggerScript::Create(m_isolate, script, inLiveEditScope),
539 !has_compile_error); 530 !has_compile_error);
540 } 531 }
541 } 532 }
542 533
(...skipping 12 matching lines...) Expand all
555 } 546 }
556 547
557 void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext, 548 void V8Debugger::ExceptionThrown(v8::Local<v8::Context> pausedContext,
558 v8::Local<v8::Object> execState, 549 v8::Local<v8::Object> execState,
559 v8::Local<v8::Value> exception, 550 v8::Local<v8::Value> exception,
560 bool isPromiseRejection, bool isUncaught) { 551 bool isPromiseRejection, bool isUncaught) {
561 handleProgramBreak(pausedContext, execState, exception, 552 handleProgramBreak(pausedContext, execState, exception,
562 v8::Local<v8::Array>(), isPromiseRejection, isUncaught); 553 v8::Local<v8::Array>(), isPromiseRejection, isUncaught);
563 } 554 }
564 555
556 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
557 const v8::debug::Location& start,
558 const v8::debug::Location& end) {
559 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
560 if (!agent) return false;
561 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start,
562 end);
563 }
564
565 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, 565 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type,
566 int id) { 566 int id) {
567 if (!m_maxAsyncCallStackDepth) return; 567 if (!m_maxAsyncCallStackDepth) return;
568 // Async task events from Promises are given misaligned pointers to prevent 568 // Async task events from Promises are given misaligned pointers to prevent
569 // from overlapping with other Blink task identifiers. There is a single 569 // from overlapping with other Blink task identifiers. There is a single
570 // namespace of such ids, managed by src/js/promise.js. 570 // namespace of such ids, managed by src/js/promise.js.
571 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 571 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
572 switch (type) { 572 switch (type) {
573 case v8::debug::kDebugEnqueueAsyncFunction: 573 case v8::debug::kDebugEnqueueAsyncFunction:
574 asyncTaskScheduled("async function", ptr, true); 574 asyncTaskScheduled("async function", ptr, true);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 962
963 size_t stackSize = 963 size_t stackSize =
964 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 964 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
965 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 965 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
966 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 966 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
967 967
968 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 968 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
969 } 969 }
970 970
971 } // namespace v8_inspector 971 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698