diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-14 09:49:20 +0200 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-15 13:59:17 +0200 |
| commit | 6de2d61a0cbcf535b455770b4d7397d580eac6c6 (patch) | |
| tree | 9cf4662763243ff35372c4c164d6fcb51f2a5a4f /lib/std | |
| parent | 78bc5d46e07f238f7ec90b1ef99001278ccc2174 (diff) | |
| download | zig-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.zig | 16 |
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); } |
