| ... | @@ -825,8 +825,19 @@ const StackIterator = union(enum) { | ... | @@ -825,8 +825,19 @@ const StackIterator = union(enum) { |
| 825 | // in our caller's frame and above. | 825 | // in our caller's frame and above. |
| 826 | return .{ .di = .init(&.current()) }; | 826 | return .{ .di = .init(&.current()) }; |
| 827 | } | 827 | } |
| 828 | flushSparcWindows(); | 828 | return .{ |
| 829 | return .{ .fp = @frameAddress() }; | 829 | // On SPARC, the frame pointer will point to the previous frame's save area, |
| | 830 | // meaning we will read the previous return address and thus miss a frame. |
| | 831 | // Instead, start at the stack pointer so we get the return address from the |
| | 832 | // current frame's save area. The addition of the stack bias cannot fail here |
| | 833 | // since we know we have a valid stack pointer. |
| | 834 | .fp = if (native_arch.isSPARC()) sp: { |
| | 835 | flushSparcWindows(); |
| | 836 | break :sp asm ("" |
| | 837 | : [_] "={o6}" (-> usize), |
| | 838 | ) + stack_bias; |
| | 839 | } else @frameAddress(), |
| | 840 | }; |
| 830 | } | 841 | } |
| 831 | fn deinit(si: *StackIterator) void { | 842 | fn deinit(si: *StackIterator) void { |
| 832 | switch (si.*) { | 843 | switch (si.*) { |