Commit 6d87bb370a
lib/std/debug.zig
@@ -521,13 +521,19 @@ pub const StackIterator = struct {
}
pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const os.ucontext_t) !StackIterator {
- var iterator = init(first_address, null);
- iterator.unwind_state = .{
- .debug_info = debug_info,
- .dwarf_context = try DW.UnwindContext.init(debug_info.allocator, context, &isValidMemory),
- };
+ // The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that
+ // the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder.
+ if (comptime builtin.target.isDarwin() and native_arch == .aarch64) {
+ return init(first_address, context.mcontext.ss.fp);
+ } else {
+ var iterator = init(first_address, null);
+ iterator.unwind_state = .{
+ .debug_info = debug_info,
+ .dwarf_context = try DW.UnwindContext.init(debug_info.allocator, context, &isValidMemory),
+ };
- return iterator;
+ return iterator;
+ }
}
pub fn deinit(self: *StackIterator) void {
@@ -663,15 +669,15 @@ pub const StackIterator = struct {
if (!unwind_state.failed) {
if (unwind_state.dwarf_context.pc == 0) return null;
if (self.next_unwind()) |return_address| {
+ self.fp = unwind_state.dwarf_context.getFp() catch 0;
return return_address;
} else |err| {
unwind_state.last_error = err;
unwind_state.failed = true;
// Fall back to fp-based unwinding on the first failure.
- // We can't attempt it for other modules later in the
- // stack because the full register state won't be unwound.
- self.fp = unwind_state.dwarf_context.getFp() catch 0;
+ // We can't attempt it again for other modules higher in the
+ // stack because the full register state won't have been unwound.
}
}
}
lib/std/dwarf.zig
@@ -1782,7 +1782,7 @@ pub const DwarfInfo = struct {
};
var update_tail: ?*RegisterUpdate = null;
- var has_return_address= true;
+ var has_return_address = true;
for (context.vm.rowColumns(row)) |column| {
if (column.register) |register| {
if (register == cie.return_address_register) {
@@ -1871,7 +1871,7 @@ pub const UnwindContext = struct {
}
pub fn getFp(self: *const UnwindContext) !usize {
- return mem.readIntSliceNative(usize, try abi.regBytes(self.thread_context, abi.fpRegNum(self.reg_context), self.reg_context));
+ return (try abi.regValueNative(usize, self.thread_context, abi.fpRegNum(self.reg_context), self.reg_context)).*;
}
};