| ... | ... | @@ -137,7 +137,7 @@ pub const StackTraceContext = blk: { |
| 137 | 137 | if (native_os == .windows) { |
| 138 | 138 | break :blk @typeInfo(@TypeOf(os.windows.CONTEXT.getRegs)).Fn.return_type.?; |
| 139 | 139 | } else if (@hasDecl(os.system, "ucontext_t")) { |
| 140 | | break :blk *const os.ucontext_t; |
| 140 | break :blk os.ucontext_t; |
| 141 | 141 | } else { |
| 142 | 142 | break :blk void; |
| 143 | 143 | } |
| ... | ... | @@ -146,7 +146,7 @@ pub const StackTraceContext = blk: { |
| 146 | 146 | /// Tries to print the stack trace starting from the supplied base pointer to stderr, |
| 147 | 147 | /// unbuffered, and ignores any error returned. |
| 148 | 148 | /// TODO multithreaded awareness |
| 149 | | pub fn dumpStackTraceFromBase(context: StackTraceContext) void { |
| 149 | pub fn dumpStackTraceFromBase(context: *const StackTraceContext) void { |
| 150 | 150 | nosuspend { |
| 151 | 151 | if (comptime builtin.target.isWasm()) { |
| 152 | 152 | if (native_os == .wasi) { |
| ... | ... | @@ -413,6 +413,14 @@ pub fn writeStackTrace( |
| 413 | 413 | } |
| 414 | 414 | } |
| 415 | 415 | |
| 416 | inline fn getContext(context: *StackTraceContext) bool { |
| 417 | if (native_os == .windows) { |
| 418 | @compileError("Syscall please!"); |
| 419 | } |
| 420 | |
| 421 | return @hasDecl(os.system, "getcontext") and os.system.getcontext(context) == 0; |
| 422 | } |
| 423 | |
| 416 | 424 | pub const StackIterator = struct { |
| 417 | 425 | // Skip every frame before this address is found. |
| 418 | 426 | first_address: ?usize, |
| ... | ... | @@ -423,7 +431,7 @@ pub const StackIterator = struct { |
| 423 | 431 | // stacks with frames that don't use a frame pointer (ie. -fomit-frame-pointer). |
| 424 | 432 | debug_info: ?*DebugInfo, |
| 425 | 433 | dwarf_context: if (supports_context) DW.UnwindContext else void = undefined, |
| 426 | | const supports_context = @hasDecl(os.system, "ucontext_t") and |
| 434 | pub const supports_context = @hasDecl(os.system, "ucontext_t") and |
| 427 | 435 | (builtin.os.tag != .linux or switch (builtin.cpu.arch) { |
| 428 | 436 | .mips, .mipsel, .mips64, .mips64el, .riscv64 => false, |
| 429 | 437 | else => true, |
| ... | ... | @@ -607,8 +615,10 @@ pub fn writeCurrentStackTrace( |
| 607 | 615 | return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr); |
| 608 | 616 | } |
| 609 | 617 | |
| 610 | | // TODO: Capture a context and use initWithContext |
| 611 | | var it = StackIterator.init(start_addr, null); |
| 618 | var context: StackTraceContext = undefined; |
| 619 | var it = (if (getContext(&context)) blk: { |
| 620 | break :blk StackIterator.initWithContext(start_addr, debug_info, &context) catch null; |
| 621 | } else null) orelse StackIterator.init(start_addr, null); |
| 612 | 622 | defer it.deinit(); |
| 613 | 623 | |
| 614 | 624 | while (it.next()) |return_address| { |
| ... | ... | @@ -2163,7 +2173,7 @@ fn dumpSegfaultInfoWindows(info: *windows.EXCEPTION_POINTERS, msg: u8, label: ?[ |
| 2163 | 2173 | else => unreachable, |
| 2164 | 2174 | } catch os.abort(); |
| 2165 | 2175 | |
| 2166 | | dumpStackTraceFromBase(regs); |
| 2176 | dumpStackTraceFromBase(&regs); |
| 2167 | 2177 | } |
| 2168 | 2178 | |
| 2169 | 2179 | pub fn dumpStackPointerAddr(prefix: []const u8) void { |