Type Function ConfigurableTrace [src]

Prototype

pub fn ConfigurableTrace(comptime size: usize, comptime stack_frame_count: usize, comptime is_enabled: bool) type

Parameters

size: usizestack_frame_count: usizeis_enabled: bool

Source

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; t.addrs[t.index] = [1]usize{0} ** stack_frame_count; var stack_trace: std.builtin.StackTrace = .{ .index = 0, .instruction_addresses = &t.addrs[t.index], }; captureStackTrace(addr, &stack_trace); } // Keep counting even if the end is reached so that the // user can find out how much more size they need. t.index += 1; } pub fn dump(t: @This()) void { if (!enabled) return; const tty_config = io.tty.detectConfig(std.io.getStdErr()); const stderr = io.getStdErr().writer(); const end = @min(t.index, size); 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; }; for (t.addrs[0..end], 0..) |frames_array, i| { stderr.print("{s}:\n", .{t.notes[i]}) catch return; var frames_array_mutable = frames_array; const frames = mem.sliceTo(frames_array_mutable[0..], 0); const stack_trace: std.builtin.StackTrace = .{ .index = frames.len, .instruction_addresses = frames, }; writeStackTrace(stack_trace, stderr, debug_info, tty_config) catch continue; } if (t.index > end) { stderr.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.FormatOptions, writer: anytype, ) !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)"); } } }; }