Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(771)

Side by Side Diff: src/inspector/v8-debugger.cc

Issue 2723273002: [inspector] introduced Debugger.scheduleStepIntoAsync (Closed)
Patch Set: fixed tests Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 compileDebuggerScript(); 187 compileDebuggerScript();
188 } 188 }
189 189
190 void V8Debugger::disable() { 190 void V8Debugger::disable() {
191 if (--m_enableCount) return; 191 if (--m_enableCount) return;
192 DCHECK(enabled()); 192 DCHECK(enabled());
193 clearBreakpoints(); 193 clearBreakpoints();
194 m_debuggerScript.Reset(); 194 m_debuggerScript.Reset();
195 m_debuggerContext.Reset(); 195 m_debuggerContext.Reset();
196 allAsyncTasksCanceled(); 196 allAsyncTasksCanceled();
197 m_taskWithScheduledBreak = nullptr;
197 m_wasmTranslation.Clear(); 198 m_wasmTranslation.Clear();
198 v8::debug::SetDebugDelegate(m_isolate, nullptr); 199 v8::debug::SetDebugDelegate(m_isolate, nullptr);
199 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr); 200 v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
200 m_isolate->RestoreOriginalHeapLimit(); 201 m_isolate->RestoreOriginalHeapLimit();
201 } 202 }
202 203
203 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); } 204 bool V8Debugger::enabled() const { return !m_debuggerScript.IsEmpty(); }
204 205
205 void V8Debugger::getCompiledScripts( 206 void V8Debugger::getCompiledScripts(
206 int contextGroupId, 207 int contextGroupId,
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 void V8Debugger::setPauseOnNextStatement(bool pause) { 331 void V8Debugger::setPauseOnNextStatement(bool pause) {
331 if (isPaused()) return; 332 if (isPaused()) return;
332 if (pause) 333 if (pause)
333 v8::debug::DebugBreak(m_isolate); 334 v8::debug::DebugBreak(m_isolate);
334 else 335 else
335 v8::debug::CancelDebugBreak(m_isolate); 336 v8::debug::CancelDebugBreak(m_isolate);
336 } 337 }
337 338
338 bool V8Debugger::canBreakProgram() { 339 bool V8Debugger::canBreakProgram() {
339 if (!m_breakpointsActivated) return false; 340 if (!m_breakpointsActivated) return false;
340 return v8::debug::HasNonBlackboxedFrameOnStack(m_isolate); 341 return !v8::debug::AllFramesOnStackAreBlackboxed(m_isolate);
341 } 342 }
342 343
343 void V8Debugger::breakProgram() { 344 void V8Debugger::breakProgram() {
344 // Don't allow nested breaks. 345 // Don't allow nested breaks.
345 if (isPaused()) return; 346 if (isPaused()) return;
346 if (!canBreakProgram()) return; 347 if (!canBreakProgram()) return;
347 348
348 v8::HandleScope scope(m_isolate); 349 v8::HandleScope scope(m_isolate);
349 v8::Local<v8::Function> breakFunction; 350 v8::Local<v8::Function> breakFunction;
350 if (!v8::Function::New(m_isolate->GetCurrentContext(), 351 if (!v8::Function::New(m_isolate->GetCurrentContext(),
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 619
619 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, 620 bool V8Debugger::IsFunctionBlackboxed(v8::Local<v8::debug::Script> script,
620 const v8::debug::Location& start, 621 const v8::debug::Location& start,
621 const v8::debug::Location& end) { 622 const v8::debug::Location& end) {
622 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script); 623 V8DebuggerAgentImpl* agent = agentForScript(m_inspector, script);
623 if (!agent) return false; 624 if (!agent) return false;
624 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start, 625 return agent->isFunctionBlackboxed(String16::fromInteger(script->Id()), start,
625 end); 626 end);
626 } 627 }
627 628
628 void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, 629 void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context,
629 int id, int parentId) { 630 v8::debug::PromiseDebugActionType type,
630 if (!m_maxAsyncCallStackDepth) return; 631 int id, int parentId,
632 bool createdByUser) {
631 // Async task events from Promises are given misaligned pointers to prevent 633 // Async task events from Promises are given misaligned pointers to prevent
632 // from overlapping with other Blink task identifiers. There is a single 634 // from overlapping with other Blink task identifiers. There is a single
633 // namespace of such ids, managed by src/js/promise.js. 635 // namespace of such ids, managed by src/js/promise.js.
634 void* ptr = reinterpret_cast<void*>(id * 2 + 1); 636 void* ptr = reinterpret_cast<void*>(id * 2 + 1);
637 void* parentPtr =
638 parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr;
639 handleAsyncTaskStepping(context, type, ptr, parentPtr, createdByUser);
640 if (!m_maxAsyncCallStackDepth) return;
635 switch (type) { 641 switch (type) {
636 case v8::debug::kDebugPromiseCreated: 642 case v8::debug::kDebugPromiseCreated:
637 asyncTaskCreated( 643 asyncTaskCreated(ptr, parentPtr);
638 ptr, parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr);
639 break; 644 break;
640 case v8::debug::kDebugEnqueueAsyncFunction: 645 case v8::debug::kDebugEnqueueAsyncFunction:
641 asyncTaskScheduled("async function", ptr, true); 646 asyncTaskScheduled("async function", ptr, true);
642 break; 647 break;
643 case v8::debug::kDebugEnqueuePromiseResolve: 648 case v8::debug::kDebugEnqueuePromiseResolve:
644 asyncTaskScheduled("Promise.resolve", ptr, true); 649 asyncTaskScheduled("Promise.resolve", ptr, true);
645 break; 650 break;
646 case v8::debug::kDebugEnqueuePromiseReject: 651 case v8::debug::kDebugEnqueuePromiseReject:
647 asyncTaskScheduled("Promise.reject", ptr, true); 652 asyncTaskScheduled("Promise.reject", ptr, true);
648 break; 653 break;
649 case v8::debug::kDebugPromiseCollected: 654 case v8::debug::kDebugPromiseCollected:
650 asyncTaskCanceled(ptr); 655 asyncTaskCanceled(ptr);
651 break; 656 break;
652 case v8::debug::kDebugWillHandle: 657 case v8::debug::kDebugWillHandle:
653 asyncTaskStarted(ptr); 658 asyncTaskStarted(ptr);
654 break; 659 break;
655 case v8::debug::kDebugDidHandle: 660 case v8::debug::kDebugDidHandle:
656 asyncTaskFinished(ptr); 661 asyncTaskFinished(ptr);
657 break; 662 break;
658 } 663 }
659 } 664 }
660 665
666 void V8Debugger::handleAsyncTaskStepping(v8::Local<v8::Context> context,
667 v8::debug::PromiseDebugActionType type,
668 void* task, void* parentTask,
669 bool createdByUser) {
670 if (type == v8::debug::kDebugEnqueueAsyncFunction ||
671 type == v8::debug::kDebugEnqueuePromiseResolve ||
672 type == v8::debug::kDebugEnqueuePromiseReject) {
673 return;
674 }
675
676 bool isScheduledTask = task == m_taskWithScheduledBreak;
677 if (type == v8::debug::kDebugPromiseCollected) {
678 if (isScheduledTask) m_taskWithScheduledBreak = nullptr;
679 return;
680 }
681 if (type == v8::debug::kDebugPromiseCreated && !parentTask) return;
682
683 DCHECK(!context.IsEmpty());
684 int contextGroupId = m_inspector->contextGroupId(context);
685 V8DebuggerAgentImpl* agent =
686 m_inspector->enabledDebuggerAgentForGroup(contextGroupId);
687 if (!agent) return;
688 if (createdByUser && type == v8::debug::kDebugPromiseCreated) {
689 if (agent->shouldBreakInScheduledAsyncTask()) {
690 m_taskWithScheduledBreak = task;
691 }
692 return;
693 }
694 if (!isScheduledTask) return;
695 if (type == v8::debug::kDebugWillHandle) {
696 agent->schedulePauseOnNextStatement(
697 protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
698 return;
699 }
700 DCHECK(type == v8::debug::kDebugDidHandle);
701 agent->cancelPauseOnNextStatement();
702 m_taskWithScheduledBreak = nullptr;
703 }
704
661 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() { 705 V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
662 if (!m_currentStacks.size()) return nullptr; 706 if (!m_currentStacks.size()) return nullptr;
663 return m_currentStacks.back().get(); 707 return m_currentStacks.back().get();
664 } 708 }
665 709
666 void V8Debugger::compileDebuggerScript() { 710 void V8Debugger::compileDebuggerScript() {
667 if (!m_debuggerScript.IsEmpty()) { 711 if (!m_debuggerScript.IsEmpty()) {
668 UNREACHABLE(); 712 UNREACHABLE();
669 return; 713 return;
670 } 714 }
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 createDataProperty(context, properties, properties->Length(), 839 createDataProperty(context, properties, properties->Length(),
796 toV8StringInternalized(m_isolate, "[[Scopes]]")); 840 toV8StringInternalized(m_isolate, "[[Scopes]]"));
797 createDataProperty(context, properties, properties->Length(), scopes); 841 createDataProperty(context, properties, properties->Length(), scopes);
798 } 842 }
799 } 843 }
800 return properties; 844 return properties;
801 } 845 }
802 846
803 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace( 847 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
804 v8::Local<v8::StackTrace> stackTrace) { 848 v8::Local<v8::StackTrace> stackTrace) {
805 int contextGroupId = 849 return V8StackTraceImpl::create(this, currentContextGroupId(), stackTrace,
806 m_isolate->InContext()
807 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
808 : 0;
809 return V8StackTraceImpl::create(this, contextGroupId, stackTrace,
810 V8StackTraceImpl::maxCallStackSizeToCapture); 850 V8StackTraceImpl::maxCallStackSizeToCapture);
811 } 851 }
812 852
813 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { 853 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
814 if (depth <= 0) 854 if (depth <= 0)
815 m_maxAsyncCallStackDepthMap.erase(agent); 855 m_maxAsyncCallStackDepthMap.erase(agent);
816 else 856 else
817 m_maxAsyncCallStackDepthMap[agent] = depth; 857 m_maxAsyncCallStackDepthMap[agent] = depth;
818 858
819 int maxAsyncCallStackDepth = 0; 859 int maxAsyncCallStackDepth = 0;
(...skipping 16 matching lines...) Expand all
836 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { 876 if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) {
837 void* taskToRemove = m_idToTask.begin()->second; 877 void* taskToRemove = m_idToTask.begin()->second;
838 asyncTaskCanceled(taskToRemove); 878 asyncTaskCanceled(taskToRemove);
839 } 879 }
840 } 880 }
841 881
842 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { 882 void V8Debugger::asyncTaskCreated(void* task, void* parentTask) {
843 if (!m_maxAsyncCallStackDepth) return; 883 if (!m_maxAsyncCallStackDepth) return;
844 if (parentTask) m_parentTask[task] = parentTask; 884 if (parentTask) m_parentTask[task] = parentTask;
845 v8::HandleScope scope(m_isolate); 885 v8::HandleScope scope(m_isolate);
846 // We don't need to pass context group id here because we gets this callback 886 // We don't need to pass context group id here because we get this callback
847 // from V8 for promise events only. 887 // from V8 for promise events only.
848 // Passing one as maxStackSize forces no async chain for the new stack and 888 // Passing one as maxStackSize forces no async chain for the new stack and
849 // allows us to not grow exponentially. 889 // allows us to not grow exponentially.
850 std::unique_ptr<V8StackTraceImpl> creationStack = 890 std::unique_ptr<V8StackTraceImpl> creationStack =
851 V8StackTraceImpl::capture(this, 0, 1, String16()); 891 V8StackTraceImpl::capture(this, 0, 1, String16());
852 if (creationStack && !creationStack->isEmpty()) { 892 if (creationStack && !creationStack->isEmpty()) {
853 m_asyncTaskCreationStacks[task] = std::move(creationStack); 893 m_asyncTaskCreationStacks[task] = std::move(creationStack);
854 registerAsyncTaskIfNeeded(task); 894 registerAsyncTaskIfNeeded(task);
855 } 895 }
856 } 896 }
857 897
858 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, 898 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
859 bool recurring) { 899 bool recurring) {
860 if (!m_maxAsyncCallStackDepth) return; 900 if (!m_maxAsyncCallStackDepth) return;
861 asyncTaskScheduled(toString16(taskName), task, recurring); 901 asyncTaskScheduled(toString16(taskName), task, recurring);
862 } 902 }
863 903
864 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, 904 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
865 bool recurring) { 905 bool recurring) {
866 if (!m_maxAsyncCallStackDepth) return; 906 if (!m_maxAsyncCallStackDepth) return;
867 v8::HandleScope scope(m_isolate); 907 v8::HandleScope scope(m_isolate);
868 int contextGroupId =
869 m_isolate->InContext()
870 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
871 : 0;
872 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( 908 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
873 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, 909 this, currentContextGroupId(),
874 taskName); 910 V8StackTraceImpl::maxCallStackSizeToCapture, taskName);
875 if (chain) { 911 if (chain) {
876 m_asyncTaskStacks[task] = std::move(chain); 912 m_asyncTaskStacks[task] = std::move(chain);
877 if (recurring) m_recurringTasks.insert(task); 913 if (recurring) m_recurringTasks.insert(task);
878 registerAsyncTaskIfNeeded(task); 914 registerAsyncTaskIfNeeded(task);
879 } 915 }
880 } 916 }
881 917
882 void V8Debugger::asyncTaskCanceled(void* task) { 918 void V8Debugger::asyncTaskCanceled(void* task) {
883 if (!m_maxAsyncCallStackDepth) return; 919 if (!m_maxAsyncCallStackDepth) return;
884 m_asyncTaskStacks.erase(task); 920 m_asyncTaskStacks.erase(task);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 void V8Debugger::unmuteScriptParsedEvents() { 983 void V8Debugger::unmuteScriptParsedEvents() {
948 --m_ignoreScriptParsedEventsCounter; 984 --m_ignoreScriptParsedEventsCounter;
949 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); 985 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
950 } 986 }
951 987
952 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 988 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
953 bool fullStack) { 989 bool fullStack) {
954 if (!m_isolate->InContext()) return nullptr; 990 if (!m_isolate->InContext()) return nullptr;
955 991
956 v8::HandleScope handles(m_isolate); 992 v8::HandleScope handles(m_isolate);
957 int contextGroupId = 993 int contextGroupId = currentContextGroupId();
958 m_inspector->contextGroupId(m_isolate->GetCurrentContext());
959 if (!contextGroupId) return nullptr; 994 if (!contextGroupId) return nullptr;
960 995
961 size_t stackSize = 996 size_t stackSize =
962 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 997 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
963 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 998 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
964 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 999 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
965 1000
966 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 1001 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
967 } 1002 }
968 1003
1004 int V8Debugger::currentContextGroupId() {
1005 if (!m_isolate->InContext()) return 0;
1006 return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
1007 }
1008
969 } // namespace v8_inspector 1009 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698