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.
pubfndefaultHandleSegfault(addr: ?usize, name: []constu8, opt_ctx: ?CpuContextPtr) noreturn {
std.Options.debug_io.vtable.crashHandler(std.Options.debug_io.userdata);
// There is very similar logic to the following in `defaultPanic`.switch (panic_stage) {
0 => {
panic_stage = 1;
_ = panicking.fetchAdd(1, .seq_cst);
trace: {
conststderr = lockStderr(&.{}).terminal();
deferunlockStderr();
if (addr) |a| {
stderr.writer.print("{s} at address 0x{x}\n", .{ name, a }) catchbreak :trace;
} else {
stderr.writer.print("{s} (no address available)\n", .{name}) catchbreak :trace;
}
if (opt_ctx) |context| {
writeCurrentStackTrace(.{
.context = context,
.allow_unsafe_unwind = true, // we're crashing anyway, give it our all!
}, stderr) catchbreak :trace;
}
}
},
1 => {
panic_stage = 2;
// A segfault happened while trying to print a previous panic message.
// We're still holding the mutex but that's fine as we're going to
// call abort().
conststderr = lockStderr(&.{}).terminal();
stderr.writer.writeAll("aborting due to recursive panic\n") catch {};
},
else => {}, // Panicked while printing the recursive panic message.
}
// We cannot allow the signal handler to return because when it runs the original instruction
// again, the memory may be mapped and undefined behavior would occur rather than repeating
// the segfault. So we simply abort here.
std.process.abort();
}