From 7b6b8b0eeb84fb1fc9720fbb05e1c2b13600e0c1 Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 29 Nov 2024 11:27:56 +0800 Subject: [PATCH] c/debug: StackTrace --- c/debug/_demo/stacktrace/main.go | 26 ++++++++++++++++++++++++++ c/debug/_wrap/debug.c | 24 ++++++++++++++++++++++++ c/debug/debug.go | 20 ++++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 c/debug/_demo/stacktrace/main.go diff --git a/c/debug/_demo/stacktrace/main.go b/c/debug/_demo/stacktrace/main.go new file mode 100644 index 000000000..303392095 --- /dev/null +++ b/c/debug/_demo/stacktrace/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "unsafe" + + "github.com/goplus/llgo/c/debug" +) + +type T struct { + n int +} + +func (t *T) Demo() { + println(t.n) + debug.StackTrace(0, func(fr *debug.Frame) bool { + var info debug.Info + debug.Addrinfo(unsafe.Pointer(fr.PC), &info) + println("[", fr.PC, "]", fr.Name, "+", fr.Offset, ", SP =", fr.SP) + return true + }) +} + +func main() { + t := &T{100} + t.Demo() +} diff --git a/c/debug/_wrap/debug.c b/c/debug/_wrap/debug.c index 7c7859195..51cdde326 100644 --- a/c/debug/_wrap/debug.c +++ b/c/debug/_wrap/debug.c @@ -4,6 +4,7 @@ #endif #include +#include void *llgo_address() { return __builtin_return_address(0); @@ -12,3 +13,26 @@ void *llgo_address() { int llgo_addrinfo(void *addr, Dl_info *info) { return dladdr(addr, info); } + +void llgo_stacktrace(int skip, void *ctx, int (*fn)(void *ctx, void *pc, void *offset, void *sp, char *name)) { + unw_cursor_t cursor; + unw_context_t context; + unw_word_t offset, pc, sp; + char fname[256]; + unw_getcontext(&context); + unw_init_local(&cursor, &context); + int depth = 0; + while (unw_step(&cursor) > 0) { + if (depth < skip) { + depth++; + continue; + } + if (unw_get_reg(&cursor, UNW_REG_IP, &pc) == 0) { + unw_get_proc_name(&cursor, fname, sizeof(fname), &offset); + unw_get_reg(&cursor, UNW_REG_SP, &sp); + if (fn(ctx, (void*)pc, (void*)offset, (void*)sp, fname) == 0) { + return; + } + } + } +} diff --git a/c/debug/debug.go b/c/debug/debug.go index 8170e3731..c208d3c4f 100644 --- a/c/debug/debug.go +++ b/c/debug/debug.go @@ -23,3 +23,23 @@ func Address() unsafe.Pointer //go:linkname Addrinfo C.llgo_addrinfo func Addrinfo(addr unsafe.Pointer, info *Info) c.Int + +//go:linkname stacktrace C.llgo_stacktrace +func stacktrace(skip c.Int, ctx unsafe.Pointer, fn func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int) + +type Frame struct { + PC uintptr + Offset uintptr + SP unsafe.Pointer + Name string +} + +func StackTrace(skip int, fn func(fr *Frame) bool) { + stacktrace(c.Int(1+skip), unsafe.Pointer(&fn), func(ctx, pc, offset, sp unsafe.Pointer, name *c.Char) c.Int { + fn := *(*func(fr *Frame) bool)(ctx) + if !fn(&Frame{uintptr(pc), uintptr(offset), sp, c.GoString(name)}) { + return 0 + } + return 1 + }) +}