[stack-trace] Add url to wasm stack traces
Wasm stack traces now show the url to the wasm script. Bug: v8:9762 Change-Id: Ie7feda499ec76bf001dea093efb720ffd691edad Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2051946 Commit-Queue: Kim-Anh Tran <kimanh@chromium.org> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#66302}
This commit is contained in:
parent
5ca49a22d6
commit
b0c4f2b090
@ -581,6 +581,12 @@ Handle<Object> WasmStackFrame::GetFunctionName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
Handle<Object> WasmStackFrame::GetScriptNameOrSourceUrl() {
|
||||
Handle<Script> script = GetScript();
|
||||
DCHECK_EQ(Script::TYPE_WASM, script->type());
|
||||
return ScriptNameOrSourceUrl(script, isolate_);
|
||||
}
|
||||
|
||||
Handle<Object> WasmStackFrame::GetWasmModuleName() {
|
||||
Handle<Object> module_name;
|
||||
Handle<WasmModuleObject> module_object(wasm_instance_->module_object(),
|
||||
|
@ -169,7 +169,7 @@ class WasmStackFrame : public StackFrameBase {
|
||||
|
||||
Handle<Object> GetFileName() override { return Null(); }
|
||||
Handle<Object> GetFunctionName() override;
|
||||
Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); }
|
||||
Handle<Object> GetScriptNameOrSourceUrl() override;
|
||||
Handle<Object> GetMethodName() override { return Null(); }
|
||||
Handle<Object> GetTypeName() override { return Null(); }
|
||||
Handle<Object> GetWasmModuleName() override;
|
||||
|
@ -368,6 +368,16 @@ void SerializeAsmJsWasmStackFrame(Isolate* isolate,
|
||||
return;
|
||||
}
|
||||
|
||||
bool IsAnonymousWasmScript(Isolate* isolate, Handle<StackTraceFrame> frame,
|
||||
Handle<Object> url) {
|
||||
DCHECK(url->IsString());
|
||||
Handle<String> anonymous_prefix =
|
||||
isolate->factory()->InternalizeString(StaticCharVector("wasm://wasm/"));
|
||||
return (StackTraceFrame::IsWasm(frame) &&
|
||||
StringIndexOf(isolate, Handle<String>::cast(url), anonymous_prefix) >=
|
||||
0);
|
||||
}
|
||||
|
||||
void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame,
|
||||
IncrementalStringBuilder* builder) {
|
||||
Handle<Object> module_name = StackTraceFrame::GetWasmModuleName(frame);
|
||||
@ -386,8 +396,15 @@ void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame,
|
||||
builder->AppendCString(" (");
|
||||
}
|
||||
|
||||
const int wasm_func_index = StackTraceFrame::GetWasmFunctionIndex(frame);
|
||||
Handle<Object> url = StackTraceFrame::GetScriptNameOrSourceUrl(frame);
|
||||
if (IsNonEmptyString(url) && !IsAnonymousWasmScript(isolate, frame, url)) {
|
||||
builder->AppendString(Handle<String>::cast(url));
|
||||
} else {
|
||||
builder->AppendCString("<anonymous>");
|
||||
}
|
||||
builder->AppendCString(":");
|
||||
|
||||
const int wasm_func_index = StackTraceFrame::GetWasmFunctionIndex(frame);
|
||||
builder->AppendCString("wasm-function[");
|
||||
builder->AppendInt(wasm_func_index);
|
||||
builder->AppendCString("]:");
|
||||
|
@ -12,8 +12,8 @@ Script wasm://wasm/8c388106 byte offset 33: Wasm opcode 0x1
|
||||
Getting current stack trace via "new Error().stack".
|
||||
Error
|
||||
at v8://test/getStack:1:1
|
||||
at func (wasm-function[0]:0x21)
|
||||
at main (wasm-function[1]:0x2f)
|
||||
at func (<anonymous>:wasm-function[0]:0x21)
|
||||
at main (<anonymous>:wasm-function[1]:0x2f)
|
||||
at v8://test/runWasm:1:22
|
||||
exports.main returned.
|
||||
Finished.
|
||||
|
@ -12,8 +12,8 @@ Result of evaluate (string):
|
||||
Error: this is your stack trace:
|
||||
-- skipped --
|
||||
at call_debugger (<anonymous>:3:5)
|
||||
at call_func (wasm-function[1]:0x37)
|
||||
at main (wasm-function[2]:0x3e)
|
||||
at call_func (<anonymous>:wasm-function[1]:0x37)
|
||||
at main (<anonymous>:wasm-function[2]:0x3e)
|
||||
at testFunction (<anonymous>:15:20)
|
||||
at <anonymous>:1:1
|
||||
Finished!
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x32: RuntimeError: wasm exception
|
||||
RuntimeError: wasm exception
|
||||
at rethrow0 (wasm-function[0]:0x32)
|
||||
at rethrow0 (<anonymous>:wasm-function[0]:0x32)
|
||||
at *%(basename)s:21:18
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x2e: RuntimeError: wasm exception
|
||||
RuntimeError: wasm exception
|
||||
at throw0 (wasm-function[0]:0x2e)
|
||||
at throw0 (<anonymous>:wasm-function[0]:0x2e)
|
||||
at *%(basename)s:17:18
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x22: RuntimeError: unreachable
|
||||
RuntimeError: unreachable
|
||||
at main (wasm-function[0]:0x22)
|
||||
at main (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:31
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x22: RuntimeError: unreachable
|
||||
RuntimeError: unreachable
|
||||
at test-module.main (wasm-function[0]:0x22)
|
||||
at test-module.main (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:31
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x22: RuntimeError: unreachable
|
||||
RuntimeError: unreachable
|
||||
at test-module (wasm-function[0]:0x22)
|
||||
at test-module (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:31
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[0]:0x22: RuntimeError: unreachable
|
||||
RuntimeError: unreachable
|
||||
at wasm-function[0]:0x22
|
||||
at <anonymous>:wasm-function[0]:0x22
|
||||
at *%(basename)s:{NUMBER}:31
|
||||
|
@ -1,4 +1,4 @@
|
||||
wasm-function[1]:0x30: RuntimeError: divide by zero
|
||||
RuntimeError: divide by zero
|
||||
at main (wasm-function[1]:0x30)
|
||||
at main (<anonymous>:wasm-function[1]:0x30)
|
||||
at *%(basename)s:{NUMBER}:16
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at main (wasm-function[0]:0x22)
|
||||
at main (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at main (wasm-function[0]:0x22)
|
||||
at main (<anonymous>:wasm-function[0]:0x22)
|
||||
at test/message/wasm-function-name-async.js:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at test-module.main (wasm-function[0]:0x22)
|
||||
at test-module.main (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at test-module.main (wasm-function[0]:0x22)
|
||||
at test-module.main (<anonymous>:wasm-function[0]:0x22)
|
||||
at test/message/wasm-module-and-function-name-async.js:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at test-module (wasm-function[0]:0x22)
|
||||
at test-module (<anonymous>:wasm-function[0]:0x22)
|
||||
at *%(basename)s:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at test-module (wasm-function[0]:0x22)
|
||||
at test-module (<anonymous>:wasm-function[0]:0x22)
|
||||
at test/message/wasm-module-name-async.js:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at wasm-function[0]:0x22
|
||||
at <anonymous>:wasm-function[0]:0x22
|
||||
at *%(basename)s:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -1,4 +1,4 @@
|
||||
RuntimeError: unreachable
|
||||
at wasm-function[0]:0x22
|
||||
at <anonymous>:wasm-function[0]:0x22
|
||||
at test/message/wasm-no-name-async.js:{NUMBER}:27
|
||||
at test/mjsunit/mjsunit.js:*
|
||||
|
@ -186,11 +186,11 @@ function redirectToInterpreter(
|
||||
assertUnreachable('should trap because of unreachable instruction');
|
||||
} catch (e) {
|
||||
checkStack(stripPath(e.stack), [
|
||||
'Error: i=8', // -
|
||||
/^ at imp \(file:\d+:29\)$/, // -
|
||||
' at plus_one (wasm-function[1]:0x3b)', // -
|
||||
' at plus_two (wasm-function[1]:0x3e)', // -
|
||||
/^ at testStackTraceThroughCWasmEntry \(file:\d+:25\)$/, // -
|
||||
'Error: i=8', // -
|
||||
/^ at imp \(file:\d+:29\)$/, // -
|
||||
' at plus_one (<anonymous>:wasm-function[1]:0x3b)', // -
|
||||
' at plus_two (<anonymous>:wasm-function[1]:0x3e)', // -
|
||||
/^ at testStackTraceThroughCWasmEntry \(file:\d+:25\)$/, // -
|
||||
/^ at file:\d+:3$/
|
||||
]);
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ function checkStack(stack, expected_lines) {
|
||||
instance.exports.main();
|
||||
assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance));
|
||||
checkStack(stripPath(stack), [
|
||||
'Error: test imported stack', // -
|
||||
/^ at func \(interpreter.js:\d+:28\)$/, // -
|
||||
' at main (wasm-function[1]:0x32)', // -
|
||||
/^ at testCallImported \(interpreter.js:\d+:22\)$/, // -
|
||||
'Error: test imported stack', // -
|
||||
/^ at func \(interpreter.js:\d+:28\)$/, // -
|
||||
' at main (<anonymous>:wasm-function[1]:0x32)', // -
|
||||
/^ at testCallImported \(interpreter.js:\d+:22\)$/, // -
|
||||
/^ at interpreter.js:\d+:3$/
|
||||
]);
|
||||
}
|
||||
@ -102,10 +102,10 @@ function checkStack(stack, expected_lines) {
|
||||
}
|
||||
assertEquals(interpreted_before + 2, %WasmNumInterpretedCalls(instance));
|
||||
checkStack(stripPath(stack), [
|
||||
'RuntimeError: unreachable', // -
|
||||
' at foo (wasm-function[0]:0x27)', // -
|
||||
' at main (wasm-function[1]:0x2c)', // -
|
||||
/^ at testTrap \(interpreter.js:\d+:24\)$/, // -
|
||||
'RuntimeError: unreachable', // -
|
||||
' at foo (<anonymous>:wasm-function[0]:0x27)', // -
|
||||
' at main (<anonymous>:wasm-function[1]:0x2c)', // -
|
||||
/^ at testTrap \(interpreter.js:\d+:24\)$/, // -
|
||||
/^ at interpreter.js:\d+:3$/
|
||||
]);
|
||||
}
|
||||
@ -134,10 +134,10 @@ function checkStack(stack, expected_lines) {
|
||||
}
|
||||
assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance));
|
||||
checkStack(stripPath(stack), [
|
||||
'Error: thrown from imported function', // -
|
||||
/^ at func \(interpreter.js:\d+:11\)$/, // -
|
||||
' at main (wasm-function[1]:0x32)', // -
|
||||
/^ at testThrowFromImport \(interpreter.js:\d+:24\)$/, // -
|
||||
'Error: thrown from imported function', // -
|
||||
/^ at func \(interpreter.js:\d+:11\)$/, // -
|
||||
' at main (<anonymous>:wasm-function[1]:0x32)', // -
|
||||
/^ at testThrowFromImport \(interpreter.js:\d+:24\)$/, // -
|
||||
/^ at interpreter.js:\d+:3$/
|
||||
]);
|
||||
}
|
||||
@ -218,10 +218,10 @@ function checkStack(stack, expected_lines) {
|
||||
for (var e = 0; e < stacks.length; ++e) {
|
||||
expected = ['Error: reentrant interpreter test #' + e];
|
||||
expected.push(/^ at func \(interpreter.js:\d+:17\)$/);
|
||||
expected.push(' at main (wasm-function[1]:0x36)');
|
||||
expected.push(' at main (<anonymous>:wasm-function[1]:0x36)');
|
||||
for (var k = e; k > 0; --k) {
|
||||
expected.push(/^ at func \(interpreter.js:\d+:33\)$/);
|
||||
expected.push(' at main (wasm-function[1]:0x36)');
|
||||
expected.push(' at main (<anonymous>:wasm-function[1]:0x36)');
|
||||
}
|
||||
expected.push(
|
||||
/^ at testReentrantInterpreter \(interpreter.js:\d+:22\)$/);
|
||||
@ -295,10 +295,10 @@ function checkStack(stack, expected_lines) {
|
||||
} catch (e) {
|
||||
if (!(e instanceof TypeError)) throw e;
|
||||
checkStack(stripPath(e.stack), [
|
||||
'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
|
||||
' at direct (wasm-function[1]:0x55)', // -
|
||||
' at main (wasm-function[3]:0x64)', // -
|
||||
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
|
||||
'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
|
||||
' at direct (<anonymous>:wasm-function[1]:0x55)', // -
|
||||
' at main (<anonymous>:wasm-function[3]:0x64)', // -
|
||||
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
|
||||
/^ at interpreter.js:\d+:3$/
|
||||
]);
|
||||
}
|
||||
@ -308,10 +308,10 @@ function checkStack(stack, expected_lines) {
|
||||
} catch (e) {
|
||||
if (!(e instanceof TypeError)) throw e;
|
||||
checkStack(stripPath(e.stack), [
|
||||
'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
|
||||
' at indirect (wasm-function[2]:0x5c)', // -
|
||||
' at main (wasm-function[3]:0x64)', // -
|
||||
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
|
||||
'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
|
||||
' at indirect (<anonymous>:wasm-function[2]:0x5c)', // -
|
||||
' at main (<anonymous>:wasm-function[3]:0x64)', // -
|
||||
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
|
||||
/^ at interpreter.js:\d+:3$/
|
||||
]);
|
||||
}
|
||||
@ -358,8 +358,8 @@ function checkStack(stack, expected_lines) {
|
||||
if (!(e instanceof RangeError)) throw e;
|
||||
checkStack(stripPath(e.stack), [
|
||||
'RangeError: Maximum call stack size exceeded',
|
||||
' at main (wasm-function[0]:0x20)'
|
||||
].concat(Array(9).fill(' at main (wasm-function[0]:0x22)')));
|
||||
' at main (<anonymous>:wasm-function[0]:0x20)'
|
||||
].concat(Array(9).fill(' at main (<anonymous>:wasm-function[0]:0x22)')));
|
||||
}
|
||||
})();
|
||||
|
||||
|
@ -23,7 +23,7 @@ function verifyStack(frames, expected) {
|
||||
assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
|
||||
var toString;
|
||||
if (exp[0]) {
|
||||
toString = "wasm-function[" + exp[6] + "]:" + exp[5];
|
||||
toString = "<anonymous>:wasm-function[" + exp[6] + "]:" + exp[5];
|
||||
if (exp[1] !== null) toString = exp[1] + " (" + toString + ")";
|
||||
} else {
|
||||
toString = exp[4] + ":" + exp[2] + ":";
|
||||
@ -69,10 +69,10 @@ var module = builder.instantiate({mod: {func: STACK}});
|
||||
(function testSimpleStack() {
|
||||
var expected_string = 'Error\n' +
|
||||
// The line numbers below will change as this test gains / loses lines..
|
||||
' at STACK (stack.js:38:11)\n' + // --
|
||||
' at main (wasm-function[1]:0x86)\n' + // --
|
||||
' at testSimpleStack (stack.js:77:18)\n' + // --
|
||||
' at stack.js:79:3'; // --
|
||||
' at STACK (stack.js:38:11)\n' + // --
|
||||
' at main (<anonymous>:wasm-function[1]:0x86)\n' + // --
|
||||
' at testSimpleStack (stack.js:77:18)\n' + // --
|
||||
' at stack.js:79:3'; // --
|
||||
|
||||
module.exports.main();
|
||||
assertEquals(expected_string, stripPath(stack));
|
||||
|
Loading…
Reference in New Issue
Block a user