From 51d08f4b9b051d66534b77462a3bfb9bace9f1fb Mon Sep 17 00:00:00 2001 From: mlugg Date: Sat, 13 Sep 2025 10:29:20 +0100 Subject: [PATCH] fix compile errors and minor bugs --- lib/compiler/test_runner.zig | 8 ++++---- lib/std/debug.zig | 26 ++++++++++++++++---------- lib/std/debug/SelfInfo.zig | 6 +++--- lib/std/start.zig | 6 ++++-- lib/std/testing/FailingAllocator.zig | 2 +- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 5e7bbd294c..42c708cbfc 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -140,7 +140,7 @@ fn mainServer() !void { else => { fail = true; if (@errorReturnTrace()) |trace| { - std.debug.dumpStackTrace(trace.*); + std.debug.dumpStackTrace(trace); } }, }; @@ -182,7 +182,7 @@ fn mainServer() !void { error.SkipZigTest => return, else => { if (@errorReturnTrace()) |trace| { - std.debug.dumpStackTrace(trace.*); + std.debug.dumpStackTrace(trace); } std.debug.print("failed with error.{t}\n", .{err}); std.process.exit(1); @@ -261,7 +261,7 @@ fn mainTerminal() void { std.debug.print("FAIL ({t})\n", .{err}); } if (@errorReturnTrace()) |trace| { - std.debug.dumpStackTrace(trace.*); + std.debug.dumpStackTrace(trace); } test_node.end(); }, @@ -398,7 +398,7 @@ pub fn fuzz( error.SkipZigTest => return, else => { std.debug.lockStdErr(); - if (@errorReturnTrace()) |trace| std.debug.dumpStackTrace(trace.*); + if (@errorReturnTrace()) |trace| std.debug.dumpStackTrace(trace); std.debug.print("failed with error.{t}\n", .{err}); std.process.exit(1); }, diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 1fdf4f2495..a94b619016 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -754,6 +754,10 @@ pub fn dumpCurrentStackTrace(options: StackUnwindOptions) void { /// 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 { + // 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. + const n_frames = st.index; + if (n_frames == 0) return writer.writeAll("(empty stack trace)\n"); const di_gpa = getDebugInfoAllocator(); const di = getSelfDebugInfo() catch |err| switch (err) { error.UnsupportedTarget => { @@ -763,14 +767,13 @@ pub fn writeStackTrace(st: *const std.builtin.StackTrace, writer: *Writer, tty_c return; }, }; - if (st.index == 0) return writer.writeAll("(empty stack trace)\n"); - const captured_frames = @min(st.index, st.instruction_addresses.len); + const captured_frames = @min(n_frames, st.instruction_addresses.len); for (st.instruction_addresses[0..captured_frames]) |return_address| { try printSourceAtAddress(di_gpa, di, writer, return_address -| 1, tty_config); } - if (st.index > captured_frames) { + if (n_frames > captured_frames) { tty_config.setColor(writer, .bold) catch {}; - try writer.print("({d} additional stack frames skipped...)\n", .{st.index - captured_frames}); + try writer.print("({d} additional stack frames skipped...)\n", .{n_frames - captured_frames}); tty_config.setColor(writer, .reset) catch {}; } } @@ -853,7 +856,7 @@ const StackIterator = union(enum) { const di = getSelfDebugInfo() catch unreachable; const di_gpa = getDebugInfoAllocator(); if (di.unwindFrame(di_gpa, unwind_context)) |ra| { - if (ra == 0) return .end; + if (ra <= 1) return .end; return .{ .frame = ra }; } else |err| { const pc = unwind_context.pc; @@ -888,7 +891,9 @@ const StackIterator = union(enum) { if (bp != 0 and bp <= fp) return .end; it.fp = bp; - return .{ .frame = ra_ptr.* }; + const ra = ra_ptr.*; + if (ra <= 1) return .end; + return .{ .frame = ra }; }, } } @@ -1409,11 +1414,12 @@ test "manage resources correctly" { return @returnAddress(); } }; - var discarding: std.io.Writer.Discarding = .init(&.{}); - var di: SelfInfo = try .open(testing.allocator); - defer di.deinit(); + const gpa = std.testing.allocator; + var discarding: std.Io.Writer.Discarding = .init(&.{}); + var di: SelfInfo = .init; + defer di.deinit(gpa); try printSourceAtAddress( - testing.allocator, + gpa, &di, &discarding.writer, S.showMyTrace(), diff --git a/lib/std/debug/SelfInfo.zig b/lib/std/debug/SelfInfo.zig index 38027dbb58..c3243edeb9 100644 --- a/lib/std/debug/SelfInfo.zig +++ b/lib/std/debug/SelfInfo.zig @@ -18,8 +18,8 @@ const root = @import("root"); const SelfInfo = @This(); -modules: std.AutoArrayHashMapUnmanaged(usize, Module.DebugInfo), -lookup_cache: Module.LookupCache, +modules: if (target_supported) std.AutoArrayHashMapUnmanaged(usize, Module.DebugInfo) else void, +lookup_cache: if (target_supported) Module.LookupCache else void, pub const Error = error{ /// The required debug info is invalid or corrupted. @@ -40,7 +40,7 @@ pub const target_supported: bool = Module != void; /// Indicates whether the `SelfInfo` implementation has support for unwinding on this target. /// /// For whether DWARF unwinding is *theoretically* possible, see `Dwarf.abi.supportsUnwinding`. -pub const supports_unwinding: bool = Module.supports_unwinding; +pub const supports_unwinding: bool = target_supported and Module.supports_unwinding; pub const UnwindContext = if (supports_unwinding) Module.UnwindContext; diff --git a/lib/std/start.zig b/lib/std/start.zig index 0ea5c44c2b..13ce744a2a 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -635,8 +635,10 @@ pub inline fn callMain() u8 { else => {}, } std.log.err("{s}", .{@errorName(err)}); - if (@errorReturnTrace()) |trace| { - std.debug.dumpStackTrace(trace); + if (native_os != .freestanding) { + if (@errorReturnTrace()) |trace| { + std.debug.dumpStackTrace(trace); + } } return 1; }; diff --git a/lib/std/testing/FailingAllocator.zig b/lib/std/testing/FailingAllocator.zig index 916dbc6655..6476725a2f 100644 --- a/lib/std/testing/FailingAllocator.zig +++ b/lib/std/testing/FailingAllocator.zig @@ -64,7 +64,7 @@ fn alloc( const self: *FailingAllocator = @ptrCast(@alignCast(ctx)); if (self.alloc_index == self.fail_index) { if (!self.has_induced_failure) { - const st = std.debug.captureCurrentStackTrace(return_address, &self.stack_addresses); + const st = std.debug.captureCurrentStackTrace(.{ .first_address = return_address }, &self.stack_addresses); @memset(self.stack_addresses[@min(st.index, self.stack_addresses.len)..], 0); self.has_induced_failure = true; }