Index: src/inspector/v8-debugger.cc |
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc |
index 0f8eaf640f32582219e7a98f5aa4eb393c3d9216..b764dd5aa5c7bee9163b3238d75f76f891df0051 100644 |
--- a/src/inspector/v8-debugger.cc |
+++ b/src/inspector/v8-debugger.cc |
@@ -571,6 +571,9 @@ void V8Debugger::PromiseEventOccurred(v8::debug::PromiseDebugActionType type, |
// namespace of such ids, managed by src/js/promise.js. |
void* ptr = reinterpret_cast<void*>(id * 2 + 1); |
switch (type) { |
+ case v8::debug::kDebugPromiseCreated: |
+ asyncTaskCreated(ptr); |
+ break; |
case v8::debug::kDebugEnqueueAsyncFunction: |
asyncTaskScheduled("async function", ptr, true); |
break; |
@@ -858,6 +861,30 @@ void V8Debugger::setAsyncCallStackDepth(V8DebuggerAgentImpl* agent, int depth) { |
if (!maxAsyncCallStackDepth) allAsyncTasksCanceled(); |
} |
+void V8Debugger::registerAsyncTaskIfNeeded(void* task) { |
+ if (m_taskToId.find(task) != m_taskToId.end()) return; |
+ |
+ int id = ++m_lastTaskId; |
+ m_taskToId[task] = id; |
+ m_idToTask[id] = task; |
+ if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
+ void* taskToRemove = m_idToTask.begin()->second; |
+ asyncTaskCanceled(taskToRemove); |
+ } |
+} |
+ |
+void V8Debugger::asyncTaskCreated(void* task) { |
+ if (!m_maxAsyncCallStackDepth) return; |
+ v8::HandleScope scope(m_isolate); |
+ std::unique_ptr<V8StackTraceImpl> chain = |
+ V8StackTraceImpl::capture(this, 0, 1, String16()); |
dgozman
2017/01/24 01:02:41
Comment that we don't need contextgroupid.
kozy
2017/01/24 21:43:39
Done.
|
+ if (chain) { |
+ String16 s = chain->buildInspectorObjectImpl()->serialize(); |
dgozman
2017/01/24 01:02:41
Remove.
kozy
2017/01/24 21:43:39
Done.
|
+ m_asyncTaskCreatedStacks[task] = std::move(chain); |
dgozman
2017/01/24 01:02:41
Should we do this after registering?
kozy
2017/01/24 21:43:39
it should be called after, otherwise we could canc
|
+ registerAsyncTaskIfNeeded(task); |
+ } |
+} |
+ |
void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
bool recurring) { |
if (!m_maxAsyncCallStackDepth) return; |
@@ -872,25 +899,23 @@ void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
m_isolate->InContext() |
? m_inspector->contextGroupId(m_isolate->GetCurrentContext()) |
: 0; |
+ auto itCreation = m_asyncTaskCreatedStacks.find(task); |
std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( |
this, contextGroupId, V8StackTraceImpl::maxCallStackSizeToCapture, |
- taskName); |
+ taskName, itCreation != m_asyncTaskCreatedStacks.end() |
+ ? itCreation->second->cloneImpl() |
+ : nullptr); |
if (chain) { |
m_asyncTaskStacks[task] = std::move(chain); |
if (recurring) m_recurringTasks.insert(task); |
- int id = ++m_lastTaskId; |
- m_taskToId[task] = id; |
- m_idToTask[id] = task; |
- if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
- void* taskToRemove = m_idToTask.begin()->second; |
- asyncTaskCanceled(taskToRemove); |
- } |
+ registerAsyncTaskIfNeeded(task); |
} |
} |
void V8Debugger::asyncTaskCanceled(void* task) { |
if (!m_maxAsyncCallStackDepth) return; |
m_asyncTaskStacks.erase(task); |
+ m_asyncTaskCreatedStacks.erase(task); |
m_recurringTasks.erase(task); |
auto it = m_taskToId.find(task); |
if (it == m_taskToId.end()) return; |
@@ -926,6 +951,7 @@ void V8Debugger::asyncTaskFinished(void* task) { |
m_currentStacks.pop_back(); |
if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
m_asyncTaskStacks.erase(task); |
+ m_asyncTaskCreatedStacks.erase(task); |
dgozman
2017/01/24 01:02:41
Let's call asyncTaskCanceled here?
kozy
2017/01/24 21:43:39
Done.
|
auto it = m_taskToId.find(task); |
if (it == m_taskToId.end()) return; |
m_idToTask.erase(it->second); |
@@ -935,6 +961,7 @@ void V8Debugger::asyncTaskFinished(void* task) { |
void V8Debugger::allAsyncTasksCanceled() { |
m_asyncTaskStacks.clear(); |
+ m_asyncTaskCreatedStacks.clear(); |
m_recurringTasks.clear(); |
m_currentStacks.clear(); |
m_currentTasks.clear(); |