| ... | @@ -521,13 +521,19 @@ pub const StackIterator = struct { | ... | @@ -521,13 +521,19 @@ pub const StackIterator = struct { |
| 521 | } | 521 | } |
| 522 | | 522 | |
| 523 | pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const os.ucontext_t) !StackIterator { | 523 | pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const os.ucontext_t) !StackIterator { |
| 524 | var iterator = init(first_address, null); | 524 | // The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that |
| 525 | iterator.unwind_state = .{ | 525 | // the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder. |
| 526 | .debug_info = debug_info, | 526 | if (comptime builtin.target.isDarwin() and native_arch == .aarch64) { |
| 527 | .dwarf_context = try DW.UnwindContext.init(debug_info.allocator, context, &isValidMemory), | 527 | return init(first_address, context.mcontext.ss.fp); |
| 528 | }; | 528 | } else { |
| | 529 | var iterator = init(first_address, null); |
| | 530 | iterator.unwind_state = .{ |
| | 531 | .debug_info = debug_info, |
| | 532 | .dwarf_context = try DW.UnwindContext.init(debug_info.allocator, context, &isValidMemory), |
| | 533 | }; |
| 529 | | 534 | |
| 530 | return iterator; | 535 | return iterator; |
| | 536 | } |
| 531 | } | 537 | } |
| 532 | | 538 | |
| 533 | pub fn deinit(self: *StackIterator) void { | 539 | pub fn deinit(self: *StackIterator) void { |
| ... | @@ -663,15 +669,15 @@ pub const StackIterator = struct { | ... | @@ -663,15 +669,15 @@ pub const StackIterator = struct { |
| 663 | if (!unwind_state.failed) { | 669 | if (!unwind_state.failed) { |
| 664 | if (unwind_state.dwarf_context.pc == 0) return null; | 670 | if (unwind_state.dwarf_context.pc == 0) return null; |
| 665 | if (self.next_unwind()) |return_address| { | 671 | if (self.next_unwind()) |return_address| { |
| | 672 | self.fp = unwind_state.dwarf_context.getFp() catch 0; |
| 666 | return return_address; | 673 | return return_address; |
| 667 | } else |err| { | 674 | } else |err| { |
| 668 | unwind_state.last_error = err; | 675 | unwind_state.last_error = err; |
| 669 | unwind_state.failed = true; | 676 | unwind_state.failed = true; |
| 670 | | 677 | |
| 671 | // Fall back to fp-based unwinding on the first failure. | 678 | // Fall back to fp-based unwinding on the first failure. |
| 672 | // We can't attempt it for other modules later in the | 679 | // We can't attempt it again for other modules higher in the |
| 673 | // stack because the full register state won't be unwound. | 680 | // stack because the full register state won't have been unwound. |
| 674 | self.fp = unwind_state.dwarf_context.getFp() catch 0; | | |
| 675 | } | 681 | } |
| 676 | } | 682 | } |
| 677 | } | 683 | } |