mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
std.Build: make number of collected stack frames configurable
This commit is contained in:
parent
0461a64a93
commit
078e330555
@ -102,6 +102,10 @@ args: ?[][]const u8 = null,
|
|||||||
debug_log_scopes: []const []const u8 = &.{},
|
debug_log_scopes: []const []const u8 = &.{},
|
||||||
debug_compile_errors: bool = false,
|
debug_compile_errors: bool = false,
|
||||||
debug_pkg_config: bool = false,
|
debug_pkg_config: bool = false,
|
||||||
|
/// Number of stack frames captured when a `StackTrace` is recorded for debug purposes,
|
||||||
|
/// in particular at `Step` creation.
|
||||||
|
/// Set to 0 to disable stack collection.
|
||||||
|
debug_stack_frames_count: u8 = 8,
|
||||||
|
|
||||||
/// Experimental. Use system Darling installation to run cross compiled macOS build artifacts.
|
/// Experimental. Use system Darling installation to run cross compiled macOS build artifacts.
|
||||||
enable_darling: bool = false,
|
enable_darling: bool = false,
|
||||||
@ -1764,33 +1768,49 @@ pub fn dumpBadGetPathHelp(
|
|||||||
});
|
});
|
||||||
|
|
||||||
const tty_config = std.io.tty.detectConfig(stderr);
|
const tty_config = std.io.tty.detectConfig(stderr);
|
||||||
tty_config.setColor(w, .red) catch {};
|
if (s.getStackTrace()) |stack_trace| {
|
||||||
try stderr.writeAll(" The step was created by this stack trace:\n");
|
|
||||||
tty_config.setColor(w, .reset) catch {};
|
|
||||||
|
|
||||||
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
|
|
||||||
try w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
const ally = debug_info.allocator;
|
|
||||||
std.debug.writeStackTrace(s.getStackTrace(), w, ally, debug_info, tty_config) catch |err| {
|
|
||||||
try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
if (asking_step) |as| {
|
|
||||||
tty_config.setColor(w, .red) catch {};
|
tty_config.setColor(w, .red) catch {};
|
||||||
try stderr.writeAll(" The step that is missing a dependency on the above step was created by this stack trace:\n");
|
try stderr.writeAll(" The step was created by this stack trace:\n");
|
||||||
tty_config.setColor(w, .reset) catch {};
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
|
||||||
std.debug.writeStackTrace(as.getStackTrace(), w, ally, debug_info, tty_config) catch |err| {
|
const debug_info = std.debug.getSelfDebugInfo() catch |err| {
|
||||||
|
try w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
const ally = debug_info.allocator;
|
||||||
|
|
||||||
|
std.debug.writeStackTrace(stack_trace, w, ally, debug_info, tty_config) catch |err| {
|
||||||
try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
|
try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
}
|
if (asking_step) |as| {
|
||||||
|
tty_config.setColor(w, .red) catch {};
|
||||||
|
try stderr.writer().print(" The step '{s}' that is missing a dependency on the above step was created by this stack trace:\n", .{as.name});
|
||||||
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
|
||||||
tty_config.setColor(w, .red) catch {};
|
if (as.getStackTrace()) |as_stack_trace| {
|
||||||
try stderr.writeAll(" Hope that helps. Proceeding to panic.\n");
|
std.debug.writeStackTrace(as_stack_trace, w, ally, debug_info, tty_config) catch |err| {
|
||||||
tty_config.setColor(w, .reset) catch {};
|
try stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const field = "debug_stack_frames_count";
|
||||||
|
comptime assert(@hasField(Build, field));
|
||||||
|
tty_config.setColor(w, .yellow) catch {};
|
||||||
|
try stderr.writer().print("no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{});
|
||||||
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tty_config.setColor(w, .red) catch {};
|
||||||
|
try stderr.writeAll(" Hope that helps. Proceeding to panic.\n");
|
||||||
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
} else {
|
||||||
|
const field = "debug_stack_frames_count";
|
||||||
|
comptime assert(@hasField(Build, field));
|
||||||
|
tty_config.setColor(w, .yellow) catch {};
|
||||||
|
try stderr.writer().print("no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{});
|
||||||
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates a new string for assigning a value to a named macro.
|
/// Allocates a new string for assigning a value to a named macro.
|
||||||
|
|||||||
@ -39,7 +39,7 @@ test_results: TestResults,
|
|||||||
|
|
||||||
/// The return address associated with creation of this step that can be useful
|
/// The return address associated with creation of this step that can be useful
|
||||||
/// to print along with debugging messages.
|
/// to print along with debugging messages.
|
||||||
debug_stack_trace: [n_debug_stack_frames]usize,
|
debug_stack_trace: []usize,
|
||||||
|
|
||||||
pub const TestResults = struct {
|
pub const TestResults = struct {
|
||||||
fail_count: u32 = 0,
|
fail_count: u32 = 0,
|
||||||
@ -58,8 +58,6 @@ pub const TestResults = struct {
|
|||||||
|
|
||||||
pub const MakeFn = *const fn (self: *Step, prog_node: *std.Progress.Node) anyerror!void;
|
pub const MakeFn = *const fn (self: *Step, prog_node: *std.Progress.Node) anyerror!void;
|
||||||
|
|
||||||
const n_debug_stack_frames = 4;
|
|
||||||
|
|
||||||
pub const State = enum {
|
pub const State = enum {
|
||||||
precheck_unstarted,
|
precheck_unstarted,
|
||||||
precheck_started,
|
precheck_started,
|
||||||
@ -140,14 +138,6 @@ pub const StepOptions = struct {
|
|||||||
pub fn init(options: StepOptions) Step {
|
pub fn init(options: StepOptions) Step {
|
||||||
const arena = options.owner.allocator;
|
const arena = options.owner.allocator;
|
||||||
|
|
||||||
var addresses = [1]usize{0} ** n_debug_stack_frames;
|
|
||||||
const first_ret_addr = options.first_ret_addr orelse @returnAddress();
|
|
||||||
var stack_trace = std.builtin.StackTrace{
|
|
||||||
.instruction_addresses = &addresses,
|
|
||||||
.index = 0,
|
|
||||||
};
|
|
||||||
std.debug.captureStackTrace(first_ret_addr, &stack_trace);
|
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.id = options.id,
|
.id = options.id,
|
||||||
.name = arena.dupe(u8, options.name) catch @panic("OOM"),
|
.name = arena.dupe(u8, options.name) catch @panic("OOM"),
|
||||||
@ -157,7 +147,17 @@ pub fn init(options: StepOptions) Step {
|
|||||||
.dependants = .{},
|
.dependants = .{},
|
||||||
.state = .precheck_unstarted,
|
.state = .precheck_unstarted,
|
||||||
.max_rss = options.max_rss,
|
.max_rss = options.max_rss,
|
||||||
.debug_stack_trace = addresses,
|
.debug_stack_trace = blk: {
|
||||||
|
const addresses = arena.alloc(usize, options.owner.debug_stack_frames_count) catch @panic("OOM");
|
||||||
|
@memset(addresses, 0);
|
||||||
|
const first_ret_addr = options.first_ret_addr orelse @returnAddress();
|
||||||
|
var stack_trace = std.builtin.StackTrace{
|
||||||
|
.instruction_addresses = addresses,
|
||||||
|
.index = 0,
|
||||||
|
};
|
||||||
|
std.debug.captureStackTrace(first_ret_addr, &stack_trace);
|
||||||
|
break :blk addresses;
|
||||||
|
},
|
||||||
.result_error_msgs = .{},
|
.result_error_msgs = .{},
|
||||||
.result_error_bundle = std.zig.ErrorBundle.empty,
|
.result_error_bundle = std.zig.ErrorBundle.empty,
|
||||||
.result_cached = false,
|
.result_cached = false,
|
||||||
@ -199,14 +199,14 @@ pub fn dependOn(self: *Step, other: *Step) void {
|
|||||||
self.dependencies.append(other) catch @panic("OOM");
|
self.dependencies.append(other) catch @panic("OOM");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getStackTrace(s: *Step) std.builtin.StackTrace {
|
pub fn getStackTrace(s: *Step) ?std.builtin.StackTrace {
|
||||||
const stack_addresses = &s.debug_stack_trace;
|
|
||||||
var len: usize = 0;
|
var len: usize = 0;
|
||||||
while (len < n_debug_stack_frames and stack_addresses[len] != 0) {
|
while (len < s.debug_stack_trace.len and s.debug_stack_trace[len] != 0) {
|
||||||
len += 1;
|
len += 1;
|
||||||
}
|
}
|
||||||
return .{
|
|
||||||
.instruction_addresses = stack_addresses,
|
return if (len == 0) null else .{
|
||||||
|
.instruction_addresses = s.debug_stack_trace,
|
||||||
.index = len,
|
.index = len,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -245,11 +245,19 @@ pub fn dump(step: *Step) void {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const ally = debug_info.allocator;
|
const ally = debug_info.allocator;
|
||||||
w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {};
|
if (step.getStackTrace()) |stack_trace| {
|
||||||
std.debug.writeStackTrace(step.getStackTrace(), w, ally, debug_info, tty_config) catch |err| {
|
w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {};
|
||||||
stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {};
|
std.debug.writeStackTrace(stack_trace, w, ally, debug_info, tty_config) catch |err| {
|
||||||
return;
|
stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {};
|
||||||
};
|
return;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const field = "debug_stack_frames_count";
|
||||||
|
comptime assert(@hasField(Build, field));
|
||||||
|
tty_config.setColor(w, .yellow) catch {};
|
||||||
|
w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {};
|
||||||
|
tty_config.setColor(w, .reset) catch {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Step = @This();
|
const Step = @This();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user