forked from cerc-io/ipld-eth-server
68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
|
// +build go1.9
|
||
|
|
||
|
package stack_test
|
||
|
|
||
|
import (
|
||
|
"runtime"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/go-stack/stack"
|
||
|
)
|
||
|
|
||
|
func TestCallerInlinedPanic(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
|
||
|
var line int
|
||
|
|
||
|
defer func() {
|
||
|
if recover() != nil {
|
||
|
var pcs [32]uintptr
|
||
|
n := runtime.Callers(1, pcs[:])
|
||
|
frames := runtime.CallersFrames(pcs[:n])
|
||
|
// count frames to runtime.sigpanic
|
||
|
panicIdx := 0
|
||
|
for {
|
||
|
f, more := frames.Next()
|
||
|
if f.Function == "runtime.sigpanic" {
|
||
|
break
|
||
|
}
|
||
|
panicIdx++
|
||
|
if !more {
|
||
|
t.Fatal("no runtime.sigpanic entry on the stack")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
c := stack.Caller(panicIdx)
|
||
|
if got, want := c.Frame().Function, "runtime.sigpanic"; got != want {
|
||
|
t.Errorf("sigpanic frame: got name == %v, want name == %v", got, want)
|
||
|
}
|
||
|
|
||
|
c1 := stack.Caller(panicIdx + 1)
|
||
|
if got, want := c1.Frame().Function, "github.com/go-stack/stack_test.inlinablePanic"; got != want {
|
||
|
t.Errorf("TestCallerInlinedPanic frame: got name == %v, want name == %v", got, want)
|
||
|
}
|
||
|
if got, want := c1.Frame().Line, line; got != want {
|
||
|
t.Errorf("TestCallerInlinedPanic frame: got line == %v, want line == %v", got, want)
|
||
|
}
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
doPanic(t, &line)
|
||
|
t.Fatal("failed to panic")
|
||
|
}
|
||
|
|
||
|
func doPanic(t *testing.T, panicLine *int) {
|
||
|
_, _, line, ok := runtime.Caller(0)
|
||
|
*panicLine = line + 11 // adjust to match line of panic below
|
||
|
if !ok {
|
||
|
t.Fatal("runtime.Caller(0) failed")
|
||
|
}
|
||
|
inlinablePanic()
|
||
|
}
|
||
|
|
||
|
func inlinablePanic() {
|
||
|
// Initiate a sigpanic.
|
||
|
var x *uintptr
|
||
|
_ = *x
|
||
|
}
|