Chromium Code Reviews| Index: src/inspector/v8-debugger.cc |
| diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc |
| index 3acb329dae1c17369177da985803ae5877125e1a..458e7111814d2aef1ca21808a3f21fc30fe100fd 100644 |
| --- a/src/inspector/v8-debugger.cc |
| +++ b/src/inspector/v8-debugger.cc |
| @@ -913,10 +913,6 @@ void V8Debugger::asyncTaskCanceledForStack(void* task) { |
| void V8Debugger::asyncTaskStartedForStack(void* task) { |
| if (!m_maxAsyncCallStackDepth) return; |
| - m_currentTasks.push_back(task); |
| - auto parentIt = m_parentTask.find(task); |
| - AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( |
| - parentIt == m_parentTask.end() ? task : parentIt->second); |
| // Needs to support following order of events: |
| // - asyncTaskScheduled |
| // <-- attached here --> |
| @@ -924,15 +920,21 @@ void V8Debugger::asyncTaskStartedForStack(void* task) { |
| // - asyncTaskCanceled <-- canceled before finished |
| // <-- async stack requested here --> |
| // - asyncTaskFinished |
| - std::weak_ptr<AsyncStackTrace> asyncParent; |
| - if (stackIt != m_asyncTaskStacks.end()) asyncParent = stackIt->second; |
| + m_currentTasks.push_back(task); |
| + auto parentIt = m_parentTask.find(task); |
| + AsyncTaskToStackTrace::iterator stackIt = m_asyncTaskStacks.find( |
| + parentIt == m_parentTask.end() ? task : parentIt->second); |
| + if (stackIt != m_asyncTaskStacks.end()) { |
| + m_currentAsyncParent.push_back(stackIt->second.lock()); |
| + } else { |
| + m_currentAsyncParent.emplace_back(); |
| + } |
| auto itCreation = m_asyncTaskCreationStacks.find(task); |
| - if (asyncParent.lock() && itCreation != m_asyncTaskCreationStacks.end()) { |
|
kozy
2017/04/27 18:35:31
this change is essential of this CL.
|
| + if (itCreation != m_asyncTaskCreationStacks.end()) { |
| m_currentAsyncCreation.push_back(itCreation->second.lock()); |
| } else { |
| m_currentAsyncCreation.emplace_back(); |
| } |
| - m_currentAsyncParent.push_back(asyncParent.lock()); |
| } |
| void V8Debugger::asyncTaskFinishedForStack(void* task) { |
| @@ -1039,9 +1041,37 @@ void V8Debugger::collectOldAsyncStacksIfNeeded() { |
| ++it; |
| } |
| } |
| + // We use parent information to provide correct parent stack for promises, |
| + // Promise.resolve().then(...).then(...) |
| + // created task#1 - stack#1 |
| + // scheduled task#1 - stack#2 |
| + // created task#2 -> task#1 - stack#3 |
| + // created task#3 -> task#2 - stack#4 |
| + // ... |
| + // started task#2 - use stack(parent(task#2)) == stack(task#1) == stack#2 |
| + // ... |
| + // 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
|
| + // finished task#2 |
| + // started task#3 - use stack(parent(task#3)) == stack(task#2) == stack#5 |
| + // ... |
| + // scheduled task#3 - stack#6 |
| + // finished task#3 |
| + // Let's consider what parent link is obsolete when we collect stacks: |
| + // stack#1 - (task#2 -> task#1, task#3 -> task#2) |
| + // stack#2 - (task#3 -> task#2) |
| + // stack#3 - (task#3 -> task#2) |
| + // stack#4 - (task#3 -> task#2) |
| + // stack#5 - () |
| + // stack#6 - () |
| + // But in case when we start collecting stacks after getting stack#4 but |
| + // before stack#5 is added we should preserve parent link since original task |
| + // can be scheduled at any time in future and this link will be required to |
| + // get correct parent stack later. It means that we should collect parent link |
| + // in case when there is no creation or schedule stack for parent. |
| for (auto it = m_parentTask.begin(); it != m_parentTask.end();) { |
| if (m_asyncTaskCreationStacks.find(it->second) == |
| - m_asyncTaskCreationStacks.end()) { |
| + m_asyncTaskCreationStacks.end() && |
| + m_asyncTaskStacks.find(it->second) == m_asyncTaskStacks.end()) { |
| it = m_parentTask.erase(it); |
| } else { |
| ++it; |