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