blob: 78725937c2ed510283b5fd0fedaa3fd3681401d9 [file] [log] [blame]
// 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.
InspectorTest.log('Tests external stack traces');
let contextGroup1 = new InspectorTest.ContextGroup();
let session1 = contextGroup1.connect();
let Protocol1 = session1.Protocol;
let contextGroup2 = new InspectorTest.ContextGroup();
let session2 = contextGroup2.connect();
let Protocol2 = session2.Protocol;
let utilsScript = `
function store(description) {
let buffer = inspector.storeCurrentStackTrace(description);
return '[' + new Int32Array(buffer).join(',') + ']';
}
function started(id) {
inspector.externalAsyncTaskStarted(Int32Array.from(JSON.parse(id)).buffer);
}
function finished(id) {
inspector.externalAsyncTaskFinished(Int32Array.from(JSON.parse(id)).buffer);
}
//# sourceURL=utils.js`;
contextGroup1.addScript(utilsScript);
contextGroup2.addScript(utilsScript);
InspectorTest.runAsyncTestSuite([
async function testDebuggerId() {
InspectorTest.log('Enabling debugger first time..');
let {result: {debuggerId}} = await Protocol1.Debugger.enable();
let firstDebuggerId = debuggerId;
InspectorTest.log('Enabling debugger again..');
({result: {debuggerId}} = await Protocol1.Debugger.enable());
if (firstDebuggerId !== debuggerId) {
InspectorTest.log(
'FAIL: second Debugger.enable returns different debugger id');
} else {
InspectorTest.log(
'> second Debugger.enable returns the same debugger id');
}
InspectorTest.log('Enabling debugger in another context group..');
({result: {debuggerId}} = await Protocol2.Debugger.enable());
if (firstDebuggerId === debuggerId) {
InspectorTest.log(
'FAIL: Debugger.enable in another context group returns the same debugger id');
} else {
InspectorTest.log(
'> Debugger.enable in another context group returns own debugger id');
}
await Protocol2.Debugger.disable();
},
async function testInstrumentation() {
Protocol1.Debugger.enable();
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
let result = await Protocol1.Runtime.evaluate(
{expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
let stackTraceId = result.result.result.objectId;
Protocol1.Runtime.evaluate({
expression: `inspector.externalAsyncTaskStarted(id);
debugger;
inspector.externalAsyncTaskFinished(id);`
});
let {params: {callFrames, asyncStackTraceId}} =
await Protocol1.Debugger.oncePaused();
result = await Protocol1.Debugger.getStackTrace(
{stackTraceId: asyncStackTraceId});
InspectorTest.logMessage(result);
await Protocol1.Debugger.disable();
},
async function testDisableStacksAfterStored() {
Protocol1.Debugger.enable();
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
let result = await Protocol1.Runtime.evaluate(
{expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
let stackTraceId = result.result.result.objectId;
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 0});
Protocol1.Runtime.evaluate({
expression: `inspector.externalAsyncTaskStarted(id);
debugger;
inspector.externalAsyncTaskFinished(id);`
});
let {params: {callFrames, asyncStackTraceId}} =
await Protocol1.Debugger.oncePaused();
if (!asyncStackTraceId) {
InspectorTest.log('> external async stack trace is empty');
} else {
InspectorTest.log('FAIL: external async stack trace is reported');
}
await Protocol1.Debugger.disable();
},
async function testDisableStacksAfterStarted() {
Protocol1.Debugger.enable();
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
let result = await Protocol1.Runtime.evaluate(
{expression: 'id = inspector.storeCurrentStackTrace(\'stack\')'});
let stackTraceId = result.result.result.objectId;
Protocol1.Runtime.evaluate(
{expression: 'inspector.externalAsyncTaskStarted(id);'});
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 0});
Protocol1.Runtime.evaluate({
expression: `debugger;
inspector.externalAsyncTaskFinished(id);`
});
let {params: {callFrames, asyncStackTraceId}} =
await Protocol1.Debugger.oncePaused();
if (!asyncStackTraceId) {
InspectorTest.log('> external async stack trace is empty');
} else {
InspectorTest.log('FAIL: external async stack trace is reported');
}
await Protocol1.Debugger.disable();
},
async function testExternalStacks() {
let debuggerId1 = (await Protocol1.Debugger.enable()).result.debuggerId;
let debuggerId2 = (await Protocol2.Debugger.enable()).result.debuggerId;
Protocol1.Debugger.setAsyncCallStackDepth({maxDepth: 32});
Protocol2.Debugger.setAsyncCallStackDepth({maxDepth: 32});
let stackTraceId1 = (await Protocol1.Runtime.evaluate({
expression: 'store(\'stack\')//# sourceURL=expr1-1.js'
})).result.result.value;
let stackTraceId2 = (await Protocol2.Runtime.evaluate({
expression: `started('${stackTraceId1}');
id = store('stack2');
finished('${stackTraceId1}');
id
//# sourceURL=expr2.js`
})).result.result.value;
Protocol1.Runtime.evaluate({
expression: `started('${stackTraceId2}');
debugger;
finished('${stackTraceId2}');
id
//# sourceURL=expr1-2.js`
});
let {params: {callFrames, asyncStackTraceId}} =
await Protocol1.Debugger.oncePaused();
let debuggers = new Map(
[[debuggerId1, Protocol1.Debugger], [debuggerId2, Protocol2.Debugger]]);
let sessions = new Map([[debuggerId1, session1], [debuggerId2, session2]]);
let currentDebuggerId = debuggerId1;
while (true) {
sessions.get(currentDebuggerId).logCallFrames(callFrames);
if (asyncStackTraceId) {
currentDebuggerId = asyncStackTraceId.debuggerId;
let {result: {stackTrace}} =
await debuggers.get(currentDebuggerId).getStackTrace({
stackTraceId: asyncStackTraceId
});
InspectorTest.log(`-- ${stackTrace.description} --`);
callFrames = stackTrace.callFrames;
asyncStackTraceId = stackTrace.parentId;
} else {
break;
}
}
Protocol1.Debugger.disable();
await Protocol2.Debugger.disable();
}
]);