Function dumpStackTraceFromBase [src]

Tries to print the stack trace starting from the supplied base pointer to stderr, unbuffered, and ignores any error returned. TODO multithreaded awareness

Prototype

pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *Writer) void

Parameters

context: *ThreadContextstderr: *Writer

Source

pub fn dumpStackTraceFromBase(context: *ThreadContext, stderr: *Writer) void { nosuspend { if (builtin.target.cpu.arch.isWasm()) { if (native_os == .wasi) { stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; } return; } if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; return; } const debug_info = getSelfDebugInfo() catch |err| { stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return; return; }; const tty_config = tty.detectConfig(.stderr()); if (native_os == .windows) { // On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context // provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace // will be captured and frames prior to the exception will be filtered. // The caveat is that RtlCaptureStackBackTrace does not include the KiUserExceptionDispatcher frame, // which is where the IP in `context` points to, so it can't be used as start_addr. // Instead, start_addr is recovered from the stack. const start_addr = if (builtin.cpu.arch == .x86) @as(*const usize, @ptrFromInt(context.getRegs().bp + 4)).* else null; writeStackTraceWindows(stderr, debug_info, tty_config, context, start_addr) catch return; return; } var it = StackIterator.initWithContext(null, debug_info, context, @frameAddress()) catch return; defer it.deinit(); // DWARF unwinding on aarch64-macos is not complete so we need to get pc address from mcontext const pc_addr = if (builtin.target.os.tag.isDarwin() and native_arch == .aarch64) context.mcontext.ss.pc else it.unwind_state.?.dwarf_context.pc; printSourceAtAddress(debug_info, stderr, pc_addr, tty_config) catch return; while (it.next()) |return_address| { printLastUnwindError(&it, debug_info, stderr, tty_config); // On arm64 macOS, the address of the last frame is 0x0 rather than 0x1 as on x86_64 macOS, // therefore, we do a check for `return_address == 0` before subtracting 1 from it to avoid // an overflow. We do not need to signal `StackIterator` as it will correctly detect this // condition on the subsequent iteration and return `null` thus terminating the loop. // same behaviour for x86-windows-msvc const address = if (return_address == 0) return_address else return_address - 1; printSourceAtAddress(debug_info, stderr, address, tty_config) catch return; } else printLastUnwindError(&it, debug_info, stderr, tty_config); } }