aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorCezary Kupaj <zenshixd@proton.me>2025-05-14 05:38:38 +0200
committerGitHub <noreply@github.com>2025-05-14 05:38:38 +0200
commit518105471e145c90809fb2f5baa53cd08bde31aa (patch)
tree8085d5407f5eead69a2af35e872e2afdde00181e /lib/std/debug.zig
parent5b606d435d139487c23d6fd30e8061dbad741ada (diff)
downloadzig-518105471e145c90809fb2f5baa53cd08bde31aa.tar.gz
zig-518105471e145c90809fb2f5baa53cd08bde31aa.zip
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
Diffstat (limited to 'lib/std/debug.zig')
-rw-r--r--lib/std/debug.zig30
1 files changed, 27 insertions, 3 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index eb7cf793f2..81c627b633 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -441,7 +441,13 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
var it = StackIterator.initWithContext(null, debug_info, context) catch return;
defer it.deinit();
- printSourceAtAddress(debug_info, stderr, it.unwind_state.?.dwarf_context.pc, tty_config) catch return;
+
+ // DWARF unwinding on aarch64-macos is not complete so we need to get pc address from mcontext
+ const pc_addr = if (builtin.target.os.tag.isDarwin() and native_arch == .aarch64)
+ context.mcontext.ss.pc
+ else
+ it.unwind_state.?.dwarf_context.pc;
+ printSourceAtAddress(debug_info, stderr, pc_addr, tty_config) catch return;
while (it.next()) |return_address| {
printLastUnwindError(&it, debug_info, stderr, tty_config);
@@ -1483,8 +1489,26 @@ fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque)
.aarch64,
.aarch64_be,
=> {
- const ctx: *posix.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
- dumpStackTraceFromBase(ctx);
+ // Some kernels don't align `ctx_ptr` properly. Handle this defensively.
+ const ctx: *align(1) posix.ucontext_t = @ptrCast(ctx_ptr);
+ var new_ctx: posix.ucontext_t = ctx.*;
+ if (builtin.os.tag.isDarwin() and builtin.cpu.arch == .aarch64) {
+ // The kernel incorrectly writes the contents of `__mcontext_data` right after `mcontext`,
+ // rather than after the 8 bytes of padding that are supposed to sit between the two. Copy the
+ // contents to the right place so that the `mcontext` pointer will be correct after the
+ // `relocateContext` call below.
+ new_ctx.__mcontext_data = @as(*align(1) extern struct {
+ onstack: c_int,
+ sigmask: std.c.sigset_t,
+ stack: std.c.stack_t,
+ link: ?*std.c.ucontext_t,
+ mcsize: u64,
+ mcontext: *std.c.mcontext_t,
+ __mcontext_data: std.c.mcontext_t align(@sizeOf(usize)), // Disable padding after `mcontext`.
+ }, @ptrCast(ctx)).__mcontext_data;
+ }
+ relocateContext(&new_ctx);
+ dumpStackTraceFromBase(&new_ctx);
},
else => {},
}