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

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

Issue 2844753002: [inspector] better stacks for promises (Closed)
Patch Set: Created 3 years, 7 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 895 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 void V8Debugger::asyncTaskCanceledForStack(void* task) { 906 void V8Debugger::asyncTaskCanceledForStack(void* task) {
907 if (!m_maxAsyncCallStackDepth) return; 907 if (!m_maxAsyncCallStackDepth) return;
908 m_asyncTaskStacks.erase(task); 908 m_asyncTaskStacks.erase(task);
909 m_recurringTasks.erase(task); 909 m_recurringTasks.erase(task);
910 m_parentTask.erase(task); 910 m_parentTask.erase(task);
911 m_asyncTaskCreationStacks.erase(task); 911 m_asyncTaskCreationStacks.erase(task);
912 } 912 }
913 913
914 void V8Debugger::asyncTaskStartedForStack(void* task) { 914 void V8Debugger::asyncTaskStartedForStack(void* task) {
915 if (!m_maxAsyncCallStackDepth) return; 915 if (!m_maxAsyncCallStackDepth) return;
916 m_currentTasks.push_back(task);
917 auto parentIt = m_parentTask.find(task);
918 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(
919 parentIt == m_parentTask.end() ? task : parentIt->second);
920 // Needs to support following order of events: 916 // Needs to support following order of events:
921 // - asyncTaskScheduled 917 // - asyncTaskScheduled
922 // <-- attached here --> 918 // <-- attached here -->
923 // - asyncTaskStarted 919 // - asyncTaskStarted
924 // - asyncTaskCanceled <-- canceled before finished 920 // - asyncTaskCanceled <-- canceled before finished
925 // <-- async stack requested here --> 921 // <-- async stack requested here -->
926 // - asyncTaskFinished 922 // - asyncTaskFinished
927 std::weak_ptr<AsyncStackTrace> asyncParent; 923 m_currentTasks.push_back(task);
928 if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second; 924 auto parentIt = m_parentTask.find(task);
925 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(
926 parentIt == m_parentTask.end() ? task : parentIt->second);
927 if (stackIt != m_asyncTaskStacks.end()) {
928 m_currentAsyncParent.push_back(stackIt->second.lock());
929 } else {
930 m_currentAsyncParent.emplace_back();
931 }
929 auto itCreation = m_asyncTaskCreationStacks.find(task); 932 auto itCreation = m_asyncTaskCreationStacks.find(task);
930 if (asyncParent.lock() && itCreation != m_asyncTaskCreationStacks.end()) { 933 if (itCreation != m_asyncTaskCreationStacks.end()) {
kozy 2017/04/27 18:35:31 this change is essential of this CL.
931 m_currentAsyncCreation.push_back(itCreation->second.lock()); 934 m_currentAsyncCreation.push_back(itCreation->second.lock());
932 } else { 935 } else {
933 m_currentAsyncCreation.emplace_back(); 936 m_currentAsyncCreation.emplace_back();
934 } 937 }
935 m_currentAsyncParent.push_back(asyncParent.lock());
936 } 938 }
937 939
938 void V8Debugger::asyncTaskFinishedForStack(void* task) { 940 void V8Debugger::asyncTaskFinishedForStack(void* task) {
939 if (!m_maxAsyncCallStackDepth) return; 941 if (!m_maxAsyncCallStackDepth) return;
940 // We could start instrumenting half way and the stack is empty. 942 // We could start instrumenting half way and the stack is empty.
941 if (!m_currentTasks.size()) return; 943 if (!m_currentTasks.size()) return;
942 DCHECK(m_currentTasks.back() == task); 944 DCHECK(m_currentTasks.back() == task);
943 m_currentTasks.pop_back(); 945 m_currentTasks.pop_back();
944 946
945 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size()); 947 DCHECK(m_currentAsyncParent.size() == m_currentAsyncCreation.size());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 } 1034 }
1033 cleanupExpiredWeakPointers(m_asyncTaskStacks); 1035 cleanupExpiredWeakPointers(m_asyncTaskStacks);
1034 cleanupExpiredWeakPointers(m_asyncTaskCreationStacks); 1036 cleanupExpiredWeakPointers(m_asyncTaskCreationStacks);
1035 for (auto it = m_recurringTasks.begin(); it != m_recurringTasks.end();) { 1037 for (auto it = m_recurringTasks.begin(); it != m_recurringTasks.end();) {
1036 if (m_asyncTaskStacks.find(*it) == m_asyncTaskStacks.end()) { 1038 if (m_asyncTaskStacks.find(*it) == m_asyncTaskStacks.end()) {
1037 it = m_recurringTasks.erase(it); 1039 it = m_recurringTasks.erase(it);
1038 } else { 1040 } else {
1039 ++it; 1041 ++it;
1040 } 1042 }
1041 } 1043 }
1044 // We use parent information to provide correct parent stack for promises,
1045 // Promise.resolve().then(...).then(...)
1046 // created task#1 - stack#1
1047 // scheduled task#1 - stack#2
1048 // created task#2 -> task#1 - stack#3
1049 // created task#3 -> task#2 - stack#4
1050 // ...
1051 // started task#2 - use stack(parent(task#2)) == stack(task#1) == stack#2
1052 // ...
1053 // scheduled task#2 - stack#5
dgozman 2017/04/27 17:26:34 scheduled after started?
kozy 2017/04/27 18:35:31 yes, it's how our promise instrumentation works an
1054 // finished task#2
1055 // started task#3 - use stack(parent(task#3)) == stack(task#2) == stack#5
1056 // ...
1057 // scheduled task#3 - stack#6
1058 // finished task#3
1059 // Let's consider what parent link is obsolete when we collect stacks:
1060 // stack#1 - (task#2 -> task#1, task#3 -> task#2)
1061 // stack#2 - (task#3 -> task#2)
1062 // stack#3 - (task#3 -> task#2)
1063 // stack#4 - (task#3 -> task#2)
1064 // stack#5 - ()
1065 // stack#6 - ()
1066 // But in case when we start collecting stacks after getting stack#4 but
1067 // before stack#5 is added we should preserve parent link since original task
1068 // can be scheduled at any time in future and this link will be required to
1069 // get correct parent stack later. It means that we should collect parent link
1070 // in case when there is no creation or schedule stack for parent.
1042 for (auto it = m_parentTask.begin(); it != m_parentTask.end();) { 1071 for (auto it = m_parentTask.begin(); it != m_parentTask.end();) {
1043 if (m_asyncTaskCreationStacks.find(it->second) == 1072 if (m_asyncTaskCreationStacks.find(it->second) ==
1044 m_asyncTaskCreationStacks.end()) { 1073 m_asyncTaskCreationStacks.end() &&
1074 m_asyncTaskStacks.find(it->second) == m_asyncTaskStacks.end()) {
1045 it = m_parentTask.erase(it); 1075 it = m_parentTask.erase(it);
1046 } else { 1076 } else {
1047 ++it; 1077 ++it;
1048 } 1078 }
1049 } 1079 }
1050 cleanupExpiredWeakPointers(m_framesCache); 1080 cleanupExpiredWeakPointers(m_framesCache);
1051 } 1081 }
1052 1082
1053 std::shared_ptr<StackFrame> V8Debugger::symbolize( 1083 std::shared_ptr<StackFrame> V8Debugger::symbolize(
1054 v8::Local<v8::StackFrame> v8Frame) { 1084 v8::Local<v8::StackFrame> v8Frame) {
(...skipping 24 matching lines...) Expand all
1079 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount); 1109 fprintf(stdout, "Async stacks count: %d\n", m_asyncStacksCount);
1080 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size()); 1110 fprintf(stdout, "Scheduled async tasks: %zu\n", m_asyncTaskStacks.size());
1081 fprintf(stdout, "Created async tasks: %zu\n", 1111 fprintf(stdout, "Created async tasks: %zu\n",
1082 m_asyncTaskCreationStacks.size()); 1112 m_asyncTaskCreationStacks.size());
1083 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size()); 1113 fprintf(stdout, "Async tasks with parent: %zu\n", m_parentTask.size());
1084 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size()); 1114 fprintf(stdout, "Recurring async tasks: %zu\n", m_recurringTasks.size());
1085 fprintf(stdout, "\n"); 1115 fprintf(stdout, "\n");
1086 } 1116 }
1087 1117
1088 } // namespace v8_inspector 1118 } // namespace v8_inspector
OLDNEW
« no previous file with comments | « no previous file | src/inspector/v8-stack-trace-impl.h » ('j') | src/inspector/v8-stack-trace-impl.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698