authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-14 09:49:20+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-15 13:59:17+02:00
log6de2d61a0cbcf535b455770b4d7397d580eac6c6
tree9cf4662763243ff35372c4c164d6fcb51f2a5a4f
parent78bc5d46e07f238f7ec90b1ef99001278ccc2174
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

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.

1 files changed, 16 insertions(+), 0 deletions(-)

lib/std/debug.zig+16
...@@ -1438,6 +1438,22 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa...@@ -1438,6 +1438,22 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
1438 break :info .{ addr, name };1438 break :info .{ addr, name };
1439 };1439 };
1440 const opt_cpu_context: ?cpu_context.Native = cpu_context.fromPosixSignalContext(ctx_ptr);1440 const opt_cpu_context: ?cpu_context.Native = cpu_context.fromPosixSignalContext(ctx_ptr);
1441
1442 if (native_arch.isSPARC()) {
1443 // It's unclear to me whether this is a QEMU bug or also real kernel behavior, but in the
1444 // former, I observed that the most recent register window wasn't getting spilled on the
1445 // stack as expected when a signal arrived. A `flushw` from the signal handler does not
1446 // appear to be sufficient either. On the other hand, when doing a synchronous stack trace
1447 // and using `flushw`, this all appears to work as expected. So, *probably* a QEMU bug, but
1448 // someone with real SPARC hardware should verify.
1449 //
1450 // In any case, the register save area exists specifically so that register windows can be
1451 // spilled asynchronously. This means that it should be perfectly fine for us to manually do
1452 // so here.
1453 const ctx = opt_cpu_context.?;
1454 @as(*[16]usize, @ptrFromInt(ctx.o[6] + StackIterator.stack_bias)).* = ctx.l ++ ctx.i;
1455 }
1456
1441 handleSegfault(addr, name, if (opt_cpu_context) |*ctx| ctx else null);1457 handleSegfault(addr, name, if (opt_cpu_context) |*ctx| ctx else null);
1442}1458}
14431459