feature. See also
. The project being documented here (as the example) is the Zig library itself.
debug.ConfigurableTrace
pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime is_enabled: bool) type
File
Code
pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime is_enabled: bool) type {
return struct {
addrs: [actual_size][stack_frame_count]usize,
notes: [actual_size][]const u8,
index: Index,
const actual_size = if (enabled) size else 0;
const Index = if (enabled) usize else u0;
pub const init: @This() = .{
.addrs = undefined,
.notes = undefined,
.index = 0,
};
pub const enabled = is_enabled;
pub const add = if (enabled) addNoInline else addNoOp;
pub noinline fn addNoInline(t: *@This(), note: []const u8) void {
comptime assert(enabled);
return addAddr(t, @returnAddress(), note);
}
pub inline fn addNoOp(t: *@This(), note: []const u8) void {
_ = t;
_ = note;
comptime assert(!enabled);
}
pub fn addAddr(t: *@This(), addr: usize, note: []const u8) void {
if (!enabled) return;
if (t.index < size) {
t.notes[t.index] = note;
const addrs = &t.addrs[t.index];
const st = captureCurrentStackTrace(.{ .first_address = addr }, addrs);
if (st.return_addresses.len < addrs.len) {
@memset(addrs[st.return_addresses.len..], 0);
}
}
// user can find out how much more size they need.
t.index += 1;
}
pub fn dump(t: @This()) void {
if (!enabled) return;
const stderr = lockStderr(&.{}).terminal();
defer unlockStderr();
const end = @min(t.index, size);
for (t.addrs[0..end], 0..) |frames_array, i| {
stderr.writer.print("{s}:\n", .{t.notes[i]}) catch return;
var frames_array_mutable = frames_array;
const frames = mem.sliceTo(frames_array_mutable[0..], 0);
const len = @min(t.index, frames.len);
const stack_trace: StackTrace = .{
.return_addresses = frames[0..len],
.skipped = if (len < frames.len) .none else .unknown,
};
writeStackTrace(&stack_trace, stderr) catch return;
}
if (t.index > end) {
stderr.writer.print("{d} more traces not shown; consider increasing trace size\n", .{
t.index - end,
}) catch return;
}
}
pub fn format(
t: @This(),
comptime fmt: []const u8,
options: std.fmt.Options,
writer: *Writer,
) !void {
if (fmt.len != 0) std.fmt.invalidFmtError(fmt, t);
_ = options;
if (enabled) {
try writer.writeAll("\n");
t.dump();
try writer.writeAll("\n");
} else {
return writer.writeAll("(value tracing disabled)");
}
}
};
}