Commit 54db36cd88

LemonBoy <thatlemon@gmail.com>
2021-04-25 19:10:11
std: Fix backtraces on sparcv9
Flush all the register windows to stack before starting the stack walk, we may otherwise try to read garbage and crash and burn. Add a few comptime annotations to debloat some functions.
1 parent 37b0574
Changed files (1)
lib
lib/std/debug.zig
@@ -336,6 +336,13 @@ pub const StackIterator = struct {
     fp: usize,
 
     pub fn init(first_address: ?usize, fp: ?usize) StackIterator {
+        if (builtin.arch == .sparcv9) {
+            // Flush all the register windows on stack.
+            asm volatile (
+                \\ flushw
+                ::: "memory");
+        }
+
         return StackIterator{
             .first_address = first_address,
             .fp = fp orelse @frameAddress(),
@@ -343,18 +350,18 @@ pub const StackIterator = struct {
     }
 
     // Offset of the saved BP wrt the frame pointer.
-    const fp_offset = if (builtin.arch.isRISCV())
+    const fp_offset = if (comptime builtin.arch.isRISCV())
         // On RISC-V the frame pointer points to the top of the saved register
         // area, on pretty much every other architecture it points to the stack
         // slot where the previous frame pointer is saved.
         2 * @sizeOf(usize)
-    else if (builtin.arch.isSPARC())
+    else if (comptime builtin.arch.isSPARC())
         // On SPARC the previous frame pointer is stored at 14 slots past %fp+BIAS.
         14 * @sizeOf(usize)
     else
         0;
 
-    const fp_bias = if (builtin.arch.isSPARC())
+    const fp_bias = if (comptime builtin.arch.isSPARC())
         // On SPARC frame pointers are biased by a constant.
         2047
     else
@@ -380,7 +387,7 @@ pub const StackIterator = struct {
     }
 
     fn next_internal(self: *StackIterator) ?usize {
-        const fp = if (builtin.arch.isSPARC())
+        const fp = if (comptime builtin.arch.isSPARC())
             // On SPARC the offset is positive. (!)
             math.add(usize, self.fp, fp_offset) catch return null
         else