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

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

Issue 2655253004: [inspector] introduced stepIntoAsync for chained callbacks (Closed)
Patch Set: PoC Created 3 years, 10 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
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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 m_executionState.Clear(); 291 m_executionState.Clear();
292 } 292 }
293 293
294 void V8Debugger::stepIntoStatement() { 294 void V8Debugger::stepIntoStatement() {
295 DCHECK(isPaused()); 295 DCHECK(isPaused());
296 DCHECK(!m_executionState.IsEmpty()); 296 DCHECK(!m_executionState.IsEmpty());
297 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); 297 v8::debug::PrepareStep(m_isolate, v8::debug::StepIn);
298 continueProgram(); 298 continueProgram();
299 } 299 }
300 300
301 Response V8Debugger::stepIntoAsync() {
302 DCHECK(isPaused());
303 DCHECK(!m_executionState.IsEmpty());
304 if (!m_currentCreatedAsyncTask) {
305 return Response::Error("No scheduled chained callback");
306 }
307 m_asyncTasksWithScheduledBreak.insert(m_currentCreatedAsyncTask);
308 v8::debug::ClearStepping(m_isolate);
309 continueProgram();
310 return Response::OK();
311 }
312
301 void V8Debugger::stepOverStatement() { 313 void V8Debugger::stepOverStatement() {
302 DCHECK(isPaused()); 314 DCHECK(isPaused());
303 DCHECK(!m_executionState.IsEmpty()); 315 DCHECK(!m_executionState.IsEmpty());
304 v8::debug::PrepareStep(m_isolate, v8::debug::StepNext); 316 v8::debug::PrepareStep(m_isolate, v8::debug::StepNext);
305 continueProgram(); 317 continueProgram();
306 } 318 }
307 319
308 void V8Debugger::stepOutOfFunction() { 320 void V8Debugger::stepOutOfFunction() {
309 DCHECK(isPaused()); 321 DCHECK(isPaused());
310 DCHECK(!m_executionState.IsEmpty()); 322 DCHECK(!m_executionState.IsEmpty());
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 return v8::Null(m_isolate); 842 return v8::Null(m_isolate);
831 if (!markAsInternal(context, location, V8InternalValueType::kLocation)) 843 if (!markAsInternal(context, location, V8InternalValueType::kLocation))
832 return v8::Null(m_isolate); 844 return v8::Null(m_isolate);
833 return location; 845 return location;
834 } 846 }
835 847
836 bool V8Debugger::isPaused() { return !m_pausedContext.IsEmpty(); } 848 bool V8Debugger::isPaused() { return !m_pausedContext.IsEmpty(); }
837 849
838 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace( 850 std::unique_ptr<V8StackTraceImpl> V8Debugger::createStackTrace(
839 v8::Local<v8::StackTrace> stackTrace) { 851 v8::Local<v8::StackTrace> stackTrace) {
840 int contextGroupId = 852 return V8StackTraceImpl::create(this, currentContextGroupId(), stackTrace,
841 m_isolate->InContext()
842 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
843 : 0;
844 return V8StackTraceImpl::create(this, contextGroupId, stackTrace,
845 V8StackTraceImpl::maxCallStackSizeToCapture); 853 V8StackTraceImpl::maxCallStackSizeToCapture);
846 } 854 }
847 855
848 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { 856 void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) {
849 if (depth <= 0) 857 if (depth <= 0)
850 m_maxAsyncCallStackDepthMap.erase(agent); 858 m_maxAsyncCallStackDepthMap.erase(agent);
851 else 859 else
852 m_maxAsyncCallStackDepthMap[agent] = depth; 860 m_maxAsyncCallStackDepthMap[agent] = depth;
853 861
854 int maxAsyncCallStackDepth = 0; 862 int maxAsyncCallStackDepth = 0;
(...skipping 26 matching lines...) Expand all
881 // We don't need to pass context group id here because we gets this callback 889 // We don't need to pass context group id here because we gets this callback
882 // from V8 for promise events only. 890 // from V8 for promise events only.
883 // Passing one as maxStackSize forces no async chain for the new stack and 891 // Passing one as maxStackSize forces no async chain for the new stack and
884 // allows us to not grow exponentially. 892 // allows us to not grow exponentially.
885 std::unique_ptr<V8StackTraceImpl> creationStack = 893 std::unique_ptr<V8StackTraceImpl> creationStack =
886 V8StackTraceImpl::capture(this, 0, 1, String16()); 894 V8StackTraceImpl::capture(this, 0, 1, String16());
887 if (creationStack && !creationStack->isEmpty()) { 895 if (creationStack && !creationStack->isEmpty()) {
888 m_asyncTaskCreationStacks[task] = std::move(creationStack); 896 m_asyncTaskCreationStacks[task] = std::move(creationStack);
889 registerAsyncTaskIfNeeded(task); 897 registerAsyncTaskIfNeeded(task);
890 } 898 }
899 if (!parentTask) return;
900 V8DebuggerAgentImpl* agent =
901 m_inspector->enabledDebuggerAgentForGroup(currentContextGroupId());
902 if (!agent) return;
903 m_currentCreatedAsyncTask = task;
904 agent->asyncTaskCreated();
905 m_currentCreatedAsyncTask = nullptr;
891 } 906 }
892 907
893 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, 908 void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task,
894 bool recurring) { 909 bool recurring) {
895 if (!m_maxAsyncCallStackDepth) return; 910 if (!m_maxAsyncCallStackDepth) return;
896 asyncTaskScheduled(toString16(taskName), task, recurring); 911 asyncTaskScheduled(toString16(taskName), task, recurring);
897 } 912 }
898 913
899 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, 914 void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
900 bool recurring) { 915 bool recurring) {
901 if (!m_maxAsyncCallStackDepth) return; 916 if (!m_maxAsyncCallStackDepth) return;
902 v8::HandleScope scope(m_isolate); 917 v8::HandleScope scope(m_isolate);
903 int contextGroupId =
904 m_isolate->InContext()
905 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
906 : 0;
907 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( 918 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
908 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, 919 this, currentContextGroupId(),
909 taskName); 920 V8StackTraceImpl::maxCallStackSizeToCapture, taskName);
910 if (chain) { 921 if (chain) {
911 m_asyncTaskStacks[task] = std::move(chain); 922 m_asyncTaskStacks[task] = std::move(chain);
912 if (recurring) m_recurringTasks.insert(task); 923 if (recurring) m_recurringTasks.insert(task);
913 registerAsyncTaskIfNeeded(task); 924 registerAsyncTaskIfNeeded(task);
914 } 925 }
915 } 926 }
916 927
917 void V8Debugger::asyncTaskCanceled(void* task) { 928 void V8Debugger::asyncTaskCanceled(void* task) {
918 if (!m_maxAsyncCallStackDepth) return; 929 if (!m_maxAsyncCallStackDepth) return;
919 m_asyncTaskStacks.erase(task); 930 m_asyncTaskStacks.erase(task);
920 m_recurringTasks.erase(task); 931 m_recurringTasks.erase(task);
921 m_parentTask.erase(task); 932 m_parentTask.erase(task);
922 m_asyncTaskCreationStacks.erase(task); 933 m_asyncTaskCreationStacks.erase(task);
934 if (m_currentCreatedAsyncTask == task) m_currentCreatedAsyncTask = nullptr;
935 m_asyncTasksWithScheduledBreak.erase(task);
923 auto it = m_taskToId.find(task); 936 auto it = m_taskToId.find(task);
924 if (it == m_taskToId.end()) return; 937 if (it == m_taskToId.end()) return;
925 m_idToTask.erase(it->second); 938 m_idToTask.erase(it->second);
926 m_taskToId.erase(it); 939 m_taskToId.erase(it);
927 } 940 }
928 941
929 void V8Debugger::asyncTaskStarted(void* task) { 942 void V8Debugger::asyncTaskStarted(void* task) {
930 if (!m_maxAsyncCallStackDepth) return; 943 if (!m_maxAsyncCallStackDepth) return;
931 m_currentTasks.push_back(task); 944 m_currentTasks.push_back(task);
932 auto parentIt = m_parentTask.find(task); 945 auto parentIt = m_parentTask.find(task);
933 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( 946 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(
934 parentIt == m_parentTask.end() ? task : parentIt->second); 947 parentIt == m_parentTask.end() ? task : parentIt->second);
935 // Needs to support following order of events: 948 // Needs to support following order of events:
936 // - asyncTaskScheduled 949 // - asyncTaskScheduled
937 // <-- attached here --> 950 // <-- attached here -->
938 // - asyncTaskStarted 951 // - asyncTaskStarted
939 // - asyncTaskCanceled <-- canceled before finished 952 // - asyncTaskCanceled <-- canceled before finished
940 // <-- async stack requested here --> 953 // <-- async stack requested here -->
941 // - asyncTaskFinished 954 // - asyncTaskFinished
942 std::unique_ptr<V8StackTraceImpl> stack; 955 std::unique_ptr<V8StackTraceImpl> stack;
943 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) 956 if (stackIt != m_asyncTaskStacks.end() && stackIt->second)
944 stack = stackIt->second->cloneImpl(); 957 stack = stackIt->second->cloneImpl();
945 auto itCreation = m_asyncTaskCreationStacks.find(task); 958 auto itCreation = m_asyncTaskCreationStacks.find(task);
946 if (stack && itCreation != m_asyncTaskCreationStacks.end()) { 959 if (stack && itCreation != m_asyncTaskCreationStacks.end()) {
947 stack->setCreation(itCreation->second->cloneImpl()); 960 stack->setCreation(itCreation->second->cloneImpl());
948 } 961 }
949 m_currentStacks.push_back(std::move(stack)); 962 m_currentStacks.push_back(std::move(stack));
963 if (m_asyncTasksWithScheduledBreak.find(task) ==
964 m_asyncTasksWithScheduledBreak.end())
965 return;
966 V8DebuggerAgentImpl* agent =
967 m_inspector->enabledDebuggerAgentForGroup(currentContextGroupId());
968 if (!agent) return;
969 agent->asyncTaskStarted();
950 } 970 }
951 971
952 void V8Debugger::asyncTaskFinished(void* task) { 972 void V8Debugger::asyncTaskFinished(void* task) {
953 if (!m_maxAsyncCallStackDepth) return; 973 if (!m_maxAsyncCallStackDepth) return;
954 // We could start instrumenting half way and the stack is empty. 974 // We could start instrumenting half way and the stack is empty.
955 if (!m_currentStacks.size()) return; 975 if (!m_currentStacks.size()) return;
956 976
957 DCHECK(m_currentTasks.back() == task); 977 DCHECK(m_currentTasks.back() == task);
958 m_currentTasks.pop_back(); 978 m_currentTasks.pop_back();
959 979
960 m_currentStacks.pop_back(); 980 m_currentStacks.pop_back();
981 if (m_asyncTasksWithScheduledBreak.find(task) !=
982 m_asyncTasksWithScheduledBreak.end()) {
983 V8DebuggerAgentImpl* agent =
984 m_inspector->enabledDebuggerAgentForGroup(currentContextGroupId());
985 if (!agent) return;
986 agent->asyncTaskFinished();
987 m_asyncTasksWithScheduledBreak.erase(task);
988 }
989
961 if (m_recurringTasks.find(task) == m_recurringTasks.end()) { 990 if (m_recurringTasks.find(task) == m_recurringTasks.end()) {
962 asyncTaskCanceled(task); 991 asyncTaskCanceled(task);
963 } 992 }
964 } 993 }
965 994
966 void V8Debugger::allAsyncTasksCanceled() { 995 void V8Debugger::allAsyncTasksCanceled() {
967 m_asyncTaskStacks.clear(); 996 m_asyncTaskStacks.clear();
968 m_recurringTasks.clear(); 997 m_recurringTasks.clear();
969 m_currentStacks.clear(); 998 m_currentStacks.clear();
970 m_currentTasks.clear(); 999 m_currentTasks.clear();
971 m_parentTask.clear(); 1000 m_parentTask.clear();
972 m_asyncTaskCreationStacks.clear(); 1001 m_asyncTaskCreationStacks.clear();
1002 m_currentCreatedAsyncTask = nullptr;
1003 m_asyncTasksWithScheduledBreak.clear();
973 m_idToTask.clear(); 1004 m_idToTask.clear();
974 m_taskToId.clear(); 1005 m_taskToId.clear();
975 m_lastTaskId = 0; 1006 m_lastTaskId = 0;
976 } 1007 }
977 1008
978 void V8Debugger::muteScriptParsedEvents() { 1009 void V8Debugger::muteScriptParsedEvents() {
979 ++m_ignoreScriptParsedEventsCounter; 1010 ++m_ignoreScriptParsedEventsCounter;
980 } 1011 }
981 1012
982 void V8Debugger::unmuteScriptParsedEvents() { 1013 void V8Debugger::unmuteScriptParsedEvents() {
983 --m_ignoreScriptParsedEventsCounter; 1014 --m_ignoreScriptParsedEventsCounter;
984 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); 1015 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
985 } 1016 }
986 1017
987 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 1018 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
988 bool fullStack) { 1019 bool fullStack) {
989 if (!m_isolate->InContext()) return nullptr; 1020 int contextGroupId = currentContextGroupId();
1021 if (!contextGroupId) return nullptr;
990 1022
991 v8::HandleScope handles(m_isolate); 1023 v8::HandleScope handles(m_isolate);
992 int contextGroupId =
993 m_inspector->contextGroupId(m_isolate->GetCurrentContext());
994 if (!contextGroupId) return nullptr;
995
996 size_t stackSize = 1024 size_t stackSize =
997 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 1025 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
998 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 1026 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
999 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 1027 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
1000 1028
1001 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 1029 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
1002 } 1030 }
1003 1031
1032 int V8Debugger::currentContextGroupId() {
1033 if (!m_isolate->InContext()) return 0;
1034 return m_inspector->contextGroupId(m_isolate->GetCurrentContext());
1035 }
1036
1004 } // namespace v8_inspector 1037 } // namespace v8_inspector
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698