diff options
| author | kcbanner <kcbanner@gmail.com> | 2023-06-26 00:59:28 -0400 |
|---|---|---|
| committer | kcbanner <kcbanner@gmail.com> | 2023-07-20 22:58:14 -0400 |
| commit | 5cd8ab2473a4255f081f417eb3ec95e1a3a9e9d8 (patch) | |
| tree | 2ee974ba827afe762cd96d327019618c95f3a6b8 /lib/std/debug.zig | |
| parent | a9b6f2d92984e1b4d4a9fe2b0ba0b14ec8b812c5 (diff) | |
| download | zig-5cd8ab2473a4255f081f417eb3ec95e1a3a9e9d8.tar.gz zig-5cd8ab2473a4255f081f417eb3ec95e1a3a9e9d8.zip | |
debug: enhance writeCurrentStackTrace to use context-based unwinding when available
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 1ae26da247..5428d7a33b 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -137,7 +137,7 @@ pub const StackTraceContext = blk: { if (native_os == .windows) { break :blk @typeInfo(@TypeOf(os.windows.CONTEXT.getRegs)).Fn.return_type.?; } else if (@hasDecl(os.system, "ucontext_t")) { - break :blk *const os.ucontext_t; + break :blk os.ucontext_t; } else { break :blk void; } @@ -146,7 +146,7 @@ pub const StackTraceContext = blk: { /// Tries to print the stack trace starting from the supplied base pointer to stderr, /// unbuffered, and ignores any error returned. /// TODO multithreaded awareness -pub fn dumpStackTraceFromBase(context: StackTraceContext) void { +pub fn dumpStackTraceFromBase(context: *const StackTraceContext) void { nosuspend { if (comptime builtin.target.isWasm()) { if (native_os == .wasi) { @@ -413,6 +413,14 @@ pub fn writeStackTrace( } } +inline fn getContext(context: *StackTraceContext) bool { + if (native_os == .windows) { + @compileError("Syscall please!"); + } + + return @hasDecl(os.system, "getcontext") and os.system.getcontext(context) == 0; +} + pub const StackIterator = struct { // Skip every frame before this address is found. first_address: ?usize, @@ -423,7 +431,7 @@ pub const StackIterator = struct { // stacks with frames that don't use a frame pointer (ie. -fomit-frame-pointer). debug_info: ?*DebugInfo, dwarf_context: if (supports_context) DW.UnwindContext else void = undefined, - const supports_context = @hasDecl(os.system, "ucontext_t") and + pub const supports_context = @hasDecl(os.system, "ucontext_t") and (builtin.os.tag != .linux or switch (builtin.cpu.arch) { .mips, .mipsel, .mips64, .mips64el, .riscv64 => false, else => true, @@ -607,8 +615,10 @@ pub fn writeCurrentStackTrace( return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr); } - // TODO: Capture a context and use initWithContext - var it = StackIterator.init(start_addr, null); + var context: StackTraceContext = undefined; + var it = (if (getContext(&context)) blk: { + break :blk StackIterator.initWithContext(start_addr, debug_info, &context) catch null; + } else null) orelse StackIterator.init(start_addr, null); defer it.deinit(); while (it.next()) |return_address| { @@ -2163,7 +2173,7 @@ fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[ else => unreachable, } catch os.abort(); - dumpStackTraceFromBase(regs); + dumpStackTraceFromBase(®s); } pub fn dumpStackPointerAddr(prefix: []const u8) void { |
