captureStackTrace
Returns a slice with the same pointer as addresses, with a potentially smaller len. On Windows, when first_address is not null, we ask for at least 32 stack frames, and then try to find the first address. If addresses.len is more than 32, we capture that many stack frames exactly, and then look for the first address, chopping off the irrelevant frames and shifting so that the returned addresses pointer equals the passed in addresses pointer.
Function parameters
Parameters
- first_address:?usize
- stack_trace:*std.builtin.StackTrace
Type definitions in this namespace
Types
- SourceLocation
- Unresolved source locations can be represented with a single `usize` that
A fully-featured panic handler namespace which lowers all panics to calls to `panicFn`.
Functions
- FullPanic
- A fully-featured panic handler namespace which lowers all panics to calls to `panicFn`.
- lockStdErr
- Allows the caller to freely write to stderr until `unlockStdErr` is called.
- lockStderrWriter
- Allows the caller to freely write to stderr until `unlockStdErr` is called.
- Print to stderr, silently returning on failure.
- dumpHex
- Tries to print a hexadecimal view of the bytes, unbuffered, and ignores any error returned.
- dumpHexFallible
- Prints a hexadecimal view of the bytes, returning any error that occurs.
- dumpCurrentStackTrace
- Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
- dumpCurrentStackTraceToWriter
- Prints the current stack trace to the provided writer.
- copyContext
- Copies one context to another, updating any internal pointers
- relocateContext
- Updates any internal pointers in the context to reflect its current location
- getContext
- Capture the current context.
- dumpStackTraceFromBase
- Tries to print the stack trace starting from the supplied base pointer to stderr,
- captureStackTrace
- Returns a slice with the same pointer as addresses, with a potentially smaller len.
- dumpStackTrace
- Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
- assert
- Invokes detectable illegal behavior when `ok` is `false`.
- assertReadable
- Invokes detectable illegal behavior when the provided slice is not mapped
- assertAligned
- Invokes detectable illegal behavior when the provided array is not aligned
- panic
- Equivalent to `@panic` but with a formatted message.
- panicExtra
- Equivalent to `@panic` but with a formatted message, and with an explicitly
- defaultPanic
- Dumps a stack trace to standard error, then aborts.
- attachSegfaultHandler
- Attaches a global SIGSEGV handler which calls `@panic("segmentation fault");`
- inValgrind
- Detect whether the program is being executed in the Valgrind virtual machine.
Deprecated because it returns the optimization mode of the standard
Values
- runtime_safety
- Deprecated because it returns the optimization mode of the standard
- sys_can_stack_trace
- = switch (builtin.cpu.arch) { // Observed to go into an infinite loop. // TODO: Make this work. .mips, .mipsel, .mips64, .mips64el, .s390x, => false, // `@returnAddress()` in LLVM 10 gives // "Non-Emscripten WebAssembly hasn't implemented __builtin_return_address". // On Emscripten, Zig only supports `@returnAddress()` in debug builds // because Emscripten's implementation is very slow. .wasm32, .wasm64, => native_os == .emscripten and builtin.mode == .Debug, // `@returnAddress()` is unsupported in LLVM 13. .bpfel, .bpfeb, => false, else => true, }
- have_ucontext
- = posix.ucontext_t != void
- ThreadContext
- Platform-specific thread state.
- have_getcontext
- = @TypeOf(posix.system.getcontext) != void
- have_segfault_handling_support
- Whether or not the current target can print useful debug information when a segfault occurs.
- default_enable_segfault_handler
- = runtime_safety and have_segfault_handling_support
Source
Implementation
pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackTrace) void {
if (native_os == .windows) {
const addrs = stack_trace.instruction_addresses;
const first_addr = first_address orelse {
stack_trace.index = walkStackWindows(addrs[0..], null);
return;
};
var addr_buf_stack: [32]usize = undefined;
const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs;
const n = walkStackWindows(addr_buf[0..], null);
const first_index = for (addr_buf[0..n], 0..) |addr, i| {
if (addr == first_addr) {
break i;
}
} else {
stack_trace.index = 0;
return;
};
const end_index = @min(first_index + addrs.len, n);
const slice = addr_buf[first_index..end_index];
// We use a for loop here because slice and addrs may alias.
for (slice, 0..) |addr, i| {
addrs[i] = addr;
}
stack_trace.index = slice.len;
} else {
// TODO: This should use the DWARF unwinder if .eh_frame_hdr is available (so that full debug info parsing isn't required).
// A new path for loading SelfInfo needs to be created which will only attempt to parse in-memory sections, because
// stopping to load other debug info (ie. source line info) from disk here is not required for unwinding.
var it = StackIterator.init(first_address, null);
defer it.deinit();
for (stack_trace.instruction_addresses, 0..) |*addr, i| {
addr.* = it.next() orelse {
stack_trace.index = i;
return;
};
}
stack_trace.index = stack_trace.instruction_addresses.len;
}
}