Index: src/inspector/v8-debugger.cc |
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc |
index f4c3ca5813a05249ba56d1278fde1a9561ddee80..2668df89289820d54c413d4c513ba8864d35f255 100644 |
--- a/src/inspector/v8-debugger.cc |
+++ b/src/inspector/v8-debugger.cc |
@@ -335,7 +335,10 @@ void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) { |
m_targetContextGroupId != targetContextGroupId) { |
return; |
} |
+ DCHECK(m_targetContextGroupId == targetContextGroupId || |
+ !m_targetContextGroupId); |
m_targetContextGroupId = targetContextGroupId; |
+ m_breakRequested = pause; |
if (pause) |
v8::debug::DebugBreak(m_isolate); |
else |
@@ -364,6 +367,8 @@ void V8Debugger::stepIntoStatement(int targetContextGroupId) { |
DCHECK(isPaused()); |
DCHECK(!m_executionState.IsEmpty()); |
DCHECK(targetContextGroupId); |
+ DCHECK(m_targetContextGroupId == targetContextGroupId || |
+ !m_targetContextGroupId); |
dgozman
2017/03/28 23:20:50
Merge with previous DCHECK and simplify it :-)
kozy
2017/03/28 23:49:49
this dcheck is redundant so removed.
|
m_targetContextGroupId = targetContextGroupId; |
v8::debug::PrepareStep(m_isolate, v8::debug::StepIn); |
continueProgram(); |
@@ -373,6 +378,8 @@ void V8Debugger::stepOverStatement(int targetContextGroupId) { |
DCHECK(isPaused()); |
DCHECK(!m_executionState.IsEmpty()); |
DCHECK(targetContextGroupId); |
+ DCHECK(m_targetContextGroupId == targetContextGroupId || |
dgozman
2017/03/28 23:20:50
everywhere
kozy
2017/03/28 23:49:49
Done.
|
+ !m_targetContextGroupId); |
m_targetContextGroupId = targetContextGroupId; |
v8::debug::PrepareStep(m_isolate, v8::debug::StepNext); |
continueProgram(); |
@@ -382,11 +389,27 @@ void V8Debugger::stepOutOfFunction(int targetContextGroupId) { |
DCHECK(isPaused()); |
DCHECK(!m_executionState.IsEmpty()); |
DCHECK(targetContextGroupId); |
+ DCHECK(m_targetContextGroupId == targetContextGroupId || |
+ !m_targetContextGroupId); |
m_targetContextGroupId = targetContextGroupId; |
v8::debug::PrepareStep(m_isolate, v8::debug::StepOut); |
continueProgram(); |
} |
+void V8Debugger::scheduleStepIntoAsync( |
+ std::unique_ptr<ScheduleStepIntoAsyncCallback> callback, |
+ int targetContextGroupId) { |
+ DCHECK(isPaused()); |
+ DCHECK(!m_executionState.IsEmpty()); |
+ DCHECK(targetContextGroupId); |
+ if (m_stepIntoAsyncCallback) { |
+ m_stepIntoAsyncCallback->sendFailure(Response::Error( |
+ "Current scheduled step into async was overriden with new one.")); |
+ } |
+ m_targetContextGroupId = targetContextGroupId; |
+ m_stepIntoAsyncCallback = std::move(callback); |
+} |
+ |
Response V8Debugger::setScriptSource( |
const String16& sourceID, v8::Local<v8::String> newSource, bool dryRun, |
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails, |
@@ -522,6 +545,11 @@ void V8Debugger::handleProgramBreak(v8::Local<v8::Context> pausedContext, |
return; |
} |
m_targetContextGroupId = 0; |
+ if (m_stepIntoAsyncCallback) { |
+ m_stepIntoAsyncCallback->sendFailure( |
+ Response::Error("No async tasks were scheduled before pause.")); |
+ m_stepIntoAsyncCallback.reset(); |
+ } |
V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup( |
m_inspector->contextGroupId(pausedContext)); |
if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return; |
@@ -633,25 +661,25 @@ void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context, |
if (!m_maxAsyncCallStackDepth) return; |
switch (type) { |
case v8::debug::kDebugPromiseCreated: |
- asyncTaskCreated(ptr, parentPtr); |
+ asyncTaskCreatedForStack(ptr, parentPtr); |
break; |
case v8::debug::kDebugEnqueueAsyncFunction: |
- asyncTaskScheduled("async function", ptr, true); |
+ asyncTaskScheduledForStack("async function", ptr, true); |
break; |
case v8::debug::kDebugEnqueuePromiseResolve: |
- asyncTaskScheduled("Promise.resolve", ptr, true); |
+ asyncTaskScheduledForStack("Promise.resolve", ptr, true); |
break; |
case v8::debug::kDebugEnqueuePromiseReject: |
- asyncTaskScheduled("Promise.reject", ptr, true); |
+ asyncTaskScheduledForStack("Promise.reject", ptr, true); |
break; |
case v8::debug::kDebugPromiseCollected: |
- asyncTaskCanceled(ptr); |
+ asyncTaskCanceledForStack(ptr); |
break; |
case v8::debug::kDebugWillHandle: |
- asyncTaskStarted(ptr); |
+ asyncTaskStartedForStack(ptr); |
break; |
case v8::debug::kDebugDidHandle: |
- asyncTaskFinished(ptr); |
+ asyncTaskFinishedForStack(ptr); |
break; |
} |
} |
@@ -679,20 +707,21 @@ void V8Debugger::handleAsyncTaskStepping(v8::Local<v8::Context> context, |
m_inspector->enabledDebuggerAgentForGroup(contextGroupId); |
if (!agent) return; |
if (createdByUser && type == v8::debug::kDebugPromiseCreated) { |
- if (agent->shouldBreakInScheduledAsyncTask()) { |
+ if (contextGroupId == m_targetContextGroupId && m_stepIntoAsyncCallback) { |
m_taskWithScheduledBreak = task; |
v8::debug::ClearStepping(m_isolate); |
+ m_stepIntoAsyncCallback->sendSuccess(); |
+ m_stepIntoAsyncCallback.reset(); |
} |
return; |
} |
if (!isScheduledTask) return; |
if (type == v8::debug::kDebugWillHandle) { |
- agent->schedulePauseOnNextStatement( |
- protocol::Debugger::Paused::ReasonEnum::Other, nullptr); |
+ if (!m_breakRequested) v8::debug::DebugBreak(m_isolate); |
return; |
} |
DCHECK(type == v8::debug::kDebugDidHandle); |
- agent->cancelPauseOnNextStatement(); |
+ if (!m_breakRequested) v8::debug::CancelDebugBreak(m_isolate); |
m_taskWithScheduledBreak = nullptr; |
} |
@@ -869,11 +898,11 @@ void V8Debugger::registerAsyncTaskIfNeeded(void* task) { |
m_idToTask[id] = task; |
if (static_cast<int>(m_idToTask.size()) > m_maxAsyncCallStacks) { |
void* taskToRemove = m_idToTask.begin()->second; |
- asyncTaskCanceled(taskToRemove); |
+ asyncTaskCanceledForStack(taskToRemove); |
} |
} |
-void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { |
+void V8Debugger::asyncTaskCreatedForStack(void* task, void* parentTask) { |
if (!m_maxAsyncCallStackDepth) return; |
if (parentTask) m_parentTask[task] = parentTask; |
v8::HandleScope scope(m_isolate); |
@@ -891,12 +920,39 @@ void V8Debugger::asyncTaskCreated(void* task, void* parentTask) { |
void V8Debugger::asyncTaskScheduled(const StringView& taskName, void* task, |
bool recurring) { |
- if (!m_maxAsyncCallStackDepth) return; |
- asyncTaskScheduled(toString16(taskName), task, recurring); |
+ asyncTaskScheduledForStack(toString16(taskName), task, recurring); |
+ if (currentContextGroupId() == m_targetContextGroupId && |
+ m_stepIntoAsyncCallback) { |
+ m_taskWithScheduledBreak = task; |
+ v8::debug::ClearStepping(m_isolate); |
+ m_stepIntoAsyncCallback->sendSuccess(); |
+ m_stepIntoAsyncCallback.reset(); |
+ } |
} |
-void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
- bool recurring) { |
+void V8Debugger::asyncTaskCanceled(void* task) { |
+ asyncTaskCanceledForStack(task); |
+ if (task == m_taskWithScheduledBreak) { |
+ m_taskWithScheduledBreak = nullptr; |
+ } |
+} |
+ |
+void V8Debugger::asyncTaskStarted(void* task) { |
+ asyncTaskStartedForStack(task); |
+ if (task == m_taskWithScheduledBreak) { |
+ if (!m_breakRequested) v8::debug::DebugBreak(m_isolate); |
+ } |
+} |
+ |
+void V8Debugger::asyncTaskFinished(void* task) { |
+ asyncTaskFinishedForStack(task); |
+ if (task == m_taskWithScheduledBreak) { |
+ if (!m_breakRequested) v8::debug::CancelDebugBreak(m_isolate); |
+ } |
+} |
+ |
+void V8Debugger::asyncTaskScheduledForStack(const String16& taskName, |
+ void* task, bool recurring) { |
if (!m_maxAsyncCallStackDepth) return; |
v8::HandleScope scope(m_isolate); |
std::unique_ptr<V8StackTraceImpl> chain = V8StackTraceImpl::capture( |
@@ -909,7 +965,7 @@ void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task, |
} |
} |
-void V8Debugger::asyncTaskCanceled(void* task) { |
+void V8Debugger::asyncTaskCanceledForStack(void* task) { |
if (!m_maxAsyncCallStackDepth) return; |
m_asyncTaskStacks.erase(task); |
m_recurringTasks.erase(task); |
@@ -921,7 +977,7 @@ void V8Debugger::asyncTaskCanceled(void* task) { |
m_taskToId.erase(it); |
} |
-void V8Debugger::asyncTaskStarted(void* task) { |
+void V8Debugger::asyncTaskStartedForStack(void* task) { |
if (!m_maxAsyncCallStackDepth) return; |
m_currentTasks.push_back(task); |
auto parentIt = m_parentTask.find(task); |
@@ -944,7 +1000,7 @@ void V8Debugger::asyncTaskStarted(void* task) { |
m_currentStacks.push_back(std::move(stack)); |
} |
-void V8Debugger::asyncTaskFinished(void* task) { |
+void V8Debugger::asyncTaskFinishedForStack(void* task) { |
if (!m_maxAsyncCallStackDepth) return; |
// We could start instrumenting half way and the stack is empty. |
if (!m_currentStacks.size()) return; |
@@ -954,7 +1010,7 @@ void V8Debugger::asyncTaskFinished(void* task) { |
m_currentStacks.pop_back(); |
if (m_recurringTasks.find(task) == m_recurringTasks.end()) { |
- asyncTaskCanceled(task); |
+ asyncTaskCanceledForStack(task); |
} |
} |