Commit 079c0fd8 authored by Alexey Kozyatinskiy's avatar Alexey Kozyatinskiy Committed by Commit Bot

[inspector] added new way to step into async task

It is preparation step for step-into-worker. There are few changes:
- added breakOnAsyncCall flag for Debugger.stepInto. When flag is set
  and async task is scheduled before step-into finished, we pause
  execution with additional Debugger.paused event. This event contains
  additional scheduledAsyncTaskId field.
- added Debugger.pauseOnAsyncTask. This method will pause execution as
  soon as given async task is started.

This mechanism is replacement for Debugger.scheduleStepIntoAsync which
can not be used between multiple targets.

As result we can split async task scheduling in one target and
requesting break for this async task running in another target.

R=pfeldman@chromium.org

Bug: chromium:778796
Cq-Include-Trybots: master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I77be0c880d91253d333c54a23a4c084e7b8549e9
Reviewed-on: https://chromium-review.googlesource.com/750071Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarPavel Feldman <pfeldman@chromium.org>
Commit-Queue: Aleksey Kozyatinskiy <kozyatinskiy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49127}
parent 70d36f67
......@@ -1861,9 +1861,7 @@ void Debug::OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id,
int parent_id) {
if (in_debug_scope() || ignore_events()) return;
if (!debug_delegate_) return;
SuppressDebug while_processing(this);
PostponeInterruptsScope no_interrupts(isolate_);
DisableBreak no_recursive_break(this);
bool created_by_user = false;
if (type == debug::kDebugPromiseCreated) {
JavaScriptFrameIterator it(isolate_);
......
......@@ -204,6 +204,11 @@
{ "name": "parent", "$ref": "StackTrace", "optional": true, "description": "Asynchronous JavaScript stack trace that preceded this stack, if available." },
{ "name": "promiseCreationFrame", "$ref": "CallFrame", "optional": true, "experimental": true, "description": "Creation frame of the Promise which produced the next synchronous trace when resolved, if available." }
]
},
{
"id": "AsyncTaskId",
"type": "string",
"experimental": true
}
],
"commands": [
......@@ -588,12 +593,22 @@
],
"description": "Continues execution until specific location is reached."
},
{
"name": "pauseOnAsyncTask",
"parameters": [
{ "name": "asyncTaskId", "$ref": "Runtime.AsyncTaskId", "description": "Debugger will pause when given async task is started." }
],
"experimental": true
},
{
"name": "stepOver",
"description": "Steps over the statement."
},
{
"name": "stepInto",
"parameters": [
{ "name": "breakOnAsyncCall", "type": "boolean", "optional": true, "experimental": true, "description": "Debugger will issue additional Debugger.paused notification if any async task is scheduled before next pause." }
],
"description": "Steps into the function call."
},
{
......@@ -606,7 +621,7 @@
},
{
"name": "scheduleStepIntoAsync",
"description": "Steps into next scheduled async task if any is scheduled before next pause. Returns success when async task is actually scheduled, returns error if no task were scheduled or another scheduleStepIntoAsync was called.",
"description": "This method is deprecated - use Debugger.stepInto with breakOnAsyncCall and Debugger.pauseOnAsyncTask instead. Steps into next scheduled async task if any is scheduled before next pause. Returns success when async task is actually scheduled, returns error if no task were scheduled or another scheduleStepIntoAsync was called.",
"experimental": true
},
{
......@@ -788,7 +803,8 @@
{ "name": "reason", "type": "string", "enum": [ "XHR", "DOM", "EventListener", "exception", "assert", "debugCommand", "promiseRejection", "OOM", "other", "ambiguous" ], "description": "Pause reason." },
{ "name": "data", "type": "object", "optional": true, "description": "Object containing break-specific auxiliary properties." },
{ "name": "hitBreakpoints", "type": "array", "optional": true, "items": { "type": "string" }, "description": "Hit breakpoints IDs" },
{ "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any." }
{ "name": "asyncStackTrace", "$ref": "Runtime.StackTrace", "optional": true, "description": "Async stack trace, if any." },
{ "name": "scheduledAsyncTaskId", "$ref": "Runtime.AsyncTaskId", "optional": true, "experimental": true, "description": "Scheduled async task id." }
],
"description": "Fired when the virtual machine stopped on breakpoint or exception or any other stop criteria."
},
......
......@@ -24,8 +24,8 @@ bool isSpaceOrNewLine(UChar c) {
return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9));
}
int charactersToInteger(const UChar* characters, size_t length,
bool* ok = nullptr) {
int64_t charactersToInteger(const UChar* characters, size_t length,
bool* ok = nullptr) {
std::vector<char> buffer;
buffer.reserve(length + 1);
for (size_t i = 0; i < length; ++i) {
......@@ -39,12 +39,9 @@ int charactersToInteger(const UChar* characters, size_t length,
char* endptr;
int64_t result =
static_cast<int64_t>(std::strtol(buffer.data(), &endptr, 10));
if (ok) {
*ok = !(*endptr) && result <= std::numeric_limits<int>::max() &&
result >= std::numeric_limits<int>::min();
}
return static_cast<int>(result);
static_cast<int64_t>(std::strtoll(buffer.data(), &endptr, 10));
if (ok) *ok = !(*endptr);
return result;
}
const UChar replacementCharacter = 0xFFFD;
......@@ -430,10 +427,19 @@ String16 String16::fromDouble(double number, int precision) {
return String16(str.get());
}
int String16::toInteger(bool* ok) const {
int64_t String16::toInteger64(bool* ok) const {
return charactersToInteger(characters16(), length(), ok);
}
int String16::toInteger(bool* ok) const {
int64_t result = toInteger64(ok);
if (ok && *ok) {
*ok = result <= std::numeric_limits<int>::max() &&
result >= std::numeric_limits<int>::min();
}
return static_cast<int>(result);
}
String16 String16::stripWhiteSpace() const {
if (!length()) return String16();
......
......@@ -37,6 +37,7 @@ class String16 {
static String16 fromDouble(double);
static String16 fromDouble(double, int precision);
int64_t toInteger64(bool* ok = nullptr) const;
int toInteger(bool* ok = nullptr) const;
String16 stripWhiteSpace() const;
const UChar* characters16() const { return m_impl.c_str(); }
......
......@@ -951,10 +951,11 @@ Response V8DebuggerAgentImpl::stepOver() {
return Response::OK();
}
Response V8DebuggerAgentImpl::stepInto() {
Response V8DebuggerAgentImpl::stepInto(Maybe<bool> inBreakOnAsyncCall) {
if (!isPaused()) return Response::Error(kDebuggerNotPaused);
m_session->releaseObjectGroup(kBacktraceObjectGroup);
m_debugger->stepIntoStatement(m_session->contextGroupId());
m_debugger->stepIntoStatement(m_session->contextGroupId(),
inBreakOnAsyncCall.fromMaybe(false));
return Response::OK();
}
......@@ -975,6 +976,17 @@ void V8DebuggerAgentImpl::scheduleStepIntoAsync(
m_session->contextGroupId());
}
Response V8DebuggerAgentImpl::pauseOnAsyncTask(const String16& inAsyncTaskId) {
bool isOk = false;
int64_t task = inAsyncTaskId.toInteger64(&isOk);
if (!isOk) {
return Response::Error("Invalid asyncTaskId");
}
m_debugger->pauseOnAsyncTask(m_session->contextGroupId(),
reinterpret_cast<void*>(task));
return Response::OK();
}
Response V8DebuggerAgentImpl::setPauseOnExceptions(
const String16& stringPauseState) {
if (!enabled()) return Response::Error(kDebuggerNotEnabled);
......@@ -1476,9 +1488,18 @@ void V8DebuggerAgentImpl::didPause(
std::unique_ptr<Array<CallFrame>> protocolCallFrames;
Response response = currentCallFrames(&protocolCallFrames);
if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
Maybe<String16> scheduledAsyncTaskId;
void* rawScheduledAsyncTask = m_debugger->scheduledAsyncTask();
if (rawScheduledAsyncTask) {
String16Builder builder;
builder.appendNumber(reinterpret_cast<size_t>(rawScheduledAsyncTask));
scheduledAsyncTaskId = builder.toString();
}
m_frontend.paused(std::move(protocolCallFrames), breakReason,
std::move(breakAuxData), std::move(hitBreakpointIds),
currentAsyncStackTrace());
currentAsyncStackTrace(), std::move(scheduledAsyncTaskId));
}
void V8DebuggerAgentImpl::didContinue() {
......
......@@ -84,10 +84,11 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
Response pause() override;
Response resume() override;
Response stepOver() override;
Response stepInto() override;
Response stepInto(Maybe<bool> inBreakOnAsyncCall) override;
Response stepOut() override;
void scheduleStepIntoAsync(
std::unique_ptr<ScheduleStepIntoAsyncCallback> callback) override;
Response pauseOnAsyncTask(const String16& inAsyncTaskId) override;
Response setPauseOnExceptions(const String16& pauseState) override;
Response evaluateOnCallFrame(
const String16& callFrameId, const String16& expression,
......
......@@ -185,6 +185,7 @@ void V8Debugger::disable() {
clearContinueToLocation();
allAsyncTasksCanceled();
m_taskWithScheduledBreak = nullptr;
m_pauseOnAsyncCall = false;
m_wasmTranslation.Clear();
v8::debug::SetDebugDelegate(m_isolate, nullptr);
v8::debug::SetOutOfMemoryCallback(m_isolate, nullptr, nullptr);
......@@ -284,10 +285,12 @@ void V8Debugger::breakProgramOnAssert(int targetContextGroupId) {
v8::debug::BreakRightNow(m_isolate);
}
void V8Debugger::stepIntoStatement(int targetContextGroupId) {
void V8Debugger::stepIntoStatement(int targetContextGroupId,
bool breakOnAsyncCall) {
DCHECK(isPaused());
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
m_pauseOnAsyncCall = breakOnAsyncCall;
v8::debug::PrepareStep(m_isolate, v8::debug::StepIn);
continueProgram(targetContextGroupId);
}
......@@ -321,6 +324,12 @@ void V8Debugger::scheduleStepIntoAsync(
m_stepIntoAsyncCallback = std::move(callback);
}
void V8Debugger::pauseOnAsyncTask(int targetContextGroupId, void* task) {
DCHECK(targetContextGroupId);
m_targetContextGroupId = targetContextGroupId;
m_taskWithScheduledBreak = task;
}
Response V8Debugger::continueToLocation(
int targetContextGroupId, V8DebuggerScript* script,
std::unique_ptr<protocol::Debugger::Location> location,
......@@ -387,6 +396,8 @@ void V8Debugger::handleProgramBreak(
m_stepIntoAsyncCallback.reset();
}
m_breakRequested = false;
m_pauseOnAsyncCall = false;
m_taskWithScheduledBreak = nullptr;
bool scheduledOOMBreak = m_scheduledOOMBreak;
bool scheduledAssertBreak = m_scheduledAssertBreak;
......@@ -758,8 +769,8 @@ void V8Debugger::asyncTaskStarted(void* task) {
}
void V8Debugger::asyncTaskFinished(void* task) {
asyncTaskFinishedForStack(task);
asyncTaskFinishedForStepping(task);
asyncTaskFinishedForStack(task);
}
void V8Debugger::asyncTaskScheduledForStack(const String16& taskName,
......@@ -835,6 +846,12 @@ void V8Debugger::asyncTaskFinishedForStack(void* task) {
}
void V8Debugger::asyncTaskCandidateForStepping(void* task) {
if (m_pauseOnAsyncCall) {
m_scheduledAsyncTask = task;
breakProgram(m_targetContextGroupId);
m_scheduledAsyncTask = nullptr;
return;
}
if (!m_stepIntoAsyncCallback) return;
DCHECK(m_targetContextGroupId);
if (currentContextGroupId() != m_targetContextGroupId) return;
......@@ -846,6 +863,8 @@ void V8Debugger::asyncTaskCandidateForStepping(void* task) {
void V8Debugger::asyncTaskStartedForStepping(void* task) {
if (m_breakRequested) return;
// TODO(kozyatinskiy): we should search task in async chain to support
// blackboxing.
if (task != m_taskWithScheduledBreak) return;
v8::debug::DebugBreak(m_isolate);
}
......
......@@ -49,12 +49,13 @@ class V8Debugger : public v8::debug::DebugDelegate {
void breakProgramOnAssert(int targetContextGroupId);
void setPauseOnNextStatement(bool, int targetContextGroupId);
void stepIntoStatement(int targetContextGroupId);
void stepIntoStatement(int targetContextGroupId, bool breakOnAsyncCall);
void stepOverStatement(int targetContextGroupId);
void stepOutOfFunction(int targetContextGroupId);
void scheduleStepIntoAsync(
std::unique_ptr<ScheduleStepIntoAsyncCallback> callback,
int targetContextGroupId);
void pauseOnAsyncTask(int targetContextGroupId, void* task);
Response continueToLocation(int targetContextGroupId,
V8DebuggerScript* script,
......@@ -107,6 +108,8 @@ class V8Debugger : public v8::debug::DebugDelegate {
void setMaxAsyncTaskStacksForTest(int limit);
void dumpAsyncTaskStacksStateForTest();
void* scheduledAsyncTask() { return m_scheduledAsyncTask; }
private:
void clearContinueToLocation();
bool shouldContinueToCurrentLocation();
......@@ -202,6 +205,8 @@ class V8Debugger : public v8::debug::DebugDelegate {
bool m_breakRequested = false;
v8::debug::ExceptionBreakState m_pauseOnExceptionsState;
bool m_pauseOnAsyncCall = false;
void* m_scheduledAsyncTask = nullptr;
WasmTranslation m_wasmTranslation;
......
Checks Debugger.scheduleStepIntoAsync.
Running test: testScheduleErrors
paused at:
function testNoScheduledTask() {
#debugger;
return 42;
paused at:
debugger;
#return 42;
}
paused at:
debugger;
return 42;#
}
Running test: testSimple
paused at:
function testSimple() {
#debugger;
Promise.resolve().then(v => v * 2);
paused at:
debugger;
#Promise.resolve().then(v => v * 2);
}
paused at:
debugger;
Promise.resolve().#then(v => v * 2);
}
scheduledAsyncTaskId is set
paused at:
debugger;
Promise.resolve().then(#v => v * 2);
}
Running test: testNotResolvedPromise
paused at:
var p = new Promise(resolve => resolveCallback = resolve);
#debugger;
p.then(v => v * 2);
paused at:
debugger;
p.#then(v => v * 2);
resolveCallback();
paused at:
debugger;
p.#then(v => v * 2);
resolveCallback();
scheduledAsyncTaskId is set
paused at:
debugger;
p.then(#v => v * 2);
resolveCallback();
Running test: testTwoAsyncTasks
paused at:
function testTwoAsyncTasks() {
#debugger;
Promise.resolve().then(v => v * 2);
paused at:
debugger;
#Promise.resolve().then(v => v * 2);
Promise.resolve().then(v => v * 4);
paused at:
debugger;
Promise.resolve().#then(v => v * 2);
Promise.resolve().then(v => v * 4);
scheduledAsyncTaskId is set
paused at:
debugger;
Promise.resolve().then(#v => v * 2);
Promise.resolve().then(v => v * 4);
Running test: testTwoTasksAndGoToSecond
paused at:
function testTwoAsyncTasks() {
#debugger;
Promise.resolve().then(v => v * 2);
paused at:
debugger;
#Promise.resolve().then(v => v * 2);
Promise.resolve().then(v => v * 4);
paused at:
Promise.resolve().then(v => v * 2);
#Promise.resolve().then(v => v * 4);
}
paused at:
Promise.resolve().then(v => v * 2);
Promise.resolve().#then(v => v * 4);
}
scheduledAsyncTaskId is set
paused at:
Promise.resolve().then(v => v * 2);
Promise.resolve().then(#v => v * 4);
}
Running test: testTwoAsyncTasksWithBreak
paused at:
function testTwoAsyncTasksWithBreak() {
#debugger;
Promise.resolve().then(v => v * 2);
paused at:
debugger;
#Promise.resolve().then(v => v * 2);
debugger;
paused at:
debugger;
Promise.resolve().#then(v => v * 2);
debugger;
scheduledAsyncTaskId is set
paused at:
Promise.resolve().then(v => v * 2);
#debugger;
Promise.resolve().then(v => v * 4);
paused at:
debugger;
#Promise.resolve().then(v => v * 4);
}
paused at:
debugger;
Promise.resolve().#then(v => v * 4);
}
scheduledAsyncTaskId is set
paused at:
debugger;
Promise.resolve().then(#v => v * 4);
}
Running test: testPromiseAll
paused at:
function testPromiseAll() {
#debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
paused at:
debugger;
#Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
}
paused at:
debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).#then(v => v * 2);
}
scheduledAsyncTaskId is set
paused at:
debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).then(#v => v * 2);
}
Running test: testWithBlackboxedCode
paused at:
function testBlackboxedCreatePromise() {
#debugger;
createPromise().then(v => v * 2);
paused at:
debugger;
#createPromise().then(v => v * 2);
}
paused at:
debugger;
createPromise().#then(v => v * 2);
}
scheduledAsyncTaskId is set
paused at:
debugger;
createPromise().then(#v => v * 2);
}
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} = InspectorTest.start('Checks Debugger.scheduleStepIntoAsync.');
contextGroup.addScript(`
function testNoScheduledTask() {
debugger;
return 42;
}
function testSimple() {
debugger;
Promise.resolve().then(v => v * 2);
}
function testNotResolvedPromise() {
var resolveCallback;
var p = new Promise(resolve => resolveCallback = resolve);
debugger;
p.then(v => v * 2);
resolveCallback();
}
function testTwoAsyncTasks() {
debugger;
Promise.resolve().then(v => v * 2);
Promise.resolve().then(v => v * 4);
}
function testTwoAsyncTasksWithBreak() {
debugger;
Promise.resolve().then(v => v * 2);
debugger;
Promise.resolve().then(v => v * 4);
}
function testPromiseAll() {
debugger;
Promise.all([ Promise.resolve(), Promise.resolve() ]).then(v => v * 2);
}
function testBlackboxedCreatePromise() {
debugger;
createPromise().then(v => v * 2);
}
//# sourceURL=test.js`);
contextGroup.addScript(`
function createPromise() {
return Promise.resolve().then(v => v * 3).then(v => v * 4);
}
//# sourceURL=framework.js`)
session.setupScriptMap();
Protocol.Debugger.enable();
InspectorTest.runAsyncTestSuite([
async function testScheduleErrors() {
Protocol.Runtime.evaluate({ expression: 'testNoScheduledTask()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testSimple() {
Protocol.Runtime.evaluate({ expression: 'testSimple()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testNotResolvedPromise() {
Protocol.Runtime.evaluate({ expression: 'testNotResolvedPromise()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testTwoAsyncTasks() {
Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasks()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testTwoTasksAndGoToSecond() {
Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasks()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testTwoAsyncTasksWithBreak() {
Protocol.Runtime.evaluate({ expression: 'testTwoAsyncTasksWithBreak()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testPromiseAll() {
Protocol.Runtime.evaluate({ expression: 'testPromiseAll()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
},
async function testWithBlackboxedCode() {
Protocol.Runtime.evaluate({ expression: 'testBlackboxedCreatePromise()' });
await waitPauseAndDumpLocation();
Protocol.Debugger.stepOver();
await waitPauseAndDumpLocation();
await Protocol.Debugger.setBlackboxPatterns({patterns: ['framework\.js'] });
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let scheduledAsyncTaskId = await waitPauseAndDumpLocation();
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
Protocol.Debugger.resume();
await waitPauseAndDumpLocation();
await Protocol.Debugger.resume();
}
]);
async function waitPauseAndDumpLocation() {
var {params:{callFrames, scheduledAsyncTaskId}} = await Protocol.Debugger.oncePaused();
InspectorTest.log('paused at:');
await session.logSourceLocation(callFrames[0].location);
if (scheduledAsyncTaskId) {
InspectorTest.log('scheduledAsyncTaskId is set\n');
}
return scheduledAsyncTaskId;
}
......@@ -21,7 +21,8 @@ paused at:
Running test: testDebuggerStmtBeforeCallback2
paused at:
debugger; setTimeout(() => 1#, 0);debugger;
setTimeout('debugger//should-break-here', 0);
#setTimeout(() => 1, 0);
paused at:
#debugger//should-break-here
......
Test for Debugger.stepInto with breakOnAsyncCall.
Running test: testSetTimeout
(anonymous) (test.js:0:0)
scheduledAsyncTaskId is set
setTimeout (test.js:0:11)
scheduledAsyncTaskId is empty
Running test: testPromiseThen
(anonymous) (test.js:0:2)
scheduledAsyncTaskId is set
p.then (test.js:0:7)
scheduledAsyncTaskId is empty
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
let {session, contextGroup, Protocol} =
InspectorTest.start('Test for Debugger.stepInto with breakOnAsyncCall.');
InspectorTest.runAsyncTestSuite([
async function testSetTimeout() {
Protocol.Debugger.enable();
Protocol.Debugger.pause();
let pausedPromise = Protocol.Debugger.oncePaused();
Protocol.Runtime.evaluate({
expression: 'setTimeout(() => 42, 0)//# sourceURL=test.js'
});
await pausedPromise;
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let {params:{callFrames, scheduledAsyncTaskId}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
if (scheduledAsyncTaskId) {
InspectorTest.log('scheduledAsyncTaskId is set');
}
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
pausedPromise = Protocol.Debugger.oncePaused();
Protocol.Debugger.resume();
({params:{callFrames, scheduledAsyncTaskId}} = await pausedPromise);
session.logCallFrames(callFrames);
if (!scheduledAsyncTaskId) {
InspectorTest.log('scheduledAsyncTaskId is empty');
}
await Protocol.Debugger.disable();
},
async function testPromiseThen() {
Protocol.Debugger.enable();
Protocol.Runtime.evaluate({expression: 'var p = Promise.resolve()'});
Protocol.Debugger.pause();
let pausedPromise = Protocol.Debugger.oncePaused();
Protocol.Runtime.evaluate({expression: 'p.then(() => 42)//# sourceURL=test.js'});
await pausedPromise;
Protocol.Debugger.stepInto({breakOnAsyncCall: true});
let {params:{callFrames, scheduledAsyncTaskId}} = await Protocol.Debugger.oncePaused();
session.logCallFrames(callFrames);
if (scheduledAsyncTaskId) {
InspectorTest.log('scheduledAsyncTaskId is set');
}
Protocol.Debugger.pauseOnAsyncTask({asyncTaskId: scheduledAsyncTaskId});
pausedPromise = Protocol.Debugger.oncePaused();
Protocol.Debugger.resume();
({params:{callFrames, scheduledAsyncTaskId}} = await pausedPromise);
session.logCallFrames(callFrames);
if (!scheduledAsyncTaskId) {
InspectorTest.log('scheduledAsyncTaskId is empty');
}
await Protocol.Debugger.disable();
}
]);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment