aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2025-10-14 09:49:20 +0200
committerAlex Rønne Petersen <alex@alexrp.com>2025-10-15 13:59:17 +0200
commit6de2d61a0cbcf535b455770b4d7397d580eac6c6 (patch)
tree9cf4662763243ff35372c4c164d6fcb51f2a5a4f /lib/std
parent78bc5d46e07f238f7ec90b1ef99001278ccc2174 (diff)
downloadzig-6de2d61a0cbcf535b455770b4d7397d580eac6c6.tar.gz
zig-6de2d61a0cbcf535b455770b4d7397d580eac6c6.zip
std.debug: work around latest SPARC register window not being spilled on signal
I have no idea if this is a QEMU bug or real kernel behavior. Either way, the register save area specifically exists for asynchronous spilling of incoming and local registers, so there should be no harm in doing this.
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/debug.zig16
1 files changed, 16 insertions, 0 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index 942c21212c..5c6043c8c3 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -1438,6 +1438,22 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
break :info .{ addr, name };
};
const opt_cpu_context: ?cpu_context.Native = cpu_context.fromPosixSignalContext(ctx_ptr);
+
+ if (native_arch.isSPARC()) {
+ // It's unclear to me whether this is a QEMU bug or also real kernel behavior, but in the
+ // former, I observed that the most recent register window wasn't getting spilled on the
+ // stack as expected when a signal arrived. A `flushw` from the signal handler does not
+ // appear to be sufficient either. On the other hand, when doing a synchronous stack trace
+ // and using `flushw`, this all appears to work as expected. So, *probably* a QEMU bug, but
+ // someone with real SPARC hardware should verify.
+ //
+ // In any case, the register save area exists specifically so that register windows can be
+ // spilled asynchronously. This means that it should be perfectly fine for us to manually do
+ // so here.
+ const ctx = opt_cpu_context.?;
+ @as(*[16]usize, @ptrFromInt(ctx.o[6] + StackIterator.stack_bias)).* = ctx.l ++ ctx.i;
+ }
+
handleSegfault(addr, name, if (opt_cpu_context) |*ctx| ctx else null);
}