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