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 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
329 } | 329 } |
330 | 330 |
331 void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) { | 331 void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) { |
332 if (isPaused()) return; | 332 if (isPaused()) return; |
333 DCHECK(targetContextGroupId); | 333 DCHECK(targetContextGroupId); |
334 if (!pause && m_targetContextGroupId && | 334 if (!pause && m_targetContextGroupId && |
335 m_targetContextGroupId != targetContextGroupId) { | 335 m_targetContextGroupId != targetContextGroupId) { |
336 return; | 336 return; |
337 } | 337 } |
338 m_targetContextGroupId = targetContextGroupId; | 338 m_targetContextGroupId = targetContextGroupId; |
339 m_breakRequested = pause; | |
339 if (pause) | 340 if (pause) |
340 v8::debug::DebugBreak(m_isolate); | 341 v8::debug::DebugBreak(m_isolate); |
341 else | 342 else |
342 v8::debug::CancelDebugBreak(m_isolate); | 343 v8::debug::CancelDebugBreak(m_isolate); |
343 } | 344 } |
344 | 345 |
345 bool V8Debugger::canBreakProgram() { | 346 bool V8Debugger::canBreakProgram() { |
346 if (!m_breakpointsActivated) return false; | 347 if (!m_breakpointsActivated) return false; |
347 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); | 348 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate); |
348 } | 349 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
380 | 381 |
381 void V8Debugger::stepOutOfFunction(int targetContextGroupId) { | 382 void V8Debugger::stepOutOfFunction(int targetContextGroupId) { |
382 DCHECK(isPaused()); | 383 DCHECK(isPaused()); |
383 DCHECK(!m_executionState.IsEmpty()); | 384 DCHECK(!m_executionState.IsEmpty()); |
384 DCHECK(targetContextGroupId); | 385 DCHECK(targetContextGroupId); |
385 m_targetContextGroupId = targetContextGroupId; | 386 m_targetContextGroupId = targetContextGroupId; |
386 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); | 387 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
387 continueProgram(); | 388 continueProgram(); |
388 } | 389 } |
389 | 390 |
391 void V8Debugger::scheduleStepIntoAsync( | |
392 std::unique_ptr<ScheduleStepIntoAsyncCallback> callback, | |
393 int targetContextGroupId) { | |
394 DCHECK(isPaused()); | |
395 DCHECK(!m_executionState.IsEmpty()); | |
396 DCHECK(targetContextGroupId); | |
397 if (m_stepIntoAsyncCallback) { | |
398 m_stepIntoAsyncCallback->sendFailure(Response::Error( | |
399 "Current scheduled step into async was overriden with new one.")); | |
400 } | |
401 m_targetContextGroupId = targetContextGroupId; | |
dgozman
2017/03/29 20:47:06
Let's add a test for scheduleStepIntoAsync+resume.
kozy
2017/03/29 22:33:34
Done.
| |
402 m_stepIntoAsyncCallback = std::move(callback); | |
403 } | |
404 | |
390 Response V8Debugger::setScriptSource( | 405 Response V8Debugger::setScriptSource( |
391 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, | 406 const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, |
392 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, | 407 Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, |
393 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged, | 408 JavaScriptCallFrames* newCallFrames, Maybe<bool>* stackChanged, |
394 bool* compileError) { | 409 bool* compileError) { |
395 class EnableLiveEditScope { | 410 class EnableLiveEditScope { |
396 public: | 411 public: |
397 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) { | 412 explicit EnableLiveEditScope(v8::Isolate* isolate) : m_isolate(isolate) { |
398 v8::debug::SetLiveEditEnabled(m_isolate, true); | 413 v8::debug::SetLiveEditEnabled(m_isolate, true); |
399 inLiveEditScope = true; | 414 inLiveEditScope = true; |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 bool isPromiseRejection, bool isUncaught) { | 530 bool isPromiseRejection, bool isUncaught) { |
516 // Don't allow nested breaks. | 531 // Don't allow nested breaks. |
517 if (isPaused()) return; | 532 if (isPaused()) return; |
518 | 533 |
519 int contextGroupId = m_inspector->contextGroupId(pausedContext); | 534 int contextGroupId = m_inspector->contextGroupId(pausedContext); |
520 if (m_targetContextGroupId && contextGroupId != m_targetContextGroupId) { | 535 if (m_targetContextGroupId && contextGroupId != m_targetContextGroupId) { |
521 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); | 536 v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
522 return; | 537 return; |
523 } | 538 } |
524 m_targetContextGroupId = 0; | 539 m_targetContextGroupId = 0; |
540 if (m_stepIntoAsyncCallback) { | |
541 m_stepIntoAsyncCallback->sendFailure( | |
542 Response::Error("No async tasks were scheduled before pause.")); | |
543 m_stepIntoAsyncCallback.reset(); | |
544 } | |
525 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( | 545 V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( |
526 m_inspector->contextGroupId(pausedContext)); | 546 m_inspector->contextGroupId(pausedContext)); |
527 if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return; | 547 if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return; |
528 | 548 |
529 std::vector<String16> breakpointIds; | 549 std::vector<String16> breakpointIds; |
530 if (!hitBreakpointNumbers.IsEmpty()) { | 550 if (!hitBreakpointNumbers.IsEmpty()) { |
531 breakpointIds.reserve(hitBreakpointNumbers->Length()); | 551 breakpointIds.reserve(hitBreakpointNumbers->Length()); |
532 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { | 552 for (uint32_t i = 0; i < hitBreakpointNumbers->Length(); i++) { |
533 v8::Local<v8::Value> hitBreakpointNumber = | 553 v8::Local<v8::Value> hitBreakpointNumber = |
534 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); | 554 hitBreakpointNumbers->Get(debuggerContext(), i).ToLocalChecked(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
617 if (!agent) return false; | 637 if (!agent) return false; |
618 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, | 638 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, |
619 end); | 639 end); |
620 } | 640 } |
621 | 641 |
622 void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context, | 642 void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context, |
623 v8::debug::PromiseDebugActionType type, | 643 v8::debug::PromiseDebugActionType type, |
624 int id, int parentId, | 644 int id, int parentId, |
625 bool createdByUser) { | 645 bool createdByUser) { |
626 // Async task events from Promises are given misaligned pointers to prevent | 646 // Async task events from Promises are given misaligned pointers to prevent |
627 // from overlapping with other Blink task identifiers. There is a single | 647 // from overlapping with other Blink task identifiers. |
628 // namespace of such ids, managed by src/js/promise.js. | 648 void* task = reinterpret_cast<void*>(id * 2 + 1); |
629 void* ptr = reinterpret_cast<void*>(id * 2 + 1); | 649 void* parentTask = |
630 void* parentPtr = | |
631 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr; | 650 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr; |
632 handleAsyncTaskStepping(context, type, ptr, parentPtr, createdByUser); | |
633 if (!m_maxAsyncCallStackDepth) return; | |
634 switch (type) { | 651 switch (type) { |
635 case v8::debug::kDebugPromiseCreated: | 652 case v8::debug::kDebugPromiseCreated: |
636 asyncTaskCreated(ptr, parentPtr); | 653 asyncTaskCreatedForStack(task, parentTask); |
654 if (createdByUser && parentTask) { | |
655 v8::Context::Scope contextScope(context); | |
656 asyncTaskCandidateForStepping(task); | |
657 } | |
637 break; | 658 break; |
638 case v8::debug::kDebugEnqueueAsyncFunction: | 659 case v8::debug::kDebugEnqueueAsyncFunction: |
639 asyncTaskScheduled("async function", ptr, true); | 660 asyncTaskScheduledForStack("async function", task, true); |
640 break; | 661 break; |
641 case v8::debug::kDebugEnqueuePromiseResolve: | 662 case v8::debug::kDebugEnqueuePromiseResolve: |
642 asyncTaskScheduled("Promise.resolve", ptr, true); | 663 asyncTaskScheduledForStack("Promise.resolve", task, true); |
643 break; | 664 break; |
644 case v8::debug::kDebugEnqueuePromiseReject: | 665 case v8::debug::kDebugEnqueuePromiseReject: |
645 asyncTaskScheduled("Promise.reject", ptr, true); | 666 asyncTaskScheduledForStack("Promise.reject", task, true); |
646 break; | 667 break; |
647 case v8::debug::kDebugPromiseCollected: | 668 case v8::debug::kDebugPromiseCollected: |
648 asyncTaskCanceled(ptr); | 669 asyncTaskCanceledForStack(task); |
670 asyncTaskCanceledForStepping(task); | |
649 break; | 671 break; |
650 case v8::debug::kDebugWillHandle: | 672 case v8::debug::kDebugWillHandle: |
651 asyncTaskStarted(ptr); | 673 asyncTaskStartedForStack(task); |
674 asyncTaskStartedForStepping(task); | |
652 break; | 675 break; |
653 case v8::debug::kDebugDidHandle: | 676 case v8::debug::kDebugDidHandle: |
654 asyncTaskFinished(ptr); | 677 asyncTaskFinishedForStack(task); |
678 asyncTaskFinishedForStepping(task); | |
655 break; | 679 break; |
656 } | 680 } |
657 } | 681 } |
658 | 682 |
659 void V8Debugger::handleAsyncTaskStepping(v8::Local<v8::Context> context, | |
660 v8::debug::PromiseDebugActionType type, | |
661 void* task, void* parentTask, | |
662 bool createdByUser) { | |
663 if (type == v8::debug::kDebugEnqueueAsyncFunction || | |
664 type == v8::debug::kDebugEnqueuePromiseResolve || | |
665 type == v8::debug::kDebugEnqueuePromiseReject) { | |
666 return; | |
667 } | |
668 | |
669 bool isScheduledTask = task == m_taskWithScheduledBreak; | |
670 if (type == v8::debug::kDebugPromiseCollected) { | |
671 if (isScheduledTask) m_taskWithScheduledBreak = nullptr; | |
672 return; | |
673 } | |
674 if (type == v8::debug::kDebugPromiseCreated && !parentTask) return; | |
675 | |
676 DCHECK(!context.IsEmpty()); | |
677 int contextGroupId = m_inspector->contextGroupId(context); | |
678 V8DebuggerAgentImpl* agent = | |
679 m_inspector->enabledDebuggerAgentForGroup(contextGroupId); | |
680 if (!agent) return; | |
681 if (createdByUser && type == v8::debug::kDebugPromiseCreated) { | |
682 if (agent->shouldBreakInScheduledAsyncTask()) { | |
683 m_taskWithScheduledBreak = task; | |
684 v8::debug::ClearStepping(m_isolate); | |
685 } | |
686 return; | |
687 } | |
688 if (!isScheduledTask) return; | |
689 if (type == v8::debug::kDebugWillHandle) { | |
690 agent->schedulePauseOnNextStatement( | |
691 protocol::Debugger::Paused::ReasonEnum::Other, nullptr); | |
692 return; | |
693 } | |
694 DCHECK(type == v8::debug::kDebugDidHandle); | |
695 agent->cancelPauseOnNextStatement(); | |
696 m_taskWithScheduledBreak = nullptr; | |
697 } | |
698 | |
699 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { | 683 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { |
700 if (!m_currentStacks.size()) return nullptr; | 684 if (!m_currentStacks.size()) return nullptr; |
701 return m_currentStacks.back().get(); | 685 return m_currentStacks.back().get(); |
702 } | 686 } |
703 | 687 |
704 void V8Debugger::compileDebuggerScript() { | 688 void V8Debugger::compileDebuggerScript() { |
705 if (!m_debuggerScript.IsEmpty()) { | 689 if (!m_debuggerScript.IsEmpty()) { |
706 UNREACHABLE(); | 690 UNREACHABLE(); |
707 return; | 691 return; |
708 } | 692 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 } | 846 } |
863 | 847 |
864 void V8Debugger::registerAsyncTaskIfNeeded(void* task) { | 848 void V8Debugger::registerAsyncTaskIfNeeded(void* task) { |
865 if (m_taskToId.find(task) != m_taskToId.end()) return; | 849 if (m_taskToId.find(task) != m_taskToId.end()) return; |
866 | 850 |
867 int id = ++m_lastTaskId; | 851 int id = ++m_lastTaskId; |
868 m_taskToId[task] = id; | 852 m_taskToId[task] = id; |
869 m_idToTask[id] = task; | 853 m_idToTask[id] = task; |
870 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { | 854 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
871 void* taskToRemove = m_idToTask.begin()->second; | 855 void* taskToRemove = m_idToTask.begin()->second; |
872 asyncTaskCanceled(taskToRemove); | 856 asyncTaskCanceledForStack(taskToRemove); |
873 } | 857 } |
874 } | 858 } |
875 | 859 |
876 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { | 860 void V8Debugger::asyncTaskCreatedForStack(void* task, void* parentTask) { |
877 if (!m_maxAsyncCallStackDepth) return; | 861 if (!m_maxAsyncCallStackDepth) return; |
878 if (parentTask) m_parentTask[task] = parentTask; | 862 if (parentTask) m_parentTask[task] = parentTask; |
879 v8::HandleScope scope(m_isolate); | 863 v8::HandleScope scope(m_isolate); |
880 // We don't need to pass context group id here because we get this callback | 864 // We don't need to pass context group id here because we get this callback |
881 // from V8 for promise events only. | 865 // from V8 for promise events only. |
882 // Passing one as maxStackSize forces no async chain for the new stack and | 866 // Passing one as maxStackSize forces no async chain for the new stack and |
883 // allows us to not grow exponentially. | 867 // allows us to not grow exponentially. |
884 std::unique_ptr<V8StackTraceImpl> creationStack = | 868 std::unique_ptr<V8StackTraceImpl> creationStack = |
885 V8StackTraceImpl::capture(this, 0, 1, String16()); | 869 V8StackTraceImpl::capture(this, 0, 1, String16()); |
886 if (creationStack && !creationStack->isEmpty()) { | 870 if (creationStack && !creationStack->isEmpty()) { |
887 m_asyncTaskCreationStacks[task] = std::move(creationStack); | 871 m_asyncTaskCreationStacks[task] = std::move(creationStack); |
888 registerAsyncTaskIfNeeded(task); | 872 registerAsyncTaskIfNeeded(task); |
889 } | 873 } |
890 } | 874 } |
891 | 875 |
892 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, | 876 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
893 bool recurring) { | 877 bool recurring) { |
894 if (!m_maxAsyncCallStackDepth) return; | 878 asyncTaskScheduledForStack(toString16(taskName), task, recurring); |
895 asyncTaskScheduled(toString16(taskName), task, recurring); | 879 asyncTaskCandidateForStepping(task); |
896 } | 880 } |
897 | 881 |
898 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, | 882 void V8Debugger::asyncTaskCanceled(void* task) { |
899 bool recurring) { | 883 asyncTaskCanceledForStack(task); |
884 asyncTaskCanceledForStepping(task); | |
885 } | |
886 | |
887 void V8Debugger::asyncTaskStarted(void* task) { | |
888 asyncTaskStartedForStack(task); | |
889 asyncTaskStartedForStepping(task); | |
890 } | |
891 | |
892 void V8Debugger::asyncTaskFinished(void* task) { | |
893 asyncTaskFinishedForStack(task); | |
894 asyncTaskFinishedForStepping(task); | |
895 } | |
896 | |
897 void V8Debugger::asyncTaskScheduledForStack(const String16& taskName, | |
898 void* task, bool recurring) { | |
900 if (!m_maxAsyncCallStackDepth) return; | 899 if (!m_maxAsyncCallStackDepth) return; |
901 v8::HandleScope scope(m_isolate); | 900 v8::HandleScope scope(m_isolate); |
902 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( | 901 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( |
903 this, currentContextGroupId(), | 902 this, currentContextGroupId(), |
904 V8StackTraceImpl::maxCallStackSizeToCapture, taskName); | 903 V8StackTraceImpl::maxCallStackSizeToCapture, taskName); |
905 if (chain) { | 904 if (chain) { |
906 m_asyncTaskStacks[task] = std::move(chain); | 905 m_asyncTaskStacks[task] = std::move(chain); |
907 if (recurring) m_recurringTasks.insert(task); | 906 if (recurring) m_recurringTasks.insert(task); |
908 registerAsyncTaskIfNeeded(task); | 907 registerAsyncTaskIfNeeded(task); |
909 } | 908 } |
910 } | 909 } |
911 | 910 |
912 void V8Debugger::asyncTaskCanceled(void* task) { | 911 void V8Debugger::asyncTaskCanceledForStack(void* task) { |
913 if (!m_maxAsyncCallStackDepth) return; | 912 if (!m_maxAsyncCallStackDepth) return; |
914 m_asyncTaskStacks.erase(task); | 913 m_asyncTaskStacks.erase(task); |
915 m_recurringTasks.erase(task); | 914 m_recurringTasks.erase(task); |
916 m_parentTask.erase(task); | 915 m_parentTask.erase(task); |
917 m_asyncTaskCreationStacks.erase(task); | 916 m_asyncTaskCreationStacks.erase(task); |
918 auto it = m_taskToId.find(task); | 917 auto it = m_taskToId.find(task); |
919 if (it == m_taskToId.end()) return; | 918 if (it == m_taskToId.end()) return; |
920 m_idToTask.erase(it->second); | 919 m_idToTask.erase(it->second); |
921 m_taskToId.erase(it); | 920 m_taskToId.erase(it); |
922 } | 921 } |
923 | 922 |
924 void V8Debugger::asyncTaskStarted(void* task) { | 923 void V8Debugger::asyncTaskStartedForStack(void* task) { |
925 if (!m_maxAsyncCallStackDepth) return; | 924 if (!m_maxAsyncCallStackDepth) return; |
926 m_currentTasks.push_back(task); | 925 m_currentTasks.push_back(task); |
927 auto parentIt = m_parentTask.find(task); | 926 auto parentIt = m_parentTask.find(task); |
928 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( | 927 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( |
929 parentIt == m_parentTask.end() ? task : parentIt->second); | 928 parentIt == m_parentTask.end() ? task : parentIt->second); |
930 // Needs to support following order of events: | 929 // Needs to support following order of events: |
931 // - asyncTaskScheduled | 930 // - asyncTaskScheduled |
932 // <-- attached here --> | 931 // <-- attached here --> |
933 // - asyncTaskStarted | 932 // - asyncTaskStarted |
934 // - asyncTaskCanceled <-- canceled before finished | 933 // - asyncTaskCanceled <-- canceled before finished |
935 // <-- async stack requested here --> | 934 // <-- async stack requested here --> |
936 // - asyncTaskFinished | 935 // - asyncTaskFinished |
937 std::unique_ptr<V8StackTraceImpl> stack; | 936 std::unique_ptr<V8StackTraceImpl> stack; |
938 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) | 937 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) |
939 stack = stackIt->second->cloneImpl(); | 938 stack = stackIt->second->cloneImpl(); |
940 auto itCreation = m_asyncTaskCreationStacks.find(task); | 939 auto itCreation = m_asyncTaskCreationStacks.find(task); |
941 if (stack && itCreation != m_asyncTaskCreationStacks.end()) { | 940 if (stack && itCreation != m_asyncTaskCreationStacks.end()) { |
942 stack->setCreation(itCreation->second->cloneImpl()); | 941 stack->setCreation(itCreation->second->cloneImpl()); |
943 } | 942 } |
944 m_currentStacks.push_back(std::move(stack)); | 943 m_currentStacks.push_back(std::move(stack)); |
945 } | 944 } |
946 | 945 |
947 void V8Debugger::asyncTaskFinished(void* task) { | 946 void V8Debugger::asyncTaskFinishedForStack(void* task) { |
948 if (!m_maxAsyncCallStackDepth) return; | 947 if (!m_maxAsyncCallStackDepth) return; |
949 // We could start instrumenting half way and the stack is empty. | 948 // We could start instrumenting half way and the stack is empty. |
950 if (!m_currentStacks.size()) return; | 949 if (!m_currentStacks.size()) return; |
951 | 950 |
952 DCHECK(m_currentTasks.back() == task); | 951 DCHECK(m_currentTasks.back() == task); |
953 m_currentTasks.pop_back(); | 952 m_currentTasks.pop_back(); |
954 | 953 |
955 m_currentStacks.pop_back(); | 954 m_currentStacks.pop_back(); |
956 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { | 955 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
957 asyncTaskCanceled(task); | 956 asyncTaskCanceledForStack(task); |
958 } | 957 } |
959 } | 958 } |
960 | 959 |
960 void V8Debugger::asyncTaskCandidateForStepping(void* task) { | |
961 if (!m_stepIntoAsyncCallback) return; | |
962 DCHECK(m_targetContextGroupId); | |
963 if (currentContextGroupId() != m_targetContextGroupId) return; | |
964 m_taskWithScheduledBreak = task; | |
965 v8::debug::ClearStepping(m_isolate); | |
966 m_stepIntoAsyncCallback->sendSuccess(); | |
967 m_stepIntoAsyncCallback.reset(); | |
968 } | |
969 | |
970 void V8Debugger::asyncTaskStartedForStepping(void* task) { | |
971 if (m_breakRequested) return; | |
972 if (task != m_taskWithScheduledBreak) return; | |
973 v8::debug::DebugBreak(m_isolate); | |
974 } | |
975 | |
976 void V8Debugger::asyncTaskFinishedForStepping(void* task) { | |
dgozman
2017/03/29 20:47:06
Should we clear m_taskWithScheduledBreak here? If
kozy
2017/03/29 22:33:34
Done.
| |
977 if (m_breakRequested) return; | |
978 if (task != m_taskWithScheduledBreak) return; | |
979 v8::debug::CancelDebugBreak(m_isolate); | |
980 } | |
981 | |
982 void V8Debugger::asyncTaskCanceledForStepping(void* task) { | |
983 if (task != m_taskWithScheduledBreak) return; | |
984 m_taskWithScheduledBreak = nullptr; | |
985 } | |
986 | |
961 void V8Debugger::allAsyncTasksCanceled() { | 987 void V8Debugger::allAsyncTasksCanceled() { |
962 m_asyncTaskStacks.clear(); | 988 m_asyncTaskStacks.clear(); |
963 m_recurringTasks.clear(); | 989 m_recurringTasks.clear(); |
964 m_currentStacks.clear(); | 990 m_currentStacks.clear(); |
965 m_currentTasks.clear(); | 991 m_currentTasks.clear(); |
966 m_parentTask.clear(); | 992 m_parentTask.clear(); |
967 m_asyncTaskCreationStacks.clear(); | 993 m_asyncTaskCreationStacks.clear(); |
968 m_idToTask.clear(); | 994 m_idToTask.clear(); |
969 m_taskToId.clear(); | 995 m_taskToId.clear(); |
970 m_lastTaskId = 0; | 996 m_lastTaskId = 0; |
(...skipping 23 matching lines...) Expand all Loading... | |
994 | 1020 |
995 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); | 1021 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); |
996 } | 1022 } |
997 | 1023 |
998 int V8Debugger::currentContextGroupId() { | 1024 int V8Debugger::currentContextGroupId() { |
999 if (!m_isolate->InContext()) return 0; | 1025 if (!m_isolate->InContext()) return 0; |
1000 return m_inspector->contextGroupId(m_isolate->GetCurrentContext()); | 1026 return m_inspector->contextGroupId(m_isolate->GetCurrentContext()); |
1001 } | 1027 } |
1002 | 1028 |
1003 } // namespace v8_inspector | 1029 } // namespace v8_inspector |
OLD | NEW |