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

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

Issue 2579403002: [inspector] introduce limit for amount of stored async stacks (Closed)
Patch Set: maps.. Created 4 years 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
« src/inspector/v8-debugger.h ('K') | « src/inspector/v8-debugger.h ('k') | no next file » | 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"
11 #include "src/inspector/string-util.h" 11 #include "src/inspector/string-util.h"
12 #include "src/inspector/v8-debugger-agent-impl.h" 12 #include "src/inspector/v8-debugger-agent-impl.h"
13 #include "src/inspector/v8-inspector-impl.h" 13 #include "src/inspector/v8-inspector-impl.h"
14 #include "src/inspector/v8-internal-value-type.h" 14 #include "src/inspector/v8-internal-value-type.h"
15 #include "src/inspector/v8-stack-trace-impl.h" 15 #include "src/inspector/v8-stack-trace-impl.h"
16 #include "src/inspector/v8-value-copier.h" 16 #include "src/inspector/v8-value-copier.h"
17 17
18 #include "include/v8-util.h" 18 #include "include/v8-util.h"
19 19
20 namespace v8_inspector { 20 namespace v8_inspector {
21 21
22 namespace { 22 namespace {
23 static const char v8AsyncTaskEventEnqueue[] = "enqueue"; 23 static const char v8AsyncTaskEventEnqueue[] = "enqueue";
24 static const char v8AsyncTaskEventEnqueueRecurring[] = "enqueueRecurring"; 24 static const char v8AsyncTaskEventEnqueueRecurring[] = "enqueueRecurring";
25 static const char v8AsyncTaskEventWillHandle[] = "willHandle"; 25 static const char v8AsyncTaskEventWillHandle[] = "willHandle";
26 static const char v8AsyncTaskEventDidHandle[] = "didHandle"; 26 static const char v8AsyncTaskEventDidHandle[] = "didHandle";
27 static const char v8AsyncTaskEventCancel[] = "cancel"; 27 static const char v8AsyncTaskEventCancel[] = "cancel";
28 28
29 // Based on DevTools frontend measurement, with asyncCallStackDepth = 4,
30 // average async call stack tail requires ~1 Kb. Let's reserve ~ 128 Mb
31 // for async stacks.
32 static const int kMaxAsyncTaskStacks = 128 * 1024;
33
29 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) { 34 inline v8::Local<v8::Boolean> v8Boolean(bool value, v8::Isolate* isolate) {
30 return value ? v8::True(isolate) : v8::False(isolate); 35 return value ? v8::True(isolate) : v8::False(isolate);
31 } 36 }
32 37
33 } // namespace 38 } // namespace
34 39
35 static bool inLiveEditScope = false; 40 static bool inLiveEditScope = false;
36 41
37 v8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod( 42 v8::MaybeLocal<v8::Value> V8Debugger::callDebuggerMethod(
38 const char* functionName, int argc, v8::Local<v8::Value> argv[]) { 43 const char* functionName, int argc, v8::Local<v8::Value> argv[]) {
39 v8::MicrotasksScope microtasks(m_isolate, 44 v8::MicrotasksScope microtasks(m_isolate,
40 v8::MicrotasksScope::kDoNotRunMicrotasks); 45 v8::MicrotasksScope::kDoNotRunMicrotasks);
41 DCHECK(m_isolate->InContext()); 46 DCHECK(m_isolate->InContext());
42 v8::Local<v8::Context> context = m_isolate->GetCurrentContext(); 47 v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
43 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate); 48 v8::Local<v8::Object> debuggerScript = m_debuggerScript.Get(m_isolate);
44 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( 49 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
45 debuggerScript 50 debuggerScript
46 ->Get(context, toV8StringInternalized(m_isolate, functionName)) 51 ->Get(context, toV8StringInternalized(m_isolate, functionName))
47 .ToLocalChecked()); 52 .ToLocalChecked());
48 return function->Call(context, debuggerScript, argc, argv); 53 return function->Call(context, debuggerScript, argc, argv);
49 } 54 }
50 55
51 V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector) 56 V8Debugger::V8Debugger(v8::Isolate* isolate, V8InspectorImpl* inspector)
52 : m_isolate(isolate), 57 : m_isolate(isolate),
53 m_inspector(inspector), 58 m_inspector(inspector),
54 m_enableCount(0), 59 m_enableCount(0),
55 m_breakpointsActivated(true), 60 m_breakpointsActivated(true),
56 m_runningNestedMessageLoop(false), 61 m_runningNestedMessageLoop(false),
57 m_ignoreScriptParsedEventsCounter(0), 62 m_ignoreScriptParsedEventsCounter(0),
63 m_lastId(0),
58 m_maxAsyncCallStackDepth(0), 64 m_maxAsyncCallStackDepth(0),
59 m_pauseOnExceptionsState(v8::debug::NoBreakOnException), 65 m_pauseOnExceptionsState(v8::debug::NoBreakOnException),
60 m_wasmTranslation(isolate) {} 66 m_wasmTranslation(isolate) {}
61 67
62 V8Debugger::~V8Debugger() {} 68 V8Debugger::~V8Debugger() {}
63 69
64 void V8Debugger::enable() { 70 void V8Debugger::enable() {
65 if (m_enableCount++) return; 71 if (m_enableCount++) return;
66 DCHECK(!enabled()); 72 DCHECK(!enabled());
67 v8::HandleScope scope(m_isolate); 73 v8::HandleScope scope(m_isolate);
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 int contextGroupId = 900 int contextGroupId =
895 m_isolate->InContext() 901 m_isolate->InContext()
896 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) 902 ? m_inspector->contextGroupId(m_isolate->GetCurrentContext())
897 : 0; 903 : 0;
898 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( 904 std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture(
899 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, 905 this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture,
900 taskName); 906 taskName);
901 if (chain) { 907 if (chain) {
902 m_asyncTaskStacks[task] = std::move(chain); 908 m_asyncTaskStacks[task] = std::move(chain);
903 if (recurring) m_recurringTasks.insert(task); 909 if (recurring) m_recurringTasks.insert(task);
910 int id = ++m_lastId;
911 m_rawIdToId[task] = id;
912 m_idToRawId[id] = task;
913 while (m_idToRawId.size() > kMaxAsyncTaskStacks) {
dgozman 2016/12/16 23:59:49 while -> if ?
kozy 2016/12/17 01:12:41 Done.
914 void* taskToRemove = m_idToRawId.begin()->second;
915 asyncTaskCanceled(taskToRemove);
916 }
904 } 917 }
905 } 918 }
906 919
907 void V8Debugger::asyncTaskCanceled(void* task) { 920 void V8Debugger::asyncTaskCanceled(void* task) {
dgozman 2016/12/16 23:59:49 Note that task can be messing from any of our maps
kozy 2016/12/17 01:12:41 Done.
908 if (!m_maxAsyncCallStackDepth) return; 921 if (!m_maxAsyncCallStackDepth) return;
909 m_asyncTaskStacks.erase(task); 922 m_asyncTaskStacks.erase(task);
910 m_recurringTasks.erase(task); 923 m_recurringTasks.erase(task);
924 auto it = m_rawIdToId.find(task);
925 m_idToRawId.erase(it->second);
926 m_rawIdToId.erase(it);
911 } 927 }
912 928
913 void V8Debugger::asyncTaskStarted(void* task) { 929 void V8Debugger::asyncTaskStarted(void* task) {
914 if (!m_maxAsyncCallStackDepth) return; 930 if (!m_maxAsyncCallStackDepth) return;
915 m_currentTasks.push_back(task); 931 m_currentTasks.push_back(task);
916 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task); 932 AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find(task);
917 // Needs to support following order of events: 933 // Needs to support following order of events:
918 // - asyncTaskScheduled 934 // - asyncTaskScheduled
919 // <-- attached here --> 935 // <-- attached here -->
920 // - asyncTaskStarted 936 // - asyncTaskStarted
921 // - asyncTaskCanceled <-- canceled before finished 937 // - asyncTaskCanceled <-- canceled before finished
922 // <-- async stack requested here --> 938 // <-- async stack requested here -->
923 // - asyncTaskFinished 939 // - asyncTaskFinished
924 std::unique_ptr<V8StackTraceImpl> stack; 940 std::unique_ptr<V8StackTraceImpl> stack;
925 if (stackIt != m_asyncTaskStacks.end() && stackIt->second) 941 if (stackIt != m_asyncTaskStacks.end() && stackIt->second)
926 stack = stackIt->second->cloneImpl(); 942 stack = stackIt->second->cloneImpl();
927 m_currentStacks.push_back(std::move(stack)); 943 m_currentStacks.push_back(std::move(stack));
928 } 944 }
929 945
930 void V8Debugger::asyncTaskFinished(void* task) { 946 void V8Debugger::asyncTaskFinished(void* task) {
931 if (!m_maxAsyncCallStackDepth) return; 947 if (!m_maxAsyncCallStackDepth) return;
932 // We could start instrumenting half way and the stack is empty. 948 // We could start instrumenting half way and the stack is empty.
933 if (!m_currentStacks.size()) return; 949 if (!m_currentStacks.size()) return;
934 950
935 DCHECK(m_currentTasks.back() == task); 951 DCHECK(m_currentTasks.back() == task);
936 m_currentTasks.pop_back(); 952 m_currentTasks.pop_back();
937 953
938 m_currentStacks.pop_back(); 954 m_currentStacks.pop_back();
939 if (m_recurringTasks.find(task) == m_recurringTasks.end()) 955 if (m_recurringTasks.find(task) == m_recurringTasks.end()) {
940 m_asyncTaskStacks.erase(task); 956 m_asyncTaskStacks.erase(task);
957 auto it = m_rawIdToId.find(task);
958 m_idToRawId.erase(it->second);
959 m_rawIdToId.erase(it);
960 }
941 } 961 }
942 962
943 void V8Debugger::allAsyncTasksCanceled() { 963 void V8Debugger::allAsyncTasksCanceled() {
944 m_asyncTaskStacks.clear(); 964 m_asyncTaskStacks.clear();
945 m_recurringTasks.clear(); 965 m_recurringTasks.clear();
946 m_currentStacks.clear(); 966 m_currentStacks.clear();
947 m_currentTasks.clear(); 967 m_currentTasks.clear();
968 m_idToRawId.clear();
969 m_rawIdToId.clear();
970 m_lastId = 0;
948 } 971 }
949 972
950 void V8Debugger::muteScriptParsedEvents() { 973 void V8Debugger::muteScriptParsedEvents() {
951 ++m_ignoreScriptParsedEventsCounter; 974 ++m_ignoreScriptParsedEventsCounter;
952 } 975 }
953 976
954 void V8Debugger::unmuteScriptParsedEvents() { 977 void V8Debugger::unmuteScriptParsedEvents() {
955 --m_ignoreScriptParsedEventsCounter; 978 --m_ignoreScriptParsedEventsCounter;
956 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0); 979 DCHECK_GE(m_ignoreScriptParsedEventsCounter, 0);
957 } 980 }
958 981
959 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace( 982 std::unique_ptr<V8StackTraceImpl> V8Debugger::captureStackTrace(
960 bool fullStack) { 983 bool fullStack) {
961 if (!m_isolate->InContext()) return nullptr; 984 if (!m_isolate->InContext()) return nullptr;
962 985
963 v8::HandleScope handles(m_isolate); 986 v8::HandleScope handles(m_isolate);
964 int contextGroupId = 987 int contextGroupId =
965 m_inspector->contextGroupId(m_isolate->GetCurrentContext()); 988 m_inspector->contextGroupId(m_isolate->GetCurrentContext());
966 if (!contextGroupId) return nullptr; 989 if (!contextGroupId) return nullptr;
967 990
968 size_t stackSize = 991 size_t stackSize =
969 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1; 992 fullStack ? V8StackTraceImpl::maxCallStackSizeToCapture : 1;
970 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId)) 993 if (m_inspector->enabledRuntimeAgentForGroup(contextGroupId))
971 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture; 994 stackSize = V8StackTraceImpl::maxCallStackSizeToCapture;
972 995
973 return V8StackTraceImpl::capture(this, contextGroupId, stackSize); 996 return V8StackTraceImpl::capture(this, contextGroupId, stackSize);
974 } 997 }
975 998
976 } // namespace v8_inspector 999 } // namespace v8_inspector
OLDNEW
« src/inspector/v8-debugger.h ('K') | « src/inspector/v8-debugger.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698