diff options
Diffstat (limited to 'core/debug/trace/trace_linux.odin')
| -rw-r--r-- | core/debug/trace/trace_linux.odin | 195 |
1 files changed, 0 insertions, 195 deletions
diff --git a/core/debug/trace/trace_linux.odin b/core/debug/trace/trace_linux.odin deleted file mode 100644 index 211c379ca..000000000 --- a/core/debug/trace/trace_linux.odin +++ /dev/null @@ -1,195 +0,0 @@ -//+private file -//+build linux -package debug_trace - -import "base:intrinsics" -import "base:runtime" -import "core:strings" -import "core:fmt" -import "core:c" - -// NOTE: Relies on C++23 which adds <stacktrace> and becomes ABI and that can be used -foreign import stdcpplibbacktrace "system:stdc++_libbacktrace" - -foreign import libdl "system:dl" - -backtrace_state :: struct {} -backtrace_error_callback :: proc "c" (data: rawptr, msg: cstring, errnum: c.int) -backtrace_simple_callback :: proc "c" (data: rawptr, pc: uintptr) -> c.int -backtrace_full_callback :: proc "c" (data: rawptr, pc: uintptr, filename: cstring, lineno: c.int, function: cstring) -> c.int -backtrace_syminfo_callback :: proc "c" (data: rawptr, pc: uintptr, symname: cstring, symval: uintptr, symsize: uintptr) - -@(default_calling_convention="c", link_prefix="__glibcxx_") -foreign stdcpplibbacktrace { - backtrace_create_state :: proc( - filename: cstring, - threaded: c.int, - error_callback: backtrace_error_callback, - data: rawptr, - ) -> ^backtrace_state --- - backtrace_simple :: proc( - state: ^backtrace_state, - skip: c.int, - callback: backtrace_simple_callback, - error_callback: backtrace_error_callback, - data: rawptr, - ) -> c.int --- - backtrace_pcinfo :: proc( - state: ^backtrace_state, - pc: uintptr, - callback: backtrace_full_callback, - error_callback: backtrace_error_callback, - data: rawptr, - ) -> c.int --- - backtrace_syminfo :: proc( - state: ^backtrace_state, - addr: uintptr, - callback: backtrace_syminfo_callback, - error_callback: backtrace_error_callback, - data: rawptr, - ) -> c.int --- - - // NOTE(bill): this is technically an internal procedure, but it is exposed - backtrace_free :: proc( - state: ^backtrace_state, - p: rawptr, - size: c.size_t, // unused - error_callback: backtrace_error_callback, // unused - data: rawptr, // unused - ) --- -} - -Dl_info :: struct { - dli_fname: cstring, - dli_fbase: rawptr, - dli_sname: cstring, - dli_saddr: rawptr, -} - -@(default_calling_convention="c") -foreign libdl { - dladdr :: proc(addr: rawptr, info: ^Dl_info) -> c.int --- -} - -@(private="package") -_Context :: struct { - state: ^backtrace_state, -} - -@(private="package") -_init :: proc(ctx: ^Context) -> (ok: bool) { - defer if !ok do destroy(ctx) - - ctx.impl.state = backtrace_create_state("odin-debug-trace", 1, nil, ctx) - return ctx.impl.state != nil -} - -@(private="package") -_destroy :: proc(ctx: ^Context) -> bool { - if ctx != nil { - backtrace_free(ctx.impl.state, nil, 0, nil, nil) - } - return true -} - -@(private="package") -_frames :: proc "contextless" (ctx: ^Context, skip: uint, frames_buffer: []Frame) -> (frames: []Frame) { - Backtrace_Context :: struct { - ctx: ^Context, - frames: []Frame, - frame_count: int, - } - - btc := &Backtrace_Context{ - ctx = ctx, - frames = frames_buffer, - } - backtrace_simple( - ctx.impl.state, - c.int(skip + 2), - proc "c" (user: rawptr, address: uintptr) -> c.int { - btc := (^Backtrace_Context)(user) - address := Frame(address) - if address == 0 { - return 1 - } - if btc.frame_count == len(btc.frames) { - return 1 - } - btc.frames[btc.frame_count] = address - btc.frame_count += 1 - return 0 - }, - nil, - btc, - ) - - if btc.frame_count > 0 { - frames = btc.frames[:btc.frame_count] - } - return -} - -@(private="package") -_resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> Frame_Location { - intrinsics.atomic_store(&ctx.in_resolve, true) - defer intrinsics.atomic_store(&ctx.in_resolve, false) - - Backtrace_Context :: struct { - rt_ctx: runtime.Context, - allocator: runtime.Allocator, - frame: Frame_Location, - } - - btc := &Backtrace_Context{ - rt_ctx = context, - allocator = allocator, - } - done := backtrace_pcinfo( - ctx.impl.state, - uintptr(frame), - proc "c" (data: rawptr, address: uintptr, file: cstring, line: c.int, symbol: cstring) -> c.int { - btc := (^Backtrace_Context)(data) - context = btc.rt_ctx - - frame := &btc.frame - - if file != nil { - frame.file_path = strings.clone_from_cstring(file, btc.allocator) - } else if info: Dl_info; dladdr(rawptr(address), &info) != 0 && info.dli_fname != "" { - frame.file_path = strings.clone_from_cstring(info.dli_fname, btc.allocator) - } - if symbol != nil { - frame.procedure = strings.clone_from_cstring(symbol, btc.allocator) - } else if info: Dl_info; dladdr(rawptr(address), &info) != 0 && info.dli_sname != "" { - frame.procedure = strings.clone_from_cstring(info.dli_sname, btc.allocator) - } else { - frame.procedure = fmt.aprintf("(procedure: 0x%x)", allocator=btc.allocator) - } - frame.line = i32(line) - return 0 - }, - nil, - btc, - ) - if done != 0 { - return btc.frame - } - - // NOTE(bill): pcinfo cannot resolve, but it might be possible to get the procedure name at least - backtrace_syminfo( - ctx.impl.state, - uintptr(frame), - proc "c" (data: rawptr, address: uintptr, symbol: cstring, _ignore0, _ignore1: uintptr) { - if symbol != nil { - btc := (^Backtrace_Context)(data) - context = btc.rt_ctx - btc.frame.procedure = strings.clone_from_cstring(symbol, btc.allocator) - } - }, - nil, - btc, - ) - - return btc.frame -}
\ No newline at end of file |