diff --git a/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar b/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar new file mode 100644 index 00000000000..ea8905ad296 --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar @@ -0,0 +1,40 @@ +# test for a bug involving printing stacktraces with missing statements; +# when dumping out information for a test. +# more info: https://github.com/gnolang/gno/pull/2813 + +loadpkg gno.land/p/demo/avl +gnoland start + +! gnokey maketx addpkg -pkgdir $WORK -pkgpath gno.land/r/pkg1 -gas-fee 1000000ugnot -gas-wanted 10000000 -broadcast -chainid=tendermint_test test1 + +stderr 'out of gas' + + +-- pkg1.gno -- +package hello + +import ( + "strconv" + + "gno.land/p/demo/avl" +) + +var hello avl.Tree + +var helloMap = make(map[string]string) + +func init() { + for i := 0; i < 1000; i++ { + s := strconv.Itoa(i) + hello.Set(s, "123") + helloMap[s] = "123" + } +} + +func Render(s string) string { + if s == "map" { + return helloMap["100"] + } + res, _ := hello.Get("100") + return res.(string) +} diff --git a/gnovm/pkg/gnolang/frame.go b/gnovm/pkg/gnolang/frame.go index 2ac1027eb32..d79093be76f 100644 --- a/gnovm/pkg/gnolang/frame.go +++ b/gnovm/pkg/gnolang/frame.go @@ -125,7 +125,11 @@ func (s Stacktrace) String() string { fmt.Fprintf(&builder, " gonative:%s.%s\n", call.Frame.Func.NativePkg, call.Frame.Func.NativeName) case call.Frame.Func != nil: fmt.Fprintf(&builder, "%s\n", toExprTrace(cx)) - fmt.Fprintf(&builder, " %s/%s:%d\n", call.Frame.Func.PkgPath, call.Frame.Func.FileName, call.Stmt.GetLine()) + line := 0 + if call.Stmt != nil { + line = call.Stmt.GetLine() + } + fmt.Fprintf(&builder, " %s/%s:%d\n", call.Frame.Func.PkgPath, call.Frame.Func.FileName, line) case call.Frame.GoFunc != nil: fmt.Fprintf(&builder, "%s\n", toExprTrace(cx)) fmt.Fprintf(&builder, " gofunction:%s\n", call.Frame.GoFunc.Value.Type()) diff --git a/gnovm/pkg/gnolang/machine.go b/gnovm/pkg/gnolang/machine.go index a0542bf9713..60b104d17bf 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -480,9 +480,12 @@ func (m *Machine) Stacktrace() (stacktrace Stacktrace) { nextStmtIndex := len(m.Stmts) - 1 for i := len(m.Frames) - 1; i >= 0; i-- { if m.Frames[i].IsCall() { - stm := m.Stmts[nextStmtIndex] - bs := stm.(*bodyStmt) - stm = bs.Body[bs.NextBodyIndex-1] + var stm Stmt + if nextStmtIndex >= 0 { + stm = m.Stmts[nextStmtIndex] + bs := stm.(*bodyStmt) + stm = bs.Body[bs.NextBodyIndex-1] + } calls = append(calls, StacktraceCall{ Stmt: stm, Frame: m.Frames[i],