Repository: tetratelabs/wazero
Pull request #2199 (2024-04-30 08:07:22)

debug: do not include inlined sources in frame counts
I noticed this while debugging https://github.com/tetratelabs/wazero/issues/2198

## After

```
wasm stack trace:
	.__rust_start_panic(i32,i32) i32
		0xa5a99: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/panic_abort/src/lib.rs:96:17 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/panic_abort/src/lib.rs:38:5
	.rust_panic(i32,i32)
		0xa5682: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:833:25
	._ZN3std9panicking20rust_panic_with_hook17h173ea7d6a1f035f0E(i32,i32,i32,i32,i32,i32)
		0xa55b5: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:803:5
	._ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17h62f35ba2527ec452E(i32)
		0xa44cf: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:659:13
	._ZN3std10sys_common9backtrace26__rust_end_short_backtrace17hdd245b5cf43b7e94E(i32)
		0xa43fa: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/sys_common/backtrace.rs:171:18
	.rust_begin_unwind(i32)
		0xa4f8c: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:647:5
	._ZN4core9panicking9panic_fmt17hb516fa06bb502322E(i32,i32)
		0xa7a94: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:72:14
	._ZN4core9panicking19assert_failed_inner17h7e440e1e2afa7d60E(i32,i32,i32,i32,i32,i32,i32)
		0xae785: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:337:23
	._ZN4core9panicking13assert_failed17h13c7c442512e8f39E(i32,i32,i32,i32,i32)
		0x5a707: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:297:5
	._ZN12aho_corasick5tests16run_search_tests17hf1210027171a9317E(i32,i32)
		0xf5df: /Users/mathetake/aho-corasick/src/tests.rs:1338:13
	._ZN4core3ops8function6FnOnce9call_once17hc2522d0bf33404b3E(i32)
		0x53367: /Users/mathetake/aho-corasick/src/tests.rs:709:13 (inlined)
		         /Users/mathetake/aho-corasick/src/tests.rs:708:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5
	._ZN4test28__rust_begin_short_backtrace17h59a53de8fec48743E(i32,i32)
		0x96379: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:621:18
	._ZN4test5types12RunnableTest3run17h75e43b06fc9be44fE(i32,i32)
		0x96196: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/types.rs:146:40
	._ZN4test8run_test17h2117ed746d4fbceeE(i32,i32,i32,i32,i32,i32,i32,i32)
		0x7ac32: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:644:60 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panic/unwind_safe.rs:272:9 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:644:27 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:567:43 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:606:17
	._ZN4test7console17run_tests_console17hda31b7a2d1edfabfE(i32,i32,i32)
		0x75d51: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:380:31 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/console.rs:329:5
	._ZN4test9test_main17h38f333ea3a200455E(i32,i32,i32,i32,i32)
		0x965a9: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:143:15
	._ZN4test16test_main_static17h574ee807b9b4a692E(i32,i32)
		0x971c3: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:162:5
	._ZN12aho_corasick4main17h4f307d5683b5a88bE()
		0x56134: /Users/mathetake/aho-corasick/src/lib.rs:1:1
	._ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hf6cc62b06f47227eE(i32)
		0x5cf86: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/sys_common/backtrace.rs:155:18
	._ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h98dc82c73e380a56E.llvm.17769364131994765198(i32) i32
		0x5a30e: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:166:18
	._ZN3std2rt19lang_start_internal17h9dd0d30024c12b69E(i32,i32,i32,i32,i32) i32
		0x9e4e9: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:284:13 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:148:48 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:148:20
	.__main_void() i32
	._start()
```

## Before

```
wasm stack trace:
	.__rust_start_panic(i32,i32) i32
		0xa5a99: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/panic_abort/src/lib.rs:96:17 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/panic_abort/src/lib.rs:38:5
	.rust_panic(i32,i32)
		0xa5682: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:833:25
	._ZN3std9panicking20rust_panic_with_hook17h173ea7d6a1f035f0E(i32,i32,i32,i32,i32,i32)
		0xa55b5: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:803:5
	._ZN3std9panicking19begin_panic_handler28_$u7b$$u7b$closure$u7d$$u7d$17h62f35ba2527ec452E(i32)
		0xa44cf: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:659:13
	._ZN3std10sys_common9backtrace26__rust_end_short_backtrace17hdd245b5cf43b7e94E(i32)
		0xa43fa: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/sys_common/backtrace.rs:171:18
	.rust_begin_unwind(i32)
		0xa4f8c: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:647:5
	._ZN4core9panicking9panic_fmt17hb516fa06bb502322E(i32,i32)
		0xa7a94: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:72:14
	._ZN4core9panicking19assert_failed_inner17h7e440e1e2afa7d60E(i32,i32,i32,i32,i32,i32,i32)
		0xae785: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:337:23
	._ZN4core9panicking13assert_failed17h13c7c442512e8f39E(i32,i32,i32,i32,i32)
		0x5a707: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panicking.rs:297:5
	._ZN12aho_corasick5tests16run_search_tests17hf1210027171a9317E(i32,i32)
		0xf5df: /Users/mathetake/aho-corasick/src/tests.rs:1338:13
	._ZN4core3ops8function6FnOnce9call_once17hc2522d0bf33404b3E(i32)
		0x53367: /Users/mathetake/aho-corasick/src/tests.rs:709:13 (inlined)
		         /Users/mathetake/aho-corasick/src/tests.rs:708:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5
	._ZN4test28__rust_begin_short_backtrace17h59a53de8fec48743E(i32,i32)
		0x96379: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:621:18
	._ZN4test5types12RunnableTest3run17h75e43b06fc9be44fE(i32,i32)
		0x96196: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/types.rs:146:40
	... maybe followed by omitted frames
	._ZN4test8run_test17h2117ed746d4fbceeE(i32,i32,i32,i32,i32,i32,i32,i32)
		0x7ac32: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:644:60 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/panic/unwind_safe.rs:272:9 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:644:27 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:567:43 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:606:17
	._ZN4test7console17run_tests_console17hda31b7a2d1edfabfE(i32,i32,i32)
		0x75d51: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:380:31 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/console.rs:329:5
	._ZN4test9test_main17h38f333ea3a200455E(i32,i32,i32,i32,i32)
		0x965a9: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:143:15
	._ZN4test16test_main_static17h574ee807b9b4a692E(i32,i32)
		0x971c3: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/test/src/lib.rs:162:5
	._ZN12aho_corasick4main17h4f307d5683b5a88bE()
		0x56134: /Users/mathetake/aho-corasick/src/lib.rs:1:1
	._ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hf6cc62b06f47227eE(i32)
		0x5cf86: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:250:5 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/sys_common/backtrace.rs:155:18
	._ZN3std2rt10lang_start28_$u7b$$u7b$closure$u7d$$u7d$17h98dc82c73e380a56E.llvm.17769364131994765198(i32) i32
		0x5a30e: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:166:18
	._ZN3std2rt19lang_start_internal17h9dd0d30024c12b69E(i32,i32,i32,i32,i32) i32
		0x9e4e9: /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/core/src/ops/function.rs:284:13 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:148:48 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:554:40 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panicking.rs:518:19 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/panic.rs:142:14 (inlined)
		         /rustc/ef71f1047e04438181d7cb925a833e2ada6ab390/library/std/src/rt.rs:148:20
	.__main_void() i32
	._start()
```

where `... maybe followed by omitted frames` was placed in the middle of traces, which was due to inclusion of inlined sources in counts.


Patch:
diff --git a/internal/wasmdebug/debug.go b/internal/wasmdebug/debug.go
index deb67493..ff0e0ccc 100644
--- a/internal/wasmdebug/debug.go
+++ b/internal/wasmdebug/debug.go
@@ -109,7 +109,10 @@ func NewErrorBuilder() ErrorBuilder {
 }
 
 type stackTrace struct {
-	frames []string
+	// frameCount is the number of stack frame currently pushed into lines.
+	frameCount int
+	// lines contains the stack trace and possibly the inlined source code information.
+	lines []string
 }
 
 // GoRuntimeErrorTracePrefix is the prefix coming before the Go runtime stack trace included in the face of runtime.Error.
@@ -125,7 +128,7 @@ func (s *stackTrace) FromRecovered(recovered interface{}) error {
 		return exitErr
 	}
 
-	stack := strings.Join(s.frames, "\n\t")
+	stack := strings.Join(s.lines, "\n\t")
 
 	// If the error was internal, don't mention it was recovered.
 	if wasmErr, ok := recovered.(*wasmruntime.Error); ok {
@@ -152,12 +155,16 @@ const MaxFrames = 30
 
 // AddFrame implements ErrorBuilder.AddFrame
 func (s *stackTrace) AddFrame(funcName string, paramTypes, resultTypes []api.ValueType, sources []string) {
+	if s.frameCount == MaxFrames {
+		return
+	}
+	s.frameCount++
 	sig := signature(funcName, paramTypes, resultTypes)
-	s.frames = append(s.frames, sig)
+	s.lines = append(s.lines, sig)
 	for _, source := range sources {
-		s.frames = append(s.frames, "\t"+source)
+		s.lines = append(s.lines, "\t"+source)
 	}
-	if len(s.frames) == MaxFrames {
-		s.frames = append(s.frames, "... maybe followed by omitted frames")
+	if s.frameCount == MaxFrames {
+		s.lines = append(s.lines, "... maybe followed by omitted frames")
 	}
 }


Test patch:
diff --git a/internal/wasmdebug/debug_test.go b/internal/wasmdebug/debug_test.go
index 8094198c..0ee4ca57 100644
--- a/internal/wasmdebug/debug_test.go
+++ b/internal/wasmdebug/debug_test.go
@@ -157,3 +157,13 @@ func (e testRuntimeErr) RuntimeError() {}
 func (e testRuntimeErr) Error() string {
 	return string(e)
 }
+
+func Test_AddFrame_MaxFrame(t *testing.T) {
+	builder := NewErrorBuilder().(*stackTrace)
+	for i := 0; i < MaxFrames+10; i++ {
+		builder.AddFrame("x.y", nil, nil, []string{"a.go:1:2", "b.go:3:4"})
+	}
+	require.Equal(t, MaxFrames, builder.frameCount)
+	require.Equal(t, MaxFrames*3 /* frame + two inlined sources */ +1, len(builder.lines))
+	require.Equal(t, "... maybe followed by omitted frames", builder.lines[len(builder.lines)-1])
+}