runtime: show stacktrace when panic
This commit is contained in:
42
_demo/failed/stacktrace/main.go
Normal file
42
_demo/failed/stacktrace/main.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MyStruct[T any] struct {
|
||||||
|
value T
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MyStruct[T]) Method() {
|
||||||
|
fmt.Println("In generic method")
|
||||||
|
genericFunc[T](m.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func genericFunc[T any](v T) {
|
||||||
|
fmt.Println("In generic function")
|
||||||
|
normalFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalFunc() {
|
||||||
|
fmt.Println("In normal function")
|
||||||
|
panic("panic occurs here")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
m := &MyStruct[string]{value: "hello"}
|
||||||
|
m.Method()
|
||||||
|
}
|
||||||
|
|
||||||
|
//Expected:
|
||||||
|
// In generic method
|
||||||
|
// In generic function
|
||||||
|
// In normal function
|
||||||
|
// panic: panic occurs here
|
||||||
|
|
||||||
|
// [0x00C6D310 github.com/goplus/llgo/internal/runtime.Rethrow+0x2f, SP = 0x60]
|
||||||
|
// [0x00C6CF44 github.com/goplus/llgo/internal/runtime.Panic+0x2d, SP = 0x50]
|
||||||
|
// [0x00C69420 main.normalFunc+0xf, SP = 0xa8]
|
||||||
|
// [0x00C69564 main.genericFunc[string]+0x18, SP = 0x74]
|
||||||
|
// [0x00C694A8 main.(*MyStruct[string]).Method+0x1f, SP = 0x84]
|
||||||
|
// [0x00C6936C main+0x4, SP = 0x40]
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
|
#define UNW_LOCAL_ONLY
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include <features.h>
|
#include <features.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -35,4 +36,4 @@ void llgo_stacktrace(int skip, void *ctx, int (*fn)(void *ctx, void *pc, void *o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
package debug
|
package debug
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo linux LDFLAGS: -lunwind
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
import (
|
import (
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/goplus/llgo/c"
|
"github.com/goplus/llgo/c"
|
||||||
|
"github.com/goplus/llgo/c/debug"
|
||||||
"github.com/goplus/llgo/c/pthread"
|
"github.com/goplus/llgo/c/pthread"
|
||||||
"github.com/goplus/llgo/c/signal"
|
"github.com/goplus/llgo/c/signal"
|
||||||
"github.com/goplus/llgo/c/syscall"
|
"github.com/goplus/llgo/c/syscall"
|
||||||
@@ -61,6 +62,13 @@ func Rethrow(link *Defer) {
|
|||||||
if ptr := excepKey.Get(); ptr != nil {
|
if ptr := excepKey.Get(); ptr != nil {
|
||||||
if link == nil {
|
if link == nil {
|
||||||
TracePanic(*(*any)(ptr))
|
TracePanic(*(*any)(ptr))
|
||||||
|
debug.StackTrace(0, func(fr *debug.Frame) bool {
|
||||||
|
var info debug.Info
|
||||||
|
debug.Addrinfo(unsafe.Pointer(fr.PC), &info)
|
||||||
|
c.Fprintf(c.Stderr, c.Str("[0x%08X %s+0x%x, SP = 0x%x]\n"), fr.PC, fr.Name, fr.Offset, fr.SP)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
c.Free(ptr)
|
c.Free(ptr)
|
||||||
c.Exit(2)
|
c.Exit(2)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user