Commit e5aa2bb224

kcbanner <kcbanner@gmail.com>
2023-07-11 02:18:58
debug: fixup last_error being printed too many times
1 parent 891fa3b
Changed files (2)
lib/std/dwarf/expressions.zig
@@ -1023,7 +1023,6 @@ pub fn Builder(comptime options: ExpressionOptions) type {
             try leb.writeULEB128(writer, value_bytes.len);
             try writer.writeAll(value_bytes);
         }
-
     };
 }
 
lib/std/debug.zig
@@ -493,6 +493,7 @@ pub const StackIterator = struct {
         debug_info: *DebugInfo,
         dwarf_context: DW.UnwindContext,
         last_error: ?UnwindError = null,
+        failed: bool = false,
     } else void = if (have_ucontext) null else {},
 
     pub fn init(first_address: ?usize, fp: ?usize) StackIterator {
@@ -530,6 +531,7 @@ pub const StackIterator = struct {
         if (!have_ucontext) return null;
         if (self.unwind_state) |*unwind_state| {
             if (unwind_state.last_error) |err| {
+                unwind_state.last_error = null;
                 return .{
                     .err = err,
                     .address = unwind_state.dwarf_context.pc,
@@ -648,15 +650,20 @@ pub const StackIterator = struct {
     fn next_internal(self: *StackIterator) ?usize {
         if (have_ucontext) {
             if (self.unwind_state) |*unwind_state| {
-                if (unwind_state.dwarf_context.pc == 0) return null;
-                if (unwind_state.last_error == null) {
-                    if (self.next_unwind()) |return_address| {
-                        return return_address;
-                    } else |err| {
-                        unwind_state.last_error = err;
-
-                        // Fall back to fp-based unwinding on the first failure
-                        self.fp = unwind_state.dwarf_context.getFp() catch 0;
+                if (!unwind_state.failed) {
+                    if (unwind_state.dwarf_context.pc == 0) return null;
+                    if (unwind_state.last_error == null) {
+                        if (self.next_unwind()) |return_address| {
+                            return return_address;
+                        } else |err| {
+                            unwind_state.last_error = err;
+                            unwind_state.failed = true;
+
+                            // Fall back to fp-based unwinding on the first failure.
+                            // We can't attempt it for other modules later in the
+                            // stack because the full register state won't be unwound.
+                            self.fp = unwind_state.dwarf_context.getFp() catch 0;
+                        }
                     }
                 }
             }