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

Unified Diff: src/inspector/v8-debugger.cc

Issue 2746743002: [inspector] support setTimeout in Debugger.scheduleStepIntoAsync method (Closed)
Patch Set: addressed comments Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/inspector/v8-debugger.cc
diff --git a/src/inspector/v8-debugger.cc b/src/inspector/v8-debugger.cc
index f4c3ca5813a05249ba56d1278fde1a9561ddee80..3f0fb900825838c2342631d7bd5ce7d1b34d2ea3 100644
--- a/src/inspector/v8-debugger.cc
+++ b/src/inspector/v8-debugger.cc
@@ -336,6 +336,7 @@ void V8Debugger::setPauseOnNextStatement(bool pause, int targetContextGroupId) {
return;
}
m_targetContextGroupId = targetContextGroupId;
+ m_breakRequested = pause;
if (pause)
v8::debug::DebugBreak(m_isolate);
else
@@ -387,6 +388,20 @@ void V8Debugger::stepOutOfFunction(int targetContextGroupId) {
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 +537,12 @@ 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();
+ }
+ m_breakRequested = false;
V8DebuggerAgentImpl* agent = m_inspector->enabledDebuggerAgentForGroup(
m_inspector->contextGroupId(pausedContext));
if (!agent || (agent->skipAllPauses() && !m_scheduledOOMBreak)) return;
@@ -624,78 +645,42 @@ void V8Debugger::PromiseEventOccurred(v8::Local<v8::Context> context,
int id, int parentId,
bool createdByUser) {
// Async task events from Promises are given misaligned pointers to prevent
- // from overlapping with other Blink task identifiers. There is a single
- // namespace of such ids, managed by src/js/promise.js.
- void* ptr = reinterpret_cast<void*>(id * 2 + 1);
- void* parentPtr =
+ // from overlapping with other Blink task identifiers.
+ void* task = reinterpret_cast<void*>(id * 2 + 1);
+ void* parentTask =
parentId ? reinterpret_cast<void*>(parentId * 2 + 1) : nullptr;
- handleAsyncTaskStepping(context, type, ptr, parentPtr, createdByUser);
- if (!m_maxAsyncCallStackDepth) return;
switch (type) {
case v8::debug::kDebugPromiseCreated:
- asyncTaskCreated(ptr, parentPtr);
+ asyncTaskCreatedForStack(task, parentTask);
+ if (createdByUser && parentTask) {
+ v8::Context::Scope contextScope(context);
+ asyncTaskCandidateForStepping(task);
+ }
break;
case v8::debug::kDebugEnqueueAsyncFunction:
- asyncTaskScheduled("async function", ptr, true);
+ asyncTaskScheduledForStack("async function", task, true);
break;
case v8::debug::kDebugEnqueuePromiseResolve:
- asyncTaskScheduled("Promise.resolve", ptr, true);
+ asyncTaskScheduledForStack("Promise.resolve", task, true);
break;
case v8::debug::kDebugEnqueuePromiseReject:
- asyncTaskScheduled("Promise.reject", ptr, true);
+ asyncTaskScheduledForStack("Promise.reject", task, true);
break;
case v8::debug::kDebugPromiseCollected:
- asyncTaskCanceled(ptr);
+ asyncTaskCanceledForStack(task);
+ asyncTaskCanceledForStepping(task);
break;
case v8::debug::kDebugWillHandle:
- asyncTaskStarted(ptr);
+ asyncTaskStartedForStack(task);
+ asyncTaskStartedForStepping(task);
break;
case v8::debug::kDebugDidHandle:
- asyncTaskFinished(ptr);
+ asyncTaskFinishedForStack(task);
+ asyncTaskFinishedForStepping(task);
break;
}
}
-void V8Debugger::handleAsyncTaskStepping(v8::Local<v8::Context> context,
- v8::debug::PromiseDebugActionType type,
- void* task, void* parentTask,
- bool createdByUser) {
- if (type == v8::debug::kDebugEnqueueAsyncFunction ||
- type == v8::debug::kDebugEnqueuePromiseResolve ||
- type == v8::debug::kDebugEnqueuePromiseReject) {
- return;
- }
-
- bool isScheduledTask = task == m_taskWithScheduledBreak;
- if (type == v8::debug::kDebugPromiseCollected) {
- if (isScheduledTask) m_taskWithScheduledBreak = nullptr;
- return;
- }
- if (type == v8::debug::kDebugPromiseCreated && !parentTask) return;
-
- DCHECK(!context.IsEmpty());
- int contextGroupId = m_inspector->contextGroupId(context);
- V8DebuggerAgentImpl* agent =
- m_inspector->enabledDebuggerAgentForGroup(contextGroupId);
- if (!agent) return;
- if (createdByUser && type == v8::debug::kDebugPromiseCreated) {
- if (agent->shouldBreakInScheduledAsyncTask()) {
- m_taskWithScheduledBreak = task;
- v8::debug::ClearStepping(m_isolate);
- }
- return;
- }
- if (!isScheduledTask) return;
- if (type == v8::debug::kDebugWillHandle) {
- agent->schedulePauseOnNextStatement(
- protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
- return;
- }
- DCHECK(type == v8::debug::kDebugDidHandle);
- agent->cancelPauseOnNextStatement();
- m_taskWithScheduledBreak = nullptr;
-}
-
V8StackTraceImpl* V8Debugger::currentAsyncCallChain() {
if (!m_currentStacks.size()) return nullptr;
return m_currentStacks.back().get();
@@ -869,11 +854,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 +876,27 @@ 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);
+ asyncTaskCandidateForStepping(task);
}
-void V8Debugger::asyncTaskScheduled(const String16& taskName, void* task,
- bool recurring) {
+void V8Debugger::asyncTaskCanceled(void* task) {
+ asyncTaskCanceledForStack(task);
+ asyncTaskCanceledForStepping(task);
+}
+
+void V8Debugger::asyncTaskStarted(void* task) {
+ asyncTaskStartedForStack(task);
+ asyncTaskStartedForStepping(task);
+}
+
+void V8Debugger::asyncTaskFinished(void* task) {
+ asyncTaskFinishedForStack(task);
+ asyncTaskFinishedForStepping(task);
+}
+
+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 +909,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 +921,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 +944,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,10 +954,38 @@ void V8Debugger::asyncTaskFinished(void* task) {
m_currentStacks.pop_back();
if (m_recurringTasks.find(task) == m_recurringTasks.end()) {
- asyncTaskCanceled(task);
+ asyncTaskCanceledForStack(task);
}
}
+void V8Debugger::asyncTaskCandidateForStepping(void* task) {
+ if (!m_stepIntoAsyncCallback) return;
+ DCHECK(m_targetContextGroupId);
+ if (currentContextGroupId() != m_targetContextGroupId) return;
+ m_taskWithScheduledBreak = task;
+ v8::debug::ClearStepping(m_isolate);
+ m_stepIntoAsyncCallback->sendSuccess();
+ m_stepIntoAsyncCallback.reset();
+}
+
+void V8Debugger::asyncTaskStartedForStepping(void* task) {
+ if (m_breakRequested) return;
+ if (task != m_taskWithScheduledBreak) return;
+ v8::debug::DebugBreak(m_isolate);
+}
+
+void V8Debugger::asyncTaskFinishedForStepping(void* task) {
+ if (task != m_taskWithScheduledBreak) return;
+ m_taskWithScheduledBreak = nullptr;
+ if (m_breakRequested) return;
+ v8::debug::CancelDebugBreak(m_isolate);
+}
+
+void V8Debugger::asyncTaskCanceledForStepping(void* task) {
+ if (task != m_taskWithScheduledBreak) return;
+ m_taskWithScheduledBreak = nullptr;
+}
+
void V8Debugger::allAsyncTasksCanceled() {
m_asyncTaskStacks.clear();
m_recurringTasks.clear();
« no previous file with comments | « src/inspector/v8-debugger.h ('k') | src/inspector/v8-debugger-agent-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698