Skip to content
Open
35 changes: 12 additions & 23 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ type Machine struct {
GCCycle int64 // number of "gc" cycles
Stage Stage // pre for static eval, add for package init, run otherwise
ReviveEnabled bool // true if revive() enabled (only in testing mode for now)
Lastline int // the line the VM is currently executing

Debugger Debugger

Expand Down Expand Up @@ -426,32 +427,17 @@ func (m *Machine) Stacktrace() (stacktrace Stacktrace) {
if m.LastFrame().Func != nil && m.LastFrame().Func.IsNative() {
stacktrace.LastLine = -1 // special line for native.
} else {
if len(m.Stmts) > 0 {
ls := m.PeekStmt(1)
if bs, ok := ls.(*bodyStmt); ok {
stacktrace.LastLine = bs.LastStmt().GetLine()
} else {
goto NOTPANIC // not a panic call
}
} else {
goto NOTPANIC // not a panic call
if m.Lastline != 0 {
stacktrace.LastLine = m.Lastline
return
}
NOTPANIC:
if len(m.Exprs) > 0 {
stacktrace.LastLine = m.PeekExpr(1).GetLine()
} else if len(m.Stmts) > 0 {
stmt := m.PeekStmt(1)
if bs, ok := stmt.(*bodyStmt); ok {
if 0 <= bs.NextBodyIndex-1 {
stmt = bs.Body[bs.NextBodyIndex-1]
}
}
stacktrace.LastLine = stmt.GetLine()
} else {
stacktrace.LastLine = 0 // dunno

ls := m.PeekStmt(1)
if bs, ok := ls.(*bodyStmt); ok {
stacktrace.LastLine = bs.LastStmt().GetLine()
return
}
}

return
}

Expand Down Expand Up @@ -1670,6 +1656,7 @@ func (m *Machine) PushStmt(s Stmt) {
if debug {
m.Printf("+s %v\n", s)
}
m.Lastline = s.GetLine()
m.Stmts = append(m.Stmts, s)
}

Expand All @@ -1679,6 +1666,7 @@ func (m *Machine) PushStmts(ss ...Stmt) {
m.Printf("+s %v\n", s)
}
}
// XXX, also set lastLine here?
m.Stmts = append(m.Stmts, ss...)
}

Expand Down Expand Up @@ -1726,6 +1714,7 @@ func (m *Machine) PopExpr() Expr {
if debug {
m.Printf("-x %v\n", x)
}
m.Lastline = x.GetLine()
m.Exprs = m.Exprs[:numExprs-1]
return x
}
Expand Down
5 changes: 5 additions & 0 deletions gnovm/tests/files/access2.gno
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ func main(cur realm) {

// Error:
// cannot directly modify readonly tainted object (w/o method): (const (ref(gno.land/p/nt/testutils) package{})).TestVar1

// Stacktrace:
// panic: cannot directly modify readonly tainted object (w/o method): (const (ref(gno.land/p/nt/testutils) package{})).TestVar1
// main<VPBlock(1,0)>(struct{( .uverse.address),("gno.land/r/access" string),(nil .uverse..grealm)})
// gno.land/r/access/access2.gno:9
19 changes: 19 additions & 0 deletions gnovm/tests/files/panic3.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

var a = 0
func foo()int{
return 1/a
}
func main() {
foo()
}

// Error:
// division by zero

// Stacktrace:
// panic: division by zero
// foo<VPBlock(3,1)>()
// main/panic3.gno:5
// main<VPBlock(1,2)>()
// main/panic3.gno:8
13 changes: 13 additions & 0 deletions gnovm/tests/files/panic4.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main

func main() {
panic("===")
}

// Stacktrace:
// panic: ===
// main<VPBlock(1,0)>()
// main/panic4.gno:4

// Error:
// ===
17 changes: 17 additions & 0 deletions gnovm/tests/files/panic5.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

func main() {
a := 0
if i := 1; true &&
i/a == 2 {
println("ok")
}
}

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/panic5.gno:6

// Error:
// division by zero
16 changes: 16 additions & 0 deletions gnovm/tests/files/panic5a.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

func main() {
a := 0
if i := 0; true && i/a == 1 {
println("ok")
}
}

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/panic5a.gno:5

// Error:
// division by zero
17 changes: 17 additions & 0 deletions gnovm/tests/files/panic5b.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

func main() {
a := 0
if i := 1; i ==
2/a {
println("ok")
}
}

// Error:
// division by zero

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/panic5b.gno:6
17 changes: 17 additions & 0 deletions gnovm/tests/files/panic5c.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package main

func main() {
a := 0
b := 1/a
}

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/panic5c.gno:5

// Error:
// division by zero

// TypeCheckError:
// main/panic5c.gno:5:2: declared and not used: b
16 changes: 16 additions & 0 deletions gnovm/tests/files/panic5d.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

func main() {
a := 0
if i := 1/a; true {
println(i)
}
}

// Error:
// division by zero

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/panic5d.gno:5
28 changes: 28 additions & 0 deletions gnovm/tests/files/panic6.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import "fmt"

func main() {
// A pointer to a pointer, initialized to nil
var doublePtr **int = nil

fmt.Println("1. Attempting to evaluate **doublePtr")

// The expression is: *(*doublePtr)
// The VM/Runtime must evaluate the INNER (*doublePtr) first
// to get the address for the OUTER (*).

// CRASH OCCURS HERE inside the first dereference.
val := **doublePtr

// This line is never reached
fmt.Println("2. Success:", val)
}

// Stacktrace:
// panic: nil pointer dereference
// main<VPBlock(1,0)>()
// main/panic6.gno:16

// Error:
// nil pointer dereference
14 changes: 14 additions & 0 deletions gnovm/tests/files/panic7.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

func main() {
var p *int
println(*p)
}

// Stacktrace:
// panic: nil pointer dereference
// main<VPBlock(1,0)>()
// main/panic7.gno:5

// Error:
// nil pointer dereference
15 changes: 15 additions & 0 deletions gnovm/tests/files/recover/recover3.gno
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package main

func main() {
for i := 0; 1/i >= 0; i++ {
break
}
}

// Error:
// division by zero

// Stacktrace:
// panic: division by zero
// main<VPBlock(1,0)>()
// main/recover3.gno:4
Loading