diff --git a/internal/wasmdebug/debug.go b/internal/wasmdebug/debug.go index deb6749381..ff0e0cccc9 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") } } diff --git a/internal/wasmdebug/debug_test.go b/internal/wasmdebug/debug_test.go index 8094198cd8..0ee4ca57b5 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]) +}