mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std: allow disabling stack tracing
This option disables both capturing and printing stack traces. The default is to disable if debug info is stripped.
This commit is contained in:
parent
abb2b1e2da
commit
3a9c680ad7
@ -567,13 +567,11 @@ pub const StackUnwindOptions = struct {
|
|||||||
///
|
///
|
||||||
/// See `writeCurrentStackTrace` to immediately print the trace instead of capturing it.
|
/// See `writeCurrentStackTrace` to immediately print the trace instead of capturing it.
|
||||||
pub fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: []usize) std.builtin.StackTrace {
|
pub fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: []usize) std.builtin.StackTrace {
|
||||||
var it = StackIterator.init(options.context) catch {
|
const empty_trace: std.builtin.StackTrace = .{ .index = 0, .instruction_addresses = &.{} };
|
||||||
return .{ .index = 0, .instruction_addresses = &.{} };
|
if (!std.options.allow_stack_tracing) return empty_trace;
|
||||||
};
|
var it = StackIterator.init(options.context) catch return empty_trace;
|
||||||
defer it.deinit();
|
defer it.deinit();
|
||||||
if (!it.stratOk(options.allow_unsafe_unwind)) {
|
if (!it.stratOk(options.allow_unsafe_unwind)) return empty_trace;
|
||||||
return .{ .index = 0, .instruction_addresses = &.{} };
|
|
||||||
}
|
|
||||||
var frame_idx: usize = 0;
|
var frame_idx: usize = 0;
|
||||||
var wait_for = options.first_address;
|
var wait_for = options.first_address;
|
||||||
while (true) switch (it.next()) {
|
while (true) switch (it.next()) {
|
||||||
@ -599,6 +597,12 @@ pub fn captureCurrentStackTrace(options: StackUnwindOptions, addr_buf: []usize)
|
|||||||
///
|
///
|
||||||
/// See `captureCurrentStackTrace` to capture the trace addresses into a buffer instead of printing.
|
/// See `captureCurrentStackTrace` to capture the trace addresses into a buffer instead of printing.
|
||||||
pub fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Writer, tty_config: tty.Config) Writer.Error!void {
|
pub fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Writer, tty_config: tty.Config) Writer.Error!void {
|
||||||
|
if (!std.options.allow_stack_tracing) {
|
||||||
|
tty_config.setColor(writer, .dim) catch {};
|
||||||
|
try writer.print("Cannot print stack trace: stack tracing is disabled\n", .{});
|
||||||
|
tty_config.setColor(writer, .reset) catch {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
const di_gpa = getDebugInfoAllocator();
|
const di_gpa = getDebugInfoAllocator();
|
||||||
const di = getSelfDebugInfo() catch |err| switch (err) {
|
const di = getSelfDebugInfo() catch |err| switch (err) {
|
||||||
error.UnsupportedTarget => {
|
error.UnsupportedTarget => {
|
||||||
@ -688,6 +692,12 @@ pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void {
|
|||||||
|
|
||||||
/// Write a previously captured stack trace to `writer`, annotated with source locations.
|
/// Write a previously captured stack trace to `writer`, annotated with source locations.
|
||||||
pub fn writeStackTrace(st: *const std.builtin.StackTrace, writer: *Writer, tty_config: tty.Config) Writer.Error!void {
|
pub fn writeStackTrace(st: *const std.builtin.StackTrace, writer: *Writer, tty_config: tty.Config) Writer.Error!void {
|
||||||
|
if (!std.options.allow_stack_tracing) {
|
||||||
|
tty_config.setColor(writer, .dim) catch {};
|
||||||
|
try writer.print("Cannot print stack trace: stack tracing is disabled\n", .{});
|
||||||
|
tty_config.setColor(writer, .reset) catch {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Fetch `st.index` straight away. Aside from avoiding redundant loads, this prevents issues if
|
// Fetch `st.index` straight away. Aside from avoiding redundant loads, this prevents issues if
|
||||||
// `st` is `@errorReturnTrace()` and errors are encountered while writing the stack trace.
|
// `st` is `@errorReturnTrace()` and errors are encountered while writing the stack trace.
|
||||||
const n_frames = st.index;
|
const n_frames = st.index;
|
||||||
|
|||||||
@ -171,6 +171,22 @@ pub const Options = struct {
|
|||||||
http_enable_ssl_key_log_file: bool = @import("builtin").mode == .Debug,
|
http_enable_ssl_key_log_file: bool = @import("builtin").mode == .Debug,
|
||||||
|
|
||||||
side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations,
|
side_channels_mitigations: crypto.SideChannelsMitigations = crypto.default_side_channels_mitigations,
|
||||||
|
|
||||||
|
/// Whether to allow capturing and writing stack traces. This affects the following functions:
|
||||||
|
/// * `debug.captureCurrentStackTrace`
|
||||||
|
/// * `debug.writeCurrentStackTrace`
|
||||||
|
/// * `debug.dumpCurrentStackTrace`
|
||||||
|
/// * `debug.writeStackTrace`
|
||||||
|
/// * `debug.dumpStackTrace`
|
||||||
|
///
|
||||||
|
/// Stack traces can generally be collected and printed when debug info is stripped, but are
|
||||||
|
/// often less useful since they usually cannot be mapped to source locations and/or have bad
|
||||||
|
/// source locations. The stack tracing logic can also be quite large, which may be undesirable,
|
||||||
|
/// particularly in ReleaseSmall.
|
||||||
|
///
|
||||||
|
/// If this is `false`, then captured stack traces will always be empty, and attempts to write
|
||||||
|
/// stack traces will just print an error to the relevant `Io.Writer` and return.
|
||||||
|
allow_stack_tracing: bool = !@import("builtin").strip_debug_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This forces the start.zig file to be imported, and the comptime logic inside that
|
// This forces the start.zig file to be imported, and the comptime logic inside that
|
||||||
|
|||||||
28
test/cases/disable_stack_tracing.zig
Normal file
28
test/cases/disable_stack_tracing.zig
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
pub const std_options: std.Options = .{
|
||||||
|
.allow_stack_tracing = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var st_buf: [8]usize = undefined;
|
||||||
|
var buf: [1024]u8 = undefined;
|
||||||
|
var stdout = std.fs.File.stdout().writer(&buf);
|
||||||
|
|
||||||
|
const captured_st = try foo(&stdout.interface, &st_buf);
|
||||||
|
try std.debug.writeStackTrace(&captured_st, &stdout.interface, .no_color);
|
||||||
|
try stdout.interface.print("stack trace index: {d}\n", .{captured_st.index});
|
||||||
|
|
||||||
|
try stdout.interface.flush();
|
||||||
|
}
|
||||||
|
fn foo(w: *std.Io.Writer, st_buf: []usize) !std.builtin.StackTrace {
|
||||||
|
try std.debug.writeCurrentStackTrace(.{}, w, .no_color);
|
||||||
|
return std.debug.captureCurrentStackTrace(.{}, st_buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
// run
|
||||||
|
//
|
||||||
|
// Cannot print stack trace: stack tracing is disabled
|
||||||
|
// Cannot print stack trace: stack tracing is disabled
|
||||||
|
// stack trace index: 0
|
||||||
|
//
|
||||||
Loading…
x
Reference in New Issue
Block a user