| 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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 v8::TryCatch try_catch(m_isolate); | 154 v8::TryCatch try_catch(m_isolate); |
| 155 return function->Call(context, debuggerScript, argc, argv); | 155 return function->Call(context, debuggerScript, argc, argv); |
| 156 } | 156 } |
| 157 return function->Call(context, debuggerScript, argc, argv); | 157 return function->Call(context, debuggerScript, argc, argv); |
| 158 } | 158 } |
| 159 | 159 |
| 160 V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) | 160 V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) |
| 161 : m_isolate(isolate), | 161 : m_isolate(isolate), |
| 162 m_inspector(inspector), | 162 m_inspector(inspector), |
| 163 m_enableCount(0), | 163 m_enableCount(0), |
| 164 m_breakpointsActivated(true), | |
| 165 m_ignoreScriptParsedEventsCounter(0), | 164 m_ignoreScriptParsedEventsCounter(0), |
| 166 m_maxAsyncCallStacks(kMaxAsyncTaskStacks), | 165 m_maxAsyncCallStacks(kMaxAsyncTaskStacks), |
| 167 m_maxAsyncCallStackDepth(0), | 166 m_maxAsyncCallStackDepth(0), |
| 168 m_pauseOnExceptionsState(v8::debug::NoBreakOnException), | 167 m_pauseOnExceptionsState(v8::debug::NoBreakOnException), |
| 169 m_wasmTranslation(isolate) {} | 168 m_wasmTranslation(isolate) {} |
| 170 | 169 |
| 171 V8Debugger::~V8Debugger() {} | 170 V8Debugger::~V8Debugger() {} |
| 172 | 171 |
| 173 void V8Debugger::enable() { | 172 void V8Debugger::enable() { |
| 174 if (m_enableCount++) return; | 173 if (m_enableCount++) return; |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 v8::Local<v8::Context> context = debuggerContext(); | 301 v8::Local<v8::Context> context = debuggerContext(); |
| 303 v8::Context::Scope contextScope(context); | 302 v8::Context::Scope contextScope(context); |
| 304 | 303 |
| 305 v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast( | 304 v8::Local<v8::Function> clearBreakpoints = v8::Local<v8::Function>::Cast( |
| 306 m_debuggerScript.Get(m_isolate) | 305 m_debuggerScript.Get(m_isolate) |
| 307 ->Get(context, toV8StringInternalized(m_isolate, "clearBreakpoints")) | 306 ->Get(context, toV8StringInternalized(m_isolate, "clearBreakpoints")) |
| 308 .ToLocalChecked()); | 307 .ToLocalChecked()); |
| 309 v8::debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); | 308 v8::debug::Call(debuggerContext(), clearBreakpoints).ToLocalChecked(); |
| 310 } | 309 } |
| 311 | 310 |
| 312 void V8Debugger::setBreakpointsActivated(bool activated) { | 311 void V8Debugger::setBreakpointsActive(bool active) { |
| 313 if (!enabled()) { | 312 if (!enabled()) { |
| 314 UNREACHABLE(); | 313 UNREACHABLE(); |
| 315 return; | 314 return; |
| 316 } | 315 } |
| 317 v8::debug::SetBreakPointsActive(m_isolate, activated); | 316 m_breakpointsActiveCount += active ? 1 : -1; |
| 318 m_breakpointsActivated = activated; | 317 v8::debug::SetBreakPointsActive(m_isolate, m_breakpointsActiveCount); |
| 319 } | 318 } |
| 320 | 319 |
| 321 v8::debug::ExceptionBreakState V8Debugger::getPauseOnExceptionsState() { | 320 v8::debug::ExceptionBreakState V8Debugger::getPauseOnExceptionsState() { |
| 322 DCHECK(enabled()); | 321 DCHECK(enabled()); |
| 323 return m_pauseOnExceptionsState; | 322 return m_pauseOnExceptionsState; |
| 324 } | 323 } |
| 325 | 324 |
| 326 void V8Debugger::setPauseOnExceptionsState( | 325 void V8Debugger::setPauseOnExceptionsState( |
| 327 v8::debug::ExceptionBreakState pauseOnExceptionsState) { | 326 v8::debug::ExceptionBreakState pauseOnExceptionsState) { |
| 328 DCHECK(enabled()); | 327 DCHECK(enabled()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 340 } | 339 } |
| 341 m_targetContextGroupId = targetContextGroupId; | 340 m_targetContextGroupId = targetContextGroupId; |
| 342 m_breakRequested = pause; | 341 m_breakRequested = pause; |
| 343 if (pause) | 342 if (pause) |
| 344 v8::debug::DebugBreak(m_isolate); | 343 v8::debug::DebugBreak(m_isolate); |
| 345 else | 344 else |
| 346 v8::debug::CancelDebugBreak(m_isolate); | 345 v8::debug::CancelDebugBreak(m_isolate); |
| 347 } | 346 } |
| 348 | 347 |
| 349 bool V8Debugger::canBreakProgram() { | 348 bool V8Debugger::canBreakProgram() { |
| 350 if (!m_breakpointsActivated) return false; | |
| 351 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); | 349 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); |
| 352 } | 350 } |
| 353 | 351 |
| 354 void V8Debugger::breakProgram(int targetContextGroupId) { | 352 void V8Debugger::breakProgram(int targetContextGroupId) { |
| 353 DCHECK(canBreakProgram()); |
| 355 // Don't allow nested breaks. | 354 // Don't allow nested breaks. |
| 356 if (isPaused()) return; | 355 if (isPaused()) return; |
| 357 if (!canBreakProgram()) return; | |
| 358 DCHECK(targetContextGroupId); | 356 DCHECK(targetContextGroupId); |
| 359 m_targetContextGroupId = targetContextGroupId; | 357 m_targetContextGroupId = targetContextGroupId; |
| 360 v8::debug::BreakRightNow(m_isolate); | 358 v8::debug::BreakRightNow(m_isolate); |
| 361 } | 359 } |
| 362 | 360 |
| 363 void V8Debugger::continueProgram(int targetContextGroupId) { | 361 void V8Debugger::continueProgram(int targetContextGroupId) { |
| 364 if (m_pausedContextGroupId != targetContextGroupId) return; | 362 if (m_pausedContextGroupId != targetContextGroupId) return; |
| 365 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); | 363 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); |
| 366 m_pausedContext.Clear(); | 364 m_pausedContext.Clear(); |
| 367 m_executionState.Clear(); | 365 m_executionState.Clear(); |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 m_targetContextGroupId = 0; | 607 m_targetContextGroupId = 0; |
| 610 if (m_stepIntoAsyncCallback) { | 608 if (m_stepIntoAsyncCallback) { |
| 611 m_stepIntoAsyncCallback->sendFailure( | 609 m_stepIntoAsyncCallback->sendFailure( |
| 612 Response::Error("No async tasks were scheduled before pause.")); | 610 Response::Error("No async tasks were scheduled before pause.")); |
| 613 m_stepIntoAsyncCallback.reset(); | 611 m_stepIntoAsyncCallback.reset(); |
| 614 } | 612 } |
| 615 m_breakRequested = false; | 613 m_breakRequested = false; |
| 616 | 614 |
| 617 bool scheduledOOMBreak = m_scheduledOOMBreak; | 615 bool scheduledOOMBreak = m_scheduledOOMBreak; |
| 618 bool scheduledAssertBreak = m_scheduledAssertBreak; | 616 bool scheduledAssertBreak = m_scheduledAssertBreak; |
| 619 auto agentCheck = [&scheduledOOMBreak](V8DebuggerAgentImpl* agent) { | |
| 620 return agent->enabled() && (scheduledOOMBreak || !agent->skipAllPauses()); | |
| 621 }; | |
| 622 | |
| 623 bool hasAgents = false; | 617 bool hasAgents = false; |
| 624 m_inspector->forEachSession( | 618 m_inspector->forEachSession( |
| 625 contextGroupId, | 619 contextGroupId, |
| 626 [&agentCheck, &hasAgents](V8InspectorSessionImpl* session) { | 620 [&scheduledOOMBreak, &hasAgents](V8InspectorSessionImpl* session) { |
| 627 if (agentCheck(session->debuggerAgent())) hasAgents = true; | 621 if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) |
| 622 hasAgents = true; |
| 628 }); | 623 }); |
| 629 if (!hasAgents) return; | 624 if (!hasAgents) return; |
| 630 | 625 |
| 631 std::vector<String16> breakpointIds; | 626 std::vector<String16> breakpointIds; |
| 632 if (!hitBreakpointNumbers.IsEmpty()) { | 627 if (!hitBreakpointNumbers.IsEmpty()) { |
| 633 breakpointIds.reserve(hitBreakpointNumbers->Length()); | 628 breakpointIds.reserve(hitBreakpointNumbers->Length()); |
| 634 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { | 629 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { |
| 635 v8::Local<v8::Value> hitBreakpointNumber = | 630 v8::Local<v8::Value> hitBreakpointNumber = |
| 636 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); | 631 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); |
| 637 DCHECK(hitBreakpointNumber->IsInt32()); | 632 DCHECK(hitBreakpointNumber->IsInt32()); |
| 638 breakpointIds.push_back(String16::fromInteger( | 633 breakpointIds.push_back(String16::fromInteger( |
| 639 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); | 634 hitBreakpointNumber->Int32Value(debuggerContext()).FromJust())); |
| 640 } | 635 } |
| 641 if (breakpointIds.size() == 1 && | 636 if (breakpointIds.size() == 1 && |
| 642 breakpointIds[0] == m_continueToLocationBreakpointId) { | 637 breakpointIds[0] == m_continueToLocationBreakpointId) { |
| 643 v8::Context::Scope contextScope(pausedContext); | 638 v8::Context::Scope contextScope(pausedContext); |
| 644 if (!shouldContinueToCurrentLocation()) return; | 639 if (!shouldContinueToCurrentLocation()) return; |
| 645 } | 640 } |
| 646 } | 641 } |
| 647 clearContinueToLocation(); | 642 clearContinueToLocation(); |
| 648 | 643 |
| 649 DCHECK(contextGroupId); | 644 DCHECK(contextGroupId); |
| 650 m_pausedContext = pausedContext; | 645 m_pausedContext = pausedContext; |
| 651 m_executionState = executionState; | 646 m_executionState = executionState; |
| 652 m_pausedContextGroupId = contextGroupId; | 647 m_pausedContextGroupId = contextGroupId; |
| 653 | 648 |
| 654 m_inspector->forEachSession( | 649 m_inspector->forEachSession( |
| 655 contextGroupId, [&agentCheck, &pausedContext, &exception, &breakpointIds, | 650 contextGroupId, [&pausedContext, &exception, &breakpointIds, |
| 656 &isPromiseRejection, &isUncaught, &scheduledOOMBreak, | 651 &isPromiseRejection, &isUncaught, &scheduledOOMBreak, |
| 657 &scheduledAssertBreak](V8InspectorSessionImpl* session) { | 652 &scheduledAssertBreak](V8InspectorSessionImpl* session) { |
| 658 if (agentCheck(session->debuggerAgent())) { | 653 if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) { |
| 659 session->debuggerAgent()->didPause( | 654 session->debuggerAgent()->didPause( |
| 660 InspectedContext::contextId(pausedContext), exception, | 655 InspectedContext::contextId(pausedContext), exception, |
| 661 breakpointIds, isPromiseRejection, isUncaught, scheduledOOMBreak, | 656 breakpointIds, isPromiseRejection, isUncaught, scheduledOOMBreak, |
| 662 scheduledAssertBreak); | 657 scheduledAssertBreak); |
| 663 } | 658 } |
| 664 }); | 659 }); |
| 665 { | 660 { |
| 666 v8::Context::Scope scope(pausedContext); | 661 v8::Context::Scope scope(pausedContext); |
| 667 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); | 662 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); |
| 668 CHECK(!context.IsEmpty() && | 663 CHECK(!context.IsEmpty() && |
| (...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); | 1208 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); |
| 1214 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); | 1209 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); |
| 1215 fprintf(stdout, "Created async tasks: %zu\n", | 1210 fprintf(stdout, "Created async tasks: %zu\n", |
| 1216 m_asyncTaskCreationStacks.size()); | 1211 m_asyncTaskCreationStacks.size()); |
| 1217 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); | 1212 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); |
| 1218 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); | 1213 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); |
| 1219 fprintf(stdout, "\n"); | 1214 fprintf(stdout, "\n"); |
| 1220 } | 1215 } |
| 1221 | 1216 |
| 1222 } // namespace v8_inspector | 1217 } // namespace v8_inspector |
| OLD | NEW |