Commit b0c4f2b0 authored by Kim-Anh Tran's avatar Kim-Anh Tran Committed by Commit Bot

[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: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66302}
parent 5ca49a22
...@@ -581,6 +581,12 @@ Handle<Object> WasmStackFrame::GetFunctionName() { ...@@ -581,6 +581,12 @@ Handle<Object> WasmStackFrame::GetFunctionName() {
return name; 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> WasmStackFrame::GetWasmModuleName() {
Handle<Object> module_name; Handle<Object> module_name;
Handle<WasmModuleObject> module_object(wasm_instance_->module_object(), Handle<WasmModuleObject> module_object(wasm_instance_->module_object(),
......
...@@ -169,7 +169,7 @@ class WasmStackFrame : public StackFrameBase { ...@@ -169,7 +169,7 @@ class WasmStackFrame : public StackFrameBase {
Handle<Object> GetFileName() override { return Null(); } Handle<Object> GetFileName() override { return Null(); }
Handle<Object> GetFunctionName() override; Handle<Object> GetFunctionName() override;
Handle<Object> GetScriptNameOrSourceUrl() override { return Null(); } Handle<Object> GetScriptNameOrSourceUrl() override;
Handle<Object> GetMethodName() override { return Null(); } Handle<Object> GetMethodName() override { return Null(); }
Handle<Object> GetTypeName() override { return Null(); } Handle<Object> GetTypeName() override { return Null(); }
Handle<Object> GetWasmModuleName() override; Handle<Object> GetWasmModuleName() override;
......
...@@ -368,6 +368,16 @@ void SerializeAsmJsWasmStackFrame(Isolate* isolate, ...@@ -368,6 +368,16 @@ void SerializeAsmJsWasmStackFrame(Isolate* isolate,
return; 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, void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame,
IncrementalStringBuilder* builder) { IncrementalStringBuilder* builder) {
Handle<Object> module_name = StackTraceFrame::GetWasmModuleName(frame); Handle<Object> module_name = StackTraceFrame::GetWasmModuleName(frame);
...@@ -386,8 +396,15 @@ void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame, ...@@ -386,8 +396,15 @@ void SerializeWasmStackFrame(Isolate* isolate, Handle<StackTraceFrame> frame,
builder->AppendCString(" ("); 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->AppendCString("wasm-function[");
builder->AppendInt(wasm_func_index); builder->AppendInt(wasm_func_index);
builder->AppendCString("]:"); builder->AppendCString("]:");
......
...@@ -12,8 +12,8 @@ Script wasm://wasm/8c388106 byte offset 33: Wasm opcode 0x1 ...@@ -12,8 +12,8 @@ Script wasm://wasm/8c388106 byte offset 33: Wasm opcode 0x1
Getting current stack trace via "new Error().stack". Getting current stack trace via "new Error().stack".
Error Error
at v8://test/getStack:1:1 at v8://test/getStack:1:1
at func (wasm-function[0]:0x21) at func (<anonymous>:wasm-function[0]:0x21)
at main (wasm-function[1]:0x2f) at main (<anonymous>:wasm-function[1]:0x2f)
at v8://test/runWasm:1:22 at v8://test/runWasm:1:22
exports.main returned. exports.main returned.
Finished. Finished.
...@@ -12,8 +12,8 @@ Result of evaluate (string): ...@@ -12,8 +12,8 @@ Result of evaluate (string):
Error: this is your stack trace: Error: this is your stack trace:
-- skipped -- -- skipped --
at call_debugger (<anonymous>:3:5) at call_debugger (<anonymous>:3:5)
at call_func (wasm-function[1]:0x37) at call_func (<anonymous>:wasm-function[1]:0x37)
at main (wasm-function[2]:0x3e) at main (<anonymous>:wasm-function[2]:0x3e)
at testFunction (<anonymous>:15:20) at testFunction (<anonymous>:15:20)
at <anonymous>:1:1 at <anonymous>:1:1
Finished! Finished!
wasm-function[0]:0x32: RuntimeError: wasm exception wasm-function[0]:0x32: RuntimeError: wasm exception
RuntimeError: wasm exception RuntimeError: wasm exception
at rethrow0 (wasm-function[0]:0x32) at rethrow0 (<anonymous>:wasm-function[0]:0x32)
at *%(basename)s:21:18 at *%(basename)s:21:18
wasm-function[0]:0x2e: RuntimeError: wasm exception wasm-function[0]:0x2e: RuntimeError: wasm exception
RuntimeError: wasm exception RuntimeError: wasm exception
at throw0 (wasm-function[0]:0x2e) at throw0 (<anonymous>:wasm-function[0]:0x2e)
at *%(basename)s:17:18 at *%(basename)s:17:18
wasm-function[0]:0x22: RuntimeError: unreachable wasm-function[0]:0x22: RuntimeError: unreachable
RuntimeError: unreachable RuntimeError: unreachable
at main (wasm-function[0]:0x22) at main (<anonymous>:wasm-function[0]:0x22)
at *%(basename)s:{NUMBER}:31 at *%(basename)s:{NUMBER}:31
wasm-function[0]:0x22: RuntimeError: unreachable wasm-function[0]:0x22: RuntimeError: unreachable
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 at *%(basename)s:{NUMBER}:31
wasm-function[0]:0x22: RuntimeError: unreachable wasm-function[0]:0x22: RuntimeError: unreachable
RuntimeError: unreachable RuntimeError: unreachable
at test-module (wasm-function[0]:0x22) at test-module (<anonymous>:wasm-function[0]:0x22)
at *%(basename)s:{NUMBER}:31 at *%(basename)s:{NUMBER}:31
wasm-function[0]:0x22: RuntimeError: unreachable wasm-function[0]:0x22: RuntimeError: unreachable
RuntimeError: unreachable RuntimeError: unreachable
at wasm-function[0]:0x22 at <anonymous>:wasm-function[0]:0x22
at *%(basename)s:{NUMBER}:31 at *%(basename)s:{NUMBER}:31
wasm-function[1]:0x30: RuntimeError: divide by zero wasm-function[1]:0x30: RuntimeError: divide by zero
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 at *%(basename)s:{NUMBER}:16
RuntimeError: unreachable RuntimeError: unreachable
at main (wasm-function[0]:0x22) at main (<anonymous>:wasm-function[0]:0x22)
at *%(basename)s:{NUMBER}:27 at *%(basename)s:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable 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/message/wasm-function-name-async.js:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
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}:27 at *%(basename)s:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable 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/message/wasm-module-and-function-name-async.js:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable RuntimeError: unreachable
at test-module (wasm-function[0]:0x22) at test-module (<anonymous>:wasm-function[0]:0x22)
at *%(basename)s:{NUMBER}:27 at *%(basename)s:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable 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/message/wasm-module-name-async.js:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable RuntimeError: unreachable
at wasm-function[0]:0x22 at <anonymous>:wasm-function[0]:0x22
at *%(basename)s:{NUMBER}:27 at *%(basename)s:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
RuntimeError: unreachable 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/message/wasm-no-name-async.js:{NUMBER}:27
at test/mjsunit/mjsunit.js:* at test/mjsunit/mjsunit.js:*
...@@ -186,11 +186,11 @@ function redirectToInterpreter( ...@@ -186,11 +186,11 @@ function redirectToInterpreter(
assertUnreachable('should trap because of unreachable instruction'); assertUnreachable('should trap because of unreachable instruction');
} catch (e) { } catch (e) {
checkStack(stripPath(e.stack), [ checkStack(stripPath(e.stack), [
'Error: i=8', // - 'Error: i=8', // -
/^ at imp \(file:\d+:29\)$/, // - /^ at imp \(file:\d+:29\)$/, // -
' at plus_one (wasm-function[1]:0x3b)', // - ' at plus_one (<anonymous>:wasm-function[1]:0x3b)', // -
' at plus_two (wasm-function[1]:0x3e)', // - ' at plus_two (<anonymous>:wasm-function[1]:0x3e)', // -
/^ at testStackTraceThroughCWasmEntry \(file:\d+:25\)$/, // - /^ at testStackTraceThroughCWasmEntry \(file:\d+:25\)$/, // -
/^ at file:\d+:3$/ /^ at file:\d+:3$/
]); ]);
} }
......
...@@ -37,10 +37,10 @@ function checkStack(stack, expected_lines) { ...@@ -37,10 +37,10 @@ function checkStack(stack, expected_lines) {
instance.exports.main(); instance.exports.main();
assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance)); assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance));
checkStack(stripPath(stack), [ checkStack(stripPath(stack), [
'Error: test imported stack', // - 'Error: test imported stack', // -
/^ at func \(interpreter.js:\d+:28\)$/, // - /^ at func \(interpreter.js:\d+:28\)$/, // -
' at main (wasm-function[1]:0x32)', // - ' at main (<anonymous>:wasm-function[1]:0x32)', // -
/^ at testCallImported \(interpreter.js:\d+:22\)$/, // - /^ at testCallImported \(interpreter.js:\d+:22\)$/, // -
/^ at interpreter.js:\d+:3$/ /^ at interpreter.js:\d+:3$/
]); ]);
} }
...@@ -102,10 +102,10 @@ function checkStack(stack, expected_lines) { ...@@ -102,10 +102,10 @@ function checkStack(stack, expected_lines) {
} }
assertEquals(interpreted_before + 2, %WasmNumInterpretedCalls(instance)); assertEquals(interpreted_before + 2, %WasmNumInterpretedCalls(instance));
checkStack(stripPath(stack), [ checkStack(stripPath(stack), [
'RuntimeError: unreachable', // - 'RuntimeError: unreachable', // -
' at foo (wasm-function[0]:0x27)', // - ' at foo (<anonymous>:wasm-function[0]:0x27)', // -
' at main (wasm-function[1]:0x2c)', // - ' at main (<anonymous>:wasm-function[1]:0x2c)', // -
/^ at testTrap \(interpreter.js:\d+:24\)$/, // - /^ at testTrap \(interpreter.js:\d+:24\)$/, // -
/^ at interpreter.js:\d+:3$/ /^ at interpreter.js:\d+:3$/
]); ]);
} }
...@@ -134,10 +134,10 @@ function checkStack(stack, expected_lines) { ...@@ -134,10 +134,10 @@ function checkStack(stack, expected_lines) {
} }
assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance)); assertEquals(interpreted_before + 1, %WasmNumInterpretedCalls(instance));
checkStack(stripPath(stack), [ checkStack(stripPath(stack), [
'Error: thrown from imported function', // - 'Error: thrown from imported function', // -
/^ at func \(interpreter.js:\d+:11\)$/, // - /^ at func \(interpreter.js:\d+:11\)$/, // -
' at main (wasm-function[1]:0x32)', // - ' at main (<anonymous>:wasm-function[1]:0x32)', // -
/^ at testThrowFromImport \(interpreter.js:\d+:24\)$/, // - /^ at testThrowFromImport \(interpreter.js:\d+:24\)$/, // -
/^ at interpreter.js:\d+:3$/ /^ at interpreter.js:\d+:3$/
]); ]);
} }
...@@ -218,10 +218,10 @@ function checkStack(stack, expected_lines) { ...@@ -218,10 +218,10 @@ function checkStack(stack, expected_lines) {
for (var e = 0; e < stacks.length; ++e) { for (var e = 0; e < stacks.length; ++e) {
expected = ['Error: reentrant interpreter test #' + e]; expected = ['Error: reentrant interpreter test #' + e];
expected.push(/^ at func \(interpreter.js:\d+:17\)$/); 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) { for (var k = e; k > 0; --k) {
expected.push(/^ at func \(interpreter.js:\d+:33\)$/); 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( expected.push(
/^ at testReentrantInterpreter \(interpreter.js:\d+:22\)$/); /^ at testReentrantInterpreter \(interpreter.js:\d+:22\)$/);
...@@ -295,10 +295,10 @@ function checkStack(stack, expected_lines) { ...@@ -295,10 +295,10 @@ function checkStack(stack, expected_lines) {
} catch (e) { } catch (e) {
if (!(e instanceof TypeError)) throw e; if (!(e instanceof TypeError)) throw e;
checkStack(stripPath(e.stack), [ checkStack(stripPath(e.stack), [
'TypeError: ' + kTrapMsgs[kTrapTypeError], // - 'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
' at direct (wasm-function[1]:0x55)', // - ' at direct (<anonymous>:wasm-function[1]:0x55)', // -
' at main (wasm-function[3]:0x64)', // - ' at main (<anonymous>:wasm-function[3]:0x64)', // -
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // - /^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
/^ at interpreter.js:\d+:3$/ /^ at interpreter.js:\d+:3$/
]); ]);
} }
...@@ -308,10 +308,10 @@ function checkStack(stack, expected_lines) { ...@@ -308,10 +308,10 @@ function checkStack(stack, expected_lines) {
} catch (e) { } catch (e) {
if (!(e instanceof TypeError)) throw e; if (!(e instanceof TypeError)) throw e;
checkStack(stripPath(e.stack), [ checkStack(stripPath(e.stack), [
'TypeError: ' + kTrapMsgs[kTrapTypeError], // - 'TypeError: ' + kTrapMsgs[kTrapTypeError], // -
' at indirect (wasm-function[2]:0x5c)', // - ' at indirect (<anonymous>:wasm-function[2]:0x5c)', // -
' at main (wasm-function[3]:0x64)', // - ' at main (<anonymous>:wasm-function[3]:0x64)', // -
/^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // - /^ at testIllegalImports \(interpreter.js:\d+:22\)$/, // -
/^ at interpreter.js:\d+:3$/ /^ at interpreter.js:\d+:3$/
]); ]);
} }
...@@ -358,8 +358,8 @@ function checkStack(stack, expected_lines) { ...@@ -358,8 +358,8 @@ function checkStack(stack, expected_lines) {
if (!(e instanceof RangeError)) throw e; if (!(e instanceof RangeError)) throw e;
checkStack(stripPath(e.stack), [ checkStack(stripPath(e.stack), [
'RangeError: Maximum call stack size exceeded', 'RangeError: Maximum call stack size exceeded',
' at main (wasm-function[0]:0x20)' ' at main (<anonymous>:wasm-function[0]:0x20)'
].concat(Array(9).fill(' at main (wasm-function[0]:0x22)'))); ].concat(Array(9).fill(' at main (<anonymous>:wasm-function[0]:0x22)')));
} }
})(); })();
......
...@@ -23,7 +23,7 @@ function verifyStack(frames, expected) { ...@@ -23,7 +23,7 @@ function verifyStack(frames, expected) {
assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()"); assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
var toString; var toString;
if (exp[0]) { 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 + ")"; if (exp[1] !== null) toString = exp[1] + " (" + toString + ")";
} else { } else {
toString = exp[4] + ":" + exp[2] + ":"; toString = exp[4] + ":" + exp[2] + ":";
...@@ -69,10 +69,10 @@ var module = builder.instantiate({mod: {func: STACK}}); ...@@ -69,10 +69,10 @@ var module = builder.instantiate({mod: {func: STACK}});
(function testSimpleStack() { (function testSimpleStack() {
var expected_string = 'Error\n' + var expected_string = 'Error\n' +
// The line numbers below will change as this test gains / loses lines.. // The line numbers below will change as this test gains / loses lines..
' at STACK (stack.js:38:11)\n' + // -- ' at STACK (stack.js:38:11)\n' + // --
' at main (wasm-function[1]:0x86)\n' + // -- ' at main (<anonymous>:wasm-function[1]:0x86)\n' + // --
' at testSimpleStack (stack.js:77:18)\n' + // -- ' at testSimpleStack (stack.js:77:18)\n' + // --
' at stack.js:79:3'; // -- ' at stack.js:79:3'; // --
module.exports.main(); module.exports.main();
assertEquals(expected_string, stripPath(stack)); assertEquals(expected_string, stripPath(stack));
......
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