authorgravatar for zenshixd@proton.meCezary Kupaj <zenshixd@proton.me> 2025-05-14 05:38:38+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-05-14 05:39:01+02:00
logc4237e890945468c4efc4fdb0f5f3f17fac25046
treef2eda190af54296b88c554f5aa455d8ac921099f
parent0cb9ffc6d87cafdb676d59e5d06192cc438058a3
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

Fix SIGSEGV handler for AArch64 Darwin targets

* ucontext_t ptr is 8-byte aligned instead of 16-byte aligned which @alignCast() expects * Retrieve pc address from ucontext_t since unwind_state is null * Work around __mcontext_data being written incorrectly by the kernel

1 files changed, 27 insertions(+), 3 deletions(-)

lib/std/debug.zig+27-3
...@@ -437,7 +437,13 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void {...@@ -437,7 +437,13 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
437437
438 var it = StackIterator.initWithContext(null, debug_info, context) catch return;438 var it = StackIterator.initWithContext(null, debug_info, context) catch return;
439 defer it.deinit();439 defer it.deinit();
440 printSourceAtAddress(debug_info, stderr, it.unwind_state.?.dwarf_context.pc, tty_config) catch return;440
441 // DWARF unwinding on aarch64-macos is not complete so we need to get pc address from mcontext
442 const pc_addr = if (builtin.target.os.tag.isDarwin() and native_arch == .aarch64)
443 context.mcontext.ss.pc
444 else
445 it.unwind_state.?.dwarf_context.pc;
446 printSourceAtAddress(debug_info, stderr, pc_addr, tty_config) catch return;
441447
442 while (it.next()) |return_address| {448 while (it.next()) |return_address| {
443 printLastUnwindError(&it, debug_info, stderr, tty_config);449 printLastUnwindError(&it, debug_info, stderr, tty_config);
...@@ -1480,8 +1486,26 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque)...@@ -1480,8 +1486,26 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque)
1480 .aarch64,1486 .aarch64,
1481 .aarch64_be,1487 .aarch64_be,
1482 => {1488 => {
1483 const ctx: *posix.ucontext_t = @ptrCast(@alignCast(ctx_ptr));1489 // Some kernels don't align `ctx_ptr` properly. Handle this defensively.
1484 dumpStackTraceFromBase(ctx);1490 const ctx: *align(1) posix.ucontext_t = @ptrCast(ctx_ptr);
1491 var new_ctx: posix.ucontext_t = ctx.*;
1492 if (builtin.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) {
1493 // The kernel incorrectly writes the contents of `__mcontext_data` right after `mcontext`,
1494 // rather than after the 8 bytes of padding that are supposed to sit between the two. Copy the
1495 // contents to the right place so that the `mcontext` pointer will be correct after the
1496 // `relocateContext` call below.
1497 new_ctx.__mcontext_data = @as(*align(1) extern struct {
1498 onstack: c_int,
1499 sigmask: std.c.sigset_t,
1500 stack: std.c.stack_t,
1501 link: ?*std.c.ucontext_t,
1502 mcsize: u64,
1503 mcontext: *std.c.mcontext_t,
1504 __mcontext_data: std.c.mcontext_t align(@sizeOf(usize)), // Disable padding after `mcontext`.
1505 }, @ptrCast(ctx)).__mcontext_data;
1506 }
1507 relocateContext(&new_ctx);
1508 dumpStackTraceFromBase(&new_ctx);
1485 },1509 },
1486 else => {},1510 else => {},
1487 }1511 }