From d447b49ceb5b597f57284dc15c1aa199574c40f3 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Wed, 18 Sep 2024 19:52:57 +0200 Subject: [PATCH 1/2] fix(gnovm): handle case of NumStmts = 0 when creating stacktraces --- .../testdata/issue_outofgas_stacktrace.txtar | 39 +++++++++++++++++++ gnovm/pkg/gnolang/frame.go | 6 ++- gnovm/pkg/gnolang/machine.go | 9 +++-- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar 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..5f952de31fe --- /dev/null +++ b/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar @@ -0,0 +1,39 @@ +# test for a bug involving printing stacktraces with missing statements; +# when dumping out information for a test. + +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 718ee803fe1..1aeb5ac048f 100644 --- a/gnovm/pkg/gnolang/machine.go +++ b/gnovm/pkg/gnolang/machine.go @@ -479,9 +479,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], From 563c44d8f7593fbe5dc7852301bc9931593902c2 Mon Sep 17 00:00:00 2001 From: Morgan Bazalgette Date: Wed, 18 Sep 2024 19:54:25 +0200 Subject: [PATCH 2/2] add reference to issue with stacktrace --- gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar | 1 + 1 file changed, 1 insertion(+) diff --git a/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar b/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar index 5f952de31fe..ea8905ad296 100644 --- a/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar +++ b/gno.land/cmd/gnoland/testdata/issue_outofgas_stacktrace.txtar @@ -1,5 +1,6 @@ # 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