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 |