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() {
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!
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
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
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
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
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
wasm-function[0]:0x22: RuntimeError: unreachable
RuntimeError: unreachable
at wasm-function[0]:0x22
at <anonymous>:wasm-function[0]:0x22
at *%(basename)s:{NUMBER}:31
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
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:*
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:*
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:*
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:*
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:*
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:*
RuntimeError: unreachable
at wasm-function[0]:0x22
at <anonymous>:wasm-function[0]:0x22
at *%(basename)s:{NUMBER}:27
at test/mjsunit/mjsunit.js:*
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));
......
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