Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

captureCurrentStackTrace

debug.captureCurrentStackTrace
pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: []usize) StackTrace

File

lib/std/debug.zig:674

Code

pub noinline fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: []usize) StackTrace {
    const empty_trace: StackTrace = .{
        .return_addresses = &.{},
        .skipped = .none,
    };
    if (!std.options.allow_stack_tracing) return empty_trace;
    var it: StackIterator = .init(options.context);
    defer it.deinit();
    if (!it.stratOk(options.allow_unsafe_unwind)) return empty_trace;

    const io = std.Options.debug_io;

    var total_frames: usize = 0;
    var index: usize = 0;
    var wait_for = options.first_address;
    // Ideally, we would iterate the whole stack so that the `index - min(buf.len, index)` would be
    // indicative of how many frames were skipped. However, this has a significant runtime cost
    // in some cases, so at least for now, we don't do that.
    const skipped: SkippedAddresses = while (index < addr_buf.len) switch (it.next(io)) {
        .switch_to_fp => if (!it.stratOk(options.allow_unsafe_unwind)) break .unknown,
        .end => break .none,
        .frame => |ret_addr| {
            if (total_frames > 10_000) {
                // Limit the number of frames in case of (e.g.) broken debug information which is
                // getting unwinding stuck in a loop.
                break .unknown;
            }
            total_frames += 1;
            if (wait_for) |target| {
                if (ret_addr != target) continue;
                wait_for = null;
            }
            addr_buf[index] = ret_addr;
            index += 1;
        },
    } else .unknown;
    return .{
        .return_addresses = addr_buf[0..index],
        .skipped = skipped,
    };
}