OLD | NEW |
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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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, &V8Debugger::v8DebugEventCallback, |
72 v8::External::New(m_isolate, this)); | 72 v8::External::New(m_isolate, this)); |
73 v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener, | 73 v8::debug::SetAsyncTaskListener(m_isolate, &V8Debugger::v8AsyncTaskListener, |
74 this); | 74 this); |
75 v8::debug::SetCompileEventListener(m_isolate, | 75 v8::debug::SetCompileEventListener(m_isolate, |
76 &V8Debugger::v8CompileEventListener, this); | 76 &V8Debugger::v8CompileEventListener, this); |
| 77 v8::debug::SetOutOfMemoryCallback(m_isolate, &V8Debugger::v8OOMCallback, |
| 78 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); | 93 v8::debug::SetDebugEventListener(m_isolate, nullptr); |
92 v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr); | 94 v8::debug::SetAsyncTaskListener(m_isolate, nullptr, nullptr); |
93 v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr); | 95 v8::debug::SetCompileEventListener(m_isolate, nullptr, nullptr); |
| 96 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr); |
| 97 m_isolate->RestoreOriginalHeapLimit(); |
94 } | 98 } |
95 | 99 |
96 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } | 100 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } |
97 | 101 |
98 void V8Debugger::getCompiledScripts( | 102 void V8Debugger::getCompiledScripts( |
99 int contextGroupId, | 103 int contextGroupId, |
100 std::vector<std::unique_ptr<V8DebuggerScript>>& result) { | 104 std::vector<std::unique_ptr<V8DebuggerScript>>& result) { |
101 v8::HandleScope scope(m_isolate); | 105 v8::HandleScope scope(m_isolate); |
102 v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate); | 106 v8::PersistentValueVector<v8::debug::Script> scripts(m_isolate); |
103 v8::debug::GetLoadedScripts(m_isolate, scripts); | 107 v8::debug::GetLoadedScripts(m_isolate, scripts); |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
476 v8::Local<v8::Value> hitBreakpointNumber = | 480 v8::Local<v8::Value> hitBreakpointNumber = |
477 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); | 481 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); |
478 DCHECK(hitBreakpointNumber->IsInt32()); | 482 DCHECK(hitBreakpointNumber->IsInt32()); |
479 breakpointIds.push_back(String16::fromInteger( | 483 breakpointIds.push_back(String16::fromInteger( |
480 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); | 484 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); |
481 } | 485 } |
482 } | 486 } |
483 | 487 |
484 m_pausedContext = pausedContext; | 488 m_pausedContext = pausedContext; |
485 m_executionState = executionState; | 489 m_executionState = executionState; |
486 V8DebuggerAgentImpl::SkipPauseRequest result = agent->didPause( | 490 V8DebuggerAgentImpl::SkipPauseRequest result = |
487 pausedContext, exception, breakpointIds, isPromiseRejection, isUncaught); | 491 agent->didPause(pausedContext, exception, breakpointIds, |
| 492 isPromiseRejection, isUncaught, m_scheduledOOMBreak); |
488 if (result == V8DebuggerAgentImpl::RequestNoSkip) { | 493 if (result == V8DebuggerAgentImpl::RequestNoSkip) { |
489 m_runningNestedMessageLoop = true; | 494 m_runningNestedMessageLoop = true; |
490 int groupId = m_inspector->contextGroupId(pausedContext); | 495 int groupId = m_inspector->contextGroupId(pausedContext); |
491 DCHECK(groupId); | 496 DCHECK(groupId); |
492 v8::Context::Scope scope(pausedContext); | 497 v8::Context::Scope scope(pausedContext); |
493 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); | 498 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); |
494 CHECK(!context.IsEmpty() && | 499 CHECK(!context.IsEmpty() && |
495 context != v8::debug::GetDebugContext(m_isolate)); | 500 context != v8::debug::GetDebugContext(m_isolate)); |
496 m_inspector->client()->runMessageLoopOnPause(groupId); | 501 m_inspector->client()->runMessageLoopOnPause(groupId); |
497 // The agent may have been removed in the nested loop. | 502 // The agent may have been removed in the nested loop. |
498 agent = m_inspector->enabledDebuggerAgentForGroup( | 503 agent = m_inspector->enabledDebuggerAgentForGroup( |
499 m_inspector->contextGroupId(pausedContext)); | 504 m_inspector->contextGroupId(pausedContext)); |
500 if (agent) agent->didContinue(); | 505 if (agent) agent->didContinue(); |
501 m_runningNestedMessageLoop = false; | 506 m_runningNestedMessageLoop = false; |
502 } | 507 } |
| 508 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit(); |
| 509 m_scheduledOOMBreak = false; |
503 m_pausedContext.Clear(); | 510 m_pausedContext.Clear(); |
504 m_executionState.Clear(); | 511 m_executionState.Clear(); |
505 | 512 |
506 if (result == V8DebuggerAgentImpl::RequestStepFrame) { | 513 if (result == V8DebuggerAgentImpl::RequestStepFrame) { |
507 v8::debug::PrepareStep(m_isolate, v8::debug::StepFrame); | 514 v8::debug::PrepareStep(m_isolate, v8::debug::StepFrame); |
508 } else if (result == V8DebuggerAgentImpl::RequestStepInto) { | 515 } else if (result == V8DebuggerAgentImpl::RequestStepInto) { |
509 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); | 516 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); |
510 } else if (result == V8DebuggerAgentImpl::RequestStepOut) { | 517 } else if (result == V8DebuggerAgentImpl::RequestStepOut) { |
511 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); | 518 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
512 } | 519 } |
513 } | 520 } |
514 | 521 |
| 522 void V8Debugger::v8OOMCallback(void* data) { |
| 523 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); |
| 524 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); |
| 525 thisPtr->m_scheduledOOMBreak = true; |
| 526 thisPtr->setPauseOnNextStatement(true); |
| 527 } |
| 528 |
515 void V8Debugger::v8DebugEventCallback( | 529 void V8Debugger::v8DebugEventCallback( |
516 const v8::debug::EventDetails& eventDetails) { | 530 const v8::debug::EventDetails& eventDetails) { |
517 V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData()); | 531 V8Debugger* thisPtr = toV8Debugger(eventDetails.GetCallbackData()); |
518 thisPtr->handleV8DebugEvent(eventDetails); | 532 thisPtr->handleV8DebugEvent(eventDetails); |
519 } | 533 } |
520 | 534 |
521 v8::Local<v8::Value> V8Debugger::callInternalGetterFunction( | 535 v8::Local<v8::Value> V8Debugger::callInternalGetterFunction( |
522 v8::Local<v8::Object> object, const char* functionName) { | 536 v8::Local<v8::Object> object, const char* functionName) { |
523 v8::MicrotasksScope microtasks(m_isolate, | 537 v8::MicrotasksScope microtasks(m_isolate, |
524 v8::MicrotasksScope::kDoNotRunMicrotasks); | 538 v8::MicrotasksScope::kDoNotRunMicrotasks); |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
997 | 1011 |
998 size_t stackSize = | 1012 size_t stackSize = |
999 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; | 1013 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; |
1000 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) | 1014 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) |
1001 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; | 1015 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; |
1002 | 1016 |
1003 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 1017 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
1004 } | 1018 } |
1005 | 1019 |
1006 } // namespace v8_inspector | 1020 } // namespace v8_inspector |
OLD | NEW |