| 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 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 } | 321 } |
| 322 | 322 |
| 323 void V8Debugger::setPauseOnExceptionsState( | 323 void V8Debugger::setPauseOnExceptionsState( |
| 324 v8::debug::ExceptionBreakState pauseOnExceptionsState) { | 324 v8::debug::ExceptionBreakState pauseOnExceptionsState) { |
| 325 DCHECK(enabled()); | 325 DCHECK(enabled()); |
| 326 if (m_pauseOnExceptionsState == pauseOnExceptionsState) return; | 326 if (m_pauseOnExceptionsState == pauseOnExceptionsState) return; |
| 327 v8::debug::ChangeBreakOnException(m_isolate, pauseOnExceptionsState); | 327 v8::debug::ChangeBreakOnException(m_isolate, pauseOnExceptionsState); |
| 328 m_pauseOnExceptionsState = pauseOnExceptionsState; | 328 m_pauseOnExceptionsState = pauseOnExceptionsState; |
| 329 } | 329 } |
| 330 | 330 |
| 331 void V8Debugger::setPauseOnNextStatement(bool pause) { | 331 void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) { |
| 332 if (isPaused()) return; | 332 if (isPaused()) return; |
| 333 DCHECK(targetContextGroupId); |
| 334 if (!pause && m_targetContextGroupId && |
| 335 m_targetContextGroupId != targetContextGroupId) { |
| 336 return; |
| 337 } |
| 338 m_targetContextGroupId = targetContextGroupId; |
| 333 if (pause) | 339 if (pause) |
| 334 v8::debug::DebugBreak(m_isolate); | 340 v8::debug::DebugBreak(m_isolate); |
| 335 else | 341 else |
| 336 v8::debug::CancelDebugBreak(m_isolate); | 342 v8::debug::CancelDebugBreak(m_isolate); |
| 337 } | 343 } |
| 338 | 344 |
| 339 bool V8Debugger::canBreakProgram() { | 345 bool V8Debugger::canBreakProgram() { |
| 340 if (!m_breakpointsActivated) return false; | 346 if (!m_breakpointsActivated) return false; |
| 341 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); | 347 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); |
| 342 } | 348 } |
| 343 | 349 |
| 344 void V8Debugger::breakProgram() { | 350 void V8Debugger::breakProgram() { |
| 345 // Don't allow nested breaks. | 351 // Don't allow nested breaks. |
| 346 if (isPaused()) return; | 352 if (isPaused()) return; |
| 347 if (!canBreakProgram()) return; | 353 if (!canBreakProgram()) return; |
| 348 v8::debug::BreakRightNow(m_isolate); | 354 v8::debug::BreakRightNow(m_isolate); |
| 349 } | 355 } |
| 350 | 356 |
| 351 void V8Debugger::continueProgram() { | 357 void V8Debugger::continueProgram() { |
| 352 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); | 358 if (isPaused()) m_inspector->client()->quitMessageLoopOnPause(); |
| 353 m_pausedContext.Clear(); | 359 m_pausedContext.Clear(); |
| 354 m_executionState.Clear(); | 360 m_executionState.Clear(); |
| 355 } | 361 } |
| 356 | 362 |
| 357 void V8Debugger::stepIntoStatement() { | 363 void V8Debugger::stepIntoStatement(int targetContextGroupId) { |
| 358 DCHECK(isPaused()); | 364 DCHECK(isPaused()); |
| 359 DCHECK(!m_executionState.IsEmpty()); | 365 DCHECK(!m_executionState.IsEmpty()); |
| 366 DCHECK(targetContextGroupId); |
| 367 m_targetContextGroupId = targetContextGroupId; |
| 360 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); | 368 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); |
| 361 continueProgram(); | 369 continueProgram(); |
| 362 } | 370 } |
| 363 | 371 |
| 364 void V8Debugger::stepOverStatement() { | 372 void V8Debugger::stepOverStatement(int targetContextGroupId) { |
| 365 DCHECK(isPaused()); | 373 DCHECK(isPaused()); |
| 366 DCHECK(!m_executionState.IsEmpty()); | 374 DCHECK(!m_executionState.IsEmpty()); |
| 375 DCHECK(targetContextGroupId); |
| 376 m_targetContextGroupId = targetContextGroupId; |
| 367 v8::debug::PrepareStep(m_isolate, v8::debug::StepNext); | 377 v8::debug::PrepareStep(m_isolate, v8::debug::StepNext); |
| 368 continueProgram(); | 378 continueProgram(); |
| 369 } | 379 } |
| 370 | 380 |
| 371 void V8Debugger::stepOutOfFunction() { | 381 void V8Debugger::stepOutOfFunction(int targetContextGroupId) { |
| 372 DCHECK(isPaused()); | 382 DCHECK(isPaused()); |
| 373 DCHECK(!m_executionState.IsEmpty()); | 383 DCHECK(!m_executionState.IsEmpty()); |
| 384 DCHECK(targetContextGroupId); |
| 385 m_targetContextGroupId = targetContextGroupId; |
| 374 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); | 386 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
| 375 continueProgram(); | 387 continueProgram(); |
| 376 } | 388 } |
| 377 | 389 |
| 378 Response V8Debugger::setScriptSource( | 390 Response V8Debugger::setScriptSource( |
| 379 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, | 391 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, |
| 380 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, | 392 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, |
| 381 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged, | 393 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged, |
| 382 bool* compileError) { | 394 bool* compileError) { |
| 383 class EnableLiveEditScope { | 395 class EnableLiveEditScope { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 } | 509 } |
| 498 | 510 |
| 499 void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext, | 511 void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext, |
| 500 v8::Local<v8::Object> executionState, | 512 v8::Local<v8::Object> executionState, |
| 501 v8::Local<v8::Value> exception, | 513 v8::Local<v8::Value> exception, |
| 502 v8::Local<v8::Array> hitBreakpointNumbers, | 514 v8::Local<v8::Array> hitBreakpointNumbers, |
| 503 bool isPromiseRejection, bool isUncaught) { | 515 bool isPromiseRejection, bool isUncaught) { |
| 504 // Don't allow nested breaks. | 516 // Don't allow nested breaks. |
| 505 if (isPaused()) return; | 517 if (isPaused()) return; |
| 506 | 518 |
| 519 int contextGroupId = m_inspector->contextGroupId(pausedContext); |
| 520 if (m_targetContextGroupId && contextGroupId != m_targetContextGroupId) { |
| 521 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
| 522 return; |
| 523 } |
| 524 m_targetContextGroupId = 0; |
| 507 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( | 525 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( |
| 508 m_inspector->contextGroupId(pausedContext)); | 526 m_inspector->contextGroupId(pausedContext)); |
| 509 if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return; | 527 if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return; |
| 510 | 528 |
| 511 std::vector<String16> breakpointIds; | 529 std::vector<String16> breakpointIds; |
| 512 if (!hitBreakpointNumbers.IsEmpty()) { | 530 if (!hitBreakpointNumbers.IsEmpty()) { |
| 513 breakpointIds.reserve(hitBreakpointNumbers->Length()); | 531 breakpointIds.reserve(hitBreakpointNumbers->Length()); |
| 514 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { | 532 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { |
| 515 v8::Local<v8::Value> hitBreakpointNumber = | 533 v8::Local<v8::Value> hitBreakpointNumber = |
| 516 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); | 534 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 542 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit(); | 560 if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit(); |
| 543 m_scheduledOOMBreak = false; | 561 m_scheduledOOMBreak = false; |
| 544 m_pausedContext.Clear(); | 562 m_pausedContext.Clear(); |
| 545 m_executionState.Clear(); | 563 m_executionState.Clear(); |
| 546 } | 564 } |
| 547 | 565 |
| 548 void V8Debugger::v8OOMCallback(void* data) { | 566 void V8Debugger::v8OOMCallback(void* data) { |
| 549 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); | 567 V8Debugger* thisPtr = static_cast<V8Debugger*>(data); |
| 550 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); | 568 thisPtr->m_isolate->IncreaseHeapLimitForDebugging(); |
| 551 thisPtr->m_scheduledOOMBreak = true; | 569 thisPtr->m_scheduledOOMBreak = true; |
| 552 thisPtr->setPauseOnNextStatement(true); | 570 v8::Local<v8::Context> context = thisPtr->m_isolate->GetEnteredContext(); |
| 571 DCHECK(!context.IsEmpty()); |
| 572 thisPtr->setPauseOnNextStatement( |
| 573 true, thisPtr->m_inspector->contextGroupId(context)); |
| 553 } | 574 } |
| 554 | 575 |
| 555 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, | 576 void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script, |
| 556 bool has_compile_error) { | 577 bool has_compile_error) { |
| 557 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); | 578 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); |
| 558 if (!agent) return; | 579 if (!agent) return; |
| 559 if (script->IsWasm()) { | 580 if (script->IsWasm()) { |
| 560 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); | 581 m_wasmTranslation.AddScript(script.As<v8::debug::WasmScript>(), agent); |
| 561 } else if (m_ignoreScriptParsedEventsCounter == 0) { | 582 } else if (m_ignoreScriptParsedEventsCounter == 0) { |
| 562 agent->didParseSource( | 583 agent->didParseSource( |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 if (type == v8::debug::kDebugPromiseCreated && !parentTask) return; | 674 if (type == v8::debug::kDebugPromiseCreated && !parentTask) return; |
| 654 | 675 |
| 655 DCHECK(!context.IsEmpty()); | 676 DCHECK(!context.IsEmpty()); |
| 656 int contextGroupId = m_inspector->contextGroupId(context); | 677 int contextGroupId = m_inspector->contextGroupId(context); |
| 657 V8DebuggerAgentImpl* agent = | 678 V8DebuggerAgentImpl* agent = |
| 658 m_inspector->enabledDebuggerAgentForGroup(contextGroupId); | 679 m_inspector->enabledDebuggerAgentForGroup(contextGroupId); |
| 659 if (!agent) return; | 680 if (!agent) return; |
| 660 if (createdByUser && type == v8::debug::kDebugPromiseCreated) { | 681 if (createdByUser && type == v8::debug::kDebugPromiseCreated) { |
| 661 if (agent->shouldBreakInScheduledAsyncTask()) { | 682 if (agent->shouldBreakInScheduledAsyncTask()) { |
| 662 m_taskWithScheduledBreak = task; | 683 m_taskWithScheduledBreak = task; |
| 684 v8::debug::ClearStepping(m_isolate); |
| 663 } | 685 } |
| 664 return; | 686 return; |
| 665 } | 687 } |
| 666 if (!isScheduledTask) return; | 688 if (!isScheduledTask) return; |
| 667 if (type == v8::debug::kDebugWillHandle) { | 689 if (type == v8::debug::kDebugWillHandle) { |
| 668 agent->schedulePauseOnNextStatement( | 690 agent->schedulePauseOnNextStatement( |
| 669 protocol::Debugger::Paused::ReasonEnum::Other, nullptr); | 691 protocol::Debugger::Paused::ReasonEnum::Other, nullptr); |
| 670 return; | 692 return; |
| 671 } | 693 } |
| 672 DCHECK(type == v8::debug::kDebugDidHandle); | 694 DCHECK(type == v8::debug::kDebugDidHandle); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 972 | 994 |
| 973 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 995 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
| 974 } | 996 } |
| 975 | 997 |
| 976 int V8Debugger::currentContextGroupId() { | 998 int V8Debugger::currentContextGroupId() { |
| 977 if (!m_isolate->InContext()) return 0; | 999 if (!m_isolate->InContext()) return 0; |
| 978 return m_inspector->contextGroupId(m_isolate->GetCurrentContext()); | 1000 return m_inspector->contextGroupId(m_isolate->GetCurrentContext()); |
| 979 } | 1001 } |
| 980 | 1002 |
| 981 } // namespace v8_inspector | 1003 } // namespace v8_inspector |
| OLD | NEW |