runtime: show stacktrace when panic

This commit is contained in:
Li Jie
2025-01-02 21:45:11 +08:00
parent 5131881bf2
commit 65f855b251
4 changed files with 56 additions and 1 deletions

View 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]

View File

@@ -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
} }
} }
} }
} }

View File

@@ -1,5 +1,9 @@
package debug package debug
/*
#cgo linux LDFLAGS: -lunwind
*/
import "C"
import ( import (
"unsafe" "unsafe"

View File

@@ -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 {