| ... | @@ -39,7 +39,7 @@ test_results: TestResults, | ... | @@ -39,7 +39,7 @@ test_results: TestResults, |
| 39 | | 39 | |
| 40 | /// The return address associated with creation of this step that can be useful | 40 | /// The return address associated with creation of this step that can be useful |
| 41 | /// to print along with debugging messages. | 41 | /// to print along with debugging messages. |
| 42 | debug_stack_trace: [n_debug_stack_frames]usize, | 42 | debug_stack_trace: []usize, |
| 43 | | 43 | |
| 44 | pub const TestResults = struct { | 44 | pub const TestResults = struct { |
| 45 | fail_count: u32 = 0, | 45 | fail_count: u32 = 0, |
| ... | @@ -58,8 +58,6 @@ pub const TestResults = struct { | ... | @@ -58,8 +58,6 @@ pub const TestResults = struct { |
| 58 | | 58 | |
| 59 | pub const MakeFn = *const fn (self: *Step, prog_node: *std.Progress.Node) anyerror!void; | 59 | pub const MakeFn = *const fn (self: *Step, prog_node: *std.Progress.Node) anyerror!void; |
| 60 | | 60 | |
| 61 | const n_debug_stack_frames = 4; | | |
| 62 | | | |
| 63 | pub const State = enum { | 61 | pub const State = enum { |
| 64 | precheck_unstarted, | 62 | precheck_unstarted, |
| 65 | precheck_started, | 63 | precheck_started, |
| ... | @@ -140,14 +138,6 @@ pub const StepOptions = struct { | ... | @@ -140,14 +138,6 @@ pub const StepOptions = struct { |
| 140 | pub fn init(options: StepOptions) Step { | 138 | pub fn init(options: StepOptions) Step { |
| 141 | const arena = options.owner.allocator; | 139 | const arena = options.owner.allocator; |
| 142 | | 140 | |
| 143 | var addresses = [1]usize{0} ** n_debug_stack_frames; | | |
| 144 | const first_ret_addr = options.first_ret_addr orelse @returnAddress(); | | |
| 145 | var stack_trace = std.builtin.StackTrace{ | | |
| 146 | .instruction_addresses = &addresses, | | |
| 147 | .index = 0, | | |
| 148 | }; | | |
| 149 | std.debug.captureStackTrace(first_ret_addr, &stack_trace); | | |
| 150 | | | |
| 151 | return .{ | 141 | return .{ |
| 152 | .id = options.id, | 142 | .id = options.id, |
| 153 | .name = arena.dupe(u8, options.name) catch @panic("OOM"), | 143 | .name = arena.dupe(u8, options.name) catch @panic("OOM"), |
| ... | @@ -157,7 +147,17 @@ pub fn init(options: StepOptions) Step { | ... | @@ -157,7 +147,17 @@ pub fn init(options: StepOptions) Step { |
| 157 | .dependants = .{}, | 147 | .dependants = .{}, |
| 158 | .state = .precheck_unstarted, | 148 | .state = .precheck_unstarted, |
| 159 | .max_rss = options.max_rss, | 149 | .max_rss = options.max_rss, |
| 160 | .debug_stack_trace = addresses, | 150 | .debug_stack_trace = blk: { |
| | 151 | const addresses = arena.alloc(usize, options.owner.debug_stack_frames_count) catch @panic("OOM"); |
| | 152 | @memset(addresses, 0); |
| | 153 | const first_ret_addr = options.first_ret_addr orelse @returnAddress(); |
| | 154 | var stack_trace = std.builtin.StackTrace{ |
| | 155 | .instruction_addresses = addresses, |
| | 156 | .index = 0, |
| | 157 | }; |
| | 158 | std.debug.captureStackTrace(first_ret_addr, &stack_trace); |
| | 159 | break :blk addresses; |
| | 160 | }, |
| 161 | .result_error_msgs = .{}, | 161 | .result_error_msgs = .{}, |
| 162 | .result_error_bundle = std.zig.ErrorBundle.empty, | 162 | .result_error_bundle = std.zig.ErrorBundle.empty, |
| 163 | .result_cached = false, | 163 | .result_cached = false, |
| ... | @@ -199,14 +199,14 @@ pub fn dependOn(self: *Step, other: *Step) void { | ... | @@ -199,14 +199,14 @@ pub fn dependOn(self: *Step, other: *Step) void { |
| 199 | self.dependencies.append(other) catch @panic("OOM"); | 199 | self.dependencies.append(other) catch @panic("OOM"); |
| 200 | } | 200 | } |
| 201 | | 201 | |
| 202 | pub fn getStackTrace(s: *Step) std.builtin.StackTrace { | 202 | pub fn getStackTrace(s: *Step) ?std.builtin.StackTrace { |
| 203 | const stack_addresses = &s.debug_stack_trace; | | |
| 204 | var len: usize = 0; | 203 | var len: usize = 0; |
| 205 | while (len < n_debug_stack_frames and stack_addresses[len] != 0) { | 204 | while (len < s.debug_stack_trace.len and s.debug_stack_trace[len] != 0) { |
| 206 | len += 1; | 205 | len += 1; |
| 207 | } | 206 | } |
| 208 | return .{ | 207 | |
| 209 | .instruction_addresses = stack_addresses, | 208 | return if (len == 0) null else .{ |
| | 209 | .instruction_addresses = s.debug_stack_trace, |
| 210 | .index = len, | 210 | .index = len, |
| 211 | }; | 211 | }; |
| 212 | } | 212 | } |
| ... | @@ -231,13 +231,9 @@ pub fn cast(step: *Step, comptime T: type) ?*T { | ... | @@ -231,13 +231,9 @@ pub fn cast(step: *Step, comptime T: type) ?*T { |
| 231 | } | 231 | } |
| 232 | | 232 | |
| 233 | /// For debugging purposes, prints identifying information about this Step. | 233 | /// For debugging purposes, prints identifying information about this Step. |
| 234 | pub fn dump(step: *Step) void { | 234 | pub fn dump(step: *Step, file: std.fs.File) void { |
| 235 | std.debug.getStderrMutex().lock(); | 235 | const w = file.writer(); |
| 236 | defer std.debug.getStderrMutex().unlock(); | 236 | const tty_config = std.io.tty.detectConfig(file); |
| 237 | | | |
| 238 | const stderr = std.io.getStdErr(); | | |
| 239 | const w = stderr.writer(); | | |
| 240 | const tty_config = std.io.tty.detectConfig(stderr); | | |
| 241 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { | 237 | const debug_info = std.debug.getSelfDebugInfo() catch |err| { |
| 242 | w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{ | 238 | w.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{ |
| 243 | @errorName(err), | 239 | @errorName(err), |
| ... | @@ -245,11 +241,19 @@ pub fn dump(step: *Step) void { | ... | @@ -245,11 +241,19 @@ pub fn dump(step: *Step) void { |
| 245 | return; | 241 | return; |
| 246 | }; | 242 | }; |
| 247 | const ally = debug_info.allocator; | 243 | const ally = debug_info.allocator; |
| 248 | w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {}; | 244 | if (step.getStackTrace()) |stack_trace| { |
| 249 | std.debug.writeStackTrace(step.getStackTrace(), w, ally, debug_info, tty_config) catch |err| { | 245 | w.print("name: '{s}'. creation stack trace:\n", .{step.name}) catch {}; |
| 250 | stderr.writer().print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {}; | 246 | std.debug.writeStackTrace(stack_trace, w, ally, debug_info, tty_config) catch |err| { |
| 251 | return; | 247 | w.print("Unable to dump stack trace: {s}\n", .{@errorName(err)}) catch {}; |
| 252 | }; | 248 | return; |
| | 249 | }; |
| | 250 | } else { |
| | 251 | const field = "debug_stack_frames_count"; |
| | 252 | comptime assert(@hasField(Build, field)); |
| | 253 | tty_config.setColor(w, .yellow) catch {}; |
| | 254 | w.print("name: '{s}'. no stack trace collected for this step, see std.Build." ++ field ++ "\n", .{step.name}) catch {}; |
| | 255 | tty_config.setColor(w, .reset) catch {}; |
| | 256 | } |
| 253 | } | 257 | } |
| 254 | | 258 | |
| 255 | const Step = @This(); | 259 | const Step = @This(); |