commit 5a4b5c8b94236429263ef25d9287b6c5cc829bde (tree)
parent 825ba5a350cab21fff5531d645d18cd9d2facd8f
Author: Mason Remaley <mason@gamesbymason.com>
Date: Fri, 10 Apr 2026 13:53:41 -0700
Uses dwarf iterator if dwarf symbols found for windows executable
Diffstat:
4 files changed, 41 insertions(+), 71 deletions(-)
diff --git a/lib/std/debug/Dwarf.zig b/lib/std/debug/Dwarf.zig
@@ -22,7 +22,9 @@ const cast = std.math.cast;
const maxInt = std.math.maxInt;
const ArrayList = std.ArrayList;
const Endian = std.builtin.Endian;
-const Reader = std.Io.Reader;
+const Io = std.Io;
+const Reader = Io.Reader;
+const Error = std.debug.SelfInfoError;
const Dwarf = @This();
@@ -1543,21 +1545,40 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 {
return str[casted_offset..last :0];
}
-pub fn getSymbol(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) !std.debug.Symbol {
+pub const SymbolIterator = struct {
+ curr: ?std.debug.SelfInfoError!std.debug.Symbol,
+
+ pub fn deinit(self: *SymbolIterator, _: Io) void {
+ self.* = undefined;
+ }
+
+ pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
+ const result = self.curr;
+ self.curr = null;
+ return result;
+ }
+};
+
+pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) SymbolIterator {
const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) {
- error.MissingDebugInfo, error.InvalidDebugInfo => return .unknown,
- else => return err,
+ error.EndOfStream, error.Overflow => return .{ .curr = error.InvalidDebugInfo },
+ else => |e| return .{ .curr = e },
};
- return .{
+ return .{ .curr = .{
.name = di.getSymbolName(address),
.compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => null,
},
.source_location = di.getLineNumberInfo(gpa, endian, compile_unit, address) catch |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => null,
- else => return err,
+ error.ReadFailed,
+ error.EndOfStream,
+ error.Overflow,
+ error.StreamTooLong,
+ => return .{ .curr = error.InvalidDebugInfo },
+ else => |e| return .{ .curr = e },
},
- };
+ } };
}
/// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and
diff --git a/lib/std/debug/Pdb.zig b/lib/std/debug/Pdb.zig
@@ -358,7 +358,7 @@ pub const BinaryAnnotation = union(enum) {
self.curr.file_id = file_id;
},
// LLVM never emits this opcode, but it's clear enough how to interpret it so we
- // may as well in case they use it in the future
+ // may as well handle it in case they emit it in the future
.change_code_length_and_code_offset => |info| {
self.curr.code_length = info.length;
self.curr.code_offset += info.delta;
diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig
@@ -30,19 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void {
if (si.unwind_cache) |cache| gpa.free(cache);
}
-pub const SymbolIterator = struct {
- curr: ?Error!std.debug.Symbol,
-
- pub fn deinit(self: *SymbolIterator, _: Io) void {
- self.* = undefined;
- }
-
- pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
- const result = self.curr;
- self.curr = null;
- return result;
- }
-};
+pub const SymbolIterator = std.debug.Dwarf.SymbolIterator;
pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
const gpa = std.debug.getDebugInfoAllocator();
@@ -67,21 +55,7 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
};
loaded_elf.scanned_dwarf = true;
}
- if (dwarf.getSymbol(gpa, native_endian, vaddr)) |sym| {
- return .{ .curr = sym };
- } else |err| switch (err) {
- error.MissingDebugInfo => {},
-
- error.InvalidDebugInfo,
- error.OutOfMemory,
- => |e| return .{ .curr = e },
-
- error.ReadFailed,
- error.EndOfStream,
- error.Overflow,
- error.StreamTooLong,
- => return .{ .curr = error.InvalidDebugInfo },
- }
+ return dwarf.getSymbols(gpa, native_endian, vaddr);
}
// When DWARF is unavailable, fall back to searching the symtab.
const symbol = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) {
diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig
@@ -33,7 +33,7 @@ pub const SymbolIterator = struct {
pub fn deinit(self: *SymbolIterator, io: Io) void {
if (self.lock) |lock| lock.unlockShared(io);
- self.symbols.deinit();
+ self.symbols.deinit(io);
self.* = undefined;
}
@@ -105,29 +105,7 @@ pub const SymbolIterator = struct {
.source_location = pdb.getLineNumberInfo(info.module, info.addr) catch null,
};
},
- .dwarf => |info| {
- // The failure cases are unreachable because we only set the dwarf field if these
- // are set
- const di = if (self.module.di.?) |*di| di else |_| unreachable;
- const dwarf = if (di.dwarf) |*dwarf| dwarf else unreachable;
-
- // Return the main symbol and then return the iterator
- defer self.symbols = .none;
- const gpa = std.debug.getDebugInfoAllocator();
- return dwarf.getSymbol(gpa, native_endian, info.addr) catch |err| switch (err) {
- error.MissingDebugInfo => return null,
-
- error.InvalidDebugInfo,
- error.OutOfMemory,
- => |e| return e,
-
- error.ReadFailed,
- error.EndOfStream,
- error.Overflow,
- error.StreamTooLong,
- => return error.InvalidDebugInfo,
- };
- },
+ .dwarf => |*info| return info.next(),
.none => return null,
}
}
@@ -368,7 +346,7 @@ const Module = struct {
/// iteration, e.g. because they only wanted the topmost call.
inline_sites: std.ArrayList(*align(1) const std.pdb.InlineSiteSym),
},
- dwarf: struct { addr: u64 },
+ dwarf: std.debug.Dwarf.SymbolIterator,
none: void,
fn init(di: *DebugInfo, vaddr: usize) Error!Symbols {
@@ -425,23 +403,20 @@ const Module = struct {
// Dwarf
dwarf: {
- if (di.dwarf == null) break :dwarf;
+ const dwarf = &(di.dwarf orelse break :dwarf);
const addr = vaddr + di.coff_image_base;
- return .{ .dwarf = .{
- .addr = addr,
- } };
+ return .{ .dwarf = dwarf.getSymbols(gpa, native_endian, addr) };
}
return error.MissingDebugInfo;
}
- fn deinit(self: *Symbols) void {
+ fn deinit(self: *Symbols, io: Io) void {
+ const gpa = std.debug.getDebugInfoAllocator();
switch (self.*) {
- .pdb => |*info| {
- const gpa = std.debug.getDebugInfoAllocator();
- info.inline_sites.deinit(gpa);
- },
- .dwarf, .none => {},
+ .pdb => |*info| info.inline_sites.deinit(gpa),
+ .dwarf => |*info| info.deinit(io),
+ .none => {},
}
}
};