| ... | @@ -974,11 +974,15 @@ const StackIterator = union(enum) { | ... | @@ -974,11 +974,15 @@ const StackIterator = union(enum) { |
| 974 | const ra_ptr: *const usize = @ptrFromInt(ra_addr); | 974 | const ra_ptr: *const usize = @ptrFromInt(ra_addr); |
| 975 | const bp = applyOffset(bp_ptr.*, stack_bias) orelse return .end; | 975 | const bp = applyOffset(bp_ptr.*, stack_bias) orelse return .end; |
| 976 | | 976 | |
| 977 | // The stack grows downards, so `bp > fp` should always hold. If it doesn't, this | 977 | // If the stack grows downwards, `bp > fp` should always hold; conversely, if it |
| 978 | // frame is invalid, so we'll treat it as though it we reached end of stack. The | 978 | // grows upwards, `bp < fp` should always hold. If that is not the case, this |
| | 979 | // frame is invalid, so we'll treat it as though we reached end of stack. The |
| 979 | // exception is address 0, which is a graceful end-of-stack signal, in which case | 980 | // exception is address 0, which is a graceful end-of-stack signal, in which case |
| 980 | // *this* return address is valid and the *next* iteration will be the last. | 981 | // *this* return address is valid and the *next* iteration will be the last. |
| 981 | if (bp != 0 and bp <= fp) return .end; | 982 | if (bp != 0 and switch (comptime builtin.target.stackGrowth()) { |
| | 983 | .down => bp <= fp, |
| | 984 | .up => bp >= fp, |
| | 985 | }) return .end; |
| 982 | | 986 | |
| 983 | it.fp = bp; | 987 | it.fp = bp; |
| 984 | const ra = stripInstructionPtrAuthCode(ra_ptr.*); | 988 | const ra = stripInstructionPtrAuthCode(ra_ptr.*); |