authorgravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-04-10 13:53:41-07:00
committergravatar for mason@gamesbymason.comMason Remaley <mason@gamesbymason.com> 2026-04-12 04:01:30-07:00
log5a4b5c8b94236429263ef25d9287b6c5cc829bde
tree52bc7eedf23bb607811581b04d1d5edfc3e27f66
parent825ba5a350cab21fff5531d645d18cd9d2facd8f

Uses dwarf iterator if dwarf symbols found for windows executable


4 files changed, 41 insertions(+), 71 deletions(-)

lib/std/debug/Dwarf.zig+28-7
......@@ -22,7 +22,9 @@ const cast = std.math.cast;
2222const maxInt = std.math.maxInt;
2323const ArrayList = std.ArrayList;
2424const Endian = std.builtin.Endian;
25const Reader = std.Io.Reader;
25const Io = std.Io;
26const Reader = Io.Reader;
27const Error = std.debug.SelfInfoError;
2628
2729const Dwarf = @This();
2830
......@@ -1543,21 +1545,40 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 {
15431545 return str[casted_offset..last :0];
15441546}
15451547
1546pub fn getSymbol(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) !std.debug.Symbol {
1548pub const SymbolIterator = struct {
1549 curr: ?std.debug.SelfInfoError!std.debug.Symbol,
1550
1551 pub fn deinit(self: *SymbolIterator, _: Io) void {
1552 self.* = undefined;
1553 }
1554
1555 pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
1556 const result = self.curr;
1557 self.curr = null;
1558 return result;
1559 }
1560};
1561
1562pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) SymbolIterator {
15471563 const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) {
1548 error.MissingDebugInfo, error.InvalidDebugInfo => return .unknown,
1549 else => return err,
1564 error.EndOfStream, error.Overflow => return .{ .curr = error.InvalidDebugInfo },
1565 else => |e| return .{ .curr = e },
15501566 };
1551 return .{
1567 return .{ .curr = .{
15521568 .name = di.getSymbolName(address),
15531569 .compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) {
15541570 error.MissingDebugInfo, error.InvalidDebugInfo => null,
15551571 },
15561572 .source_location = di.getLineNumberInfo(gpa, endian, compile_unit, address) catch |err| switch (err) {
15571573 error.MissingDebugInfo, error.InvalidDebugInfo => null,
1558 else => return err,
1574 error.ReadFailed,
1575 error.EndOfStream,
1576 error.Overflow,
1577 error.StreamTooLong,
1578 => return .{ .curr = error.InvalidDebugInfo },
1579 else => |e| return .{ .curr = e },
15591580 },
1560 };
1581 } };
15611582}
15621583
15631584/// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and
lib/std/debug/Pdb.zig+1-1
......@@ -358,7 +358,7 @@ pub const BinaryAnnotation = union(enum) {
358358 self.curr.file_id = file_id;
359359 },
360360 // LLVM never emits this opcode, but it's clear enough how to interpret it so we
361 // may as well in case they use it in the future
361 // may as well handle it in case they emit it in the future
362362 .change_code_length_and_code_offset => |info| {
363363 self.curr.code_length = info.length;
364364 self.curr.code_offset += info.delta;
lib/std/debug/SelfInfo/Elf.zig+2-28
......@@ -30,19 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void {
3030 if (si.unwind_cache) |cache| gpa.free(cache);
3131}
3232
33pub const SymbolIterator = struct {
34 curr: ?Error!std.debug.Symbol,
35
36 pub fn deinit(self: *SymbolIterator, _: Io) void {
37 self.* = undefined;
38 }
39
40 pub fn next(self: *SymbolIterator) ?Error!std.debug.Symbol {
41 const result = self.curr;
42 self.curr = null;
43 return result;
44 }
45};
33pub const SymbolIterator = std.debug.Dwarf.SymbolIterator;
4634
4735pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
4836 const gpa = std.debug.getDebugInfoAllocator();
......@@ -67,21 +55,7 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SymbolIterator {
6755 };
6856 loaded_elf.scanned_dwarf = true;
6957 }
70 if (dwarf.getSymbol(gpa, native_endian, vaddr)) |sym| {
71 return .{ .curr = sym };
72 } else |err| switch (err) {
73 error.MissingDebugInfo => {},
74
75 error.InvalidDebugInfo,
76 error.OutOfMemory,
77 => |e| return .{ .curr = e },
78
79 error.ReadFailed,
80 error.EndOfStream,
81 error.Overflow,
82 error.StreamTooLong,
83 => return .{ .curr = error.InvalidDebugInfo },
84 }
58 return dwarf.getSymbols(gpa, native_endian, vaddr);
8559 }
8660 // When DWARF is unavailable, fall back to searching the symtab.
8761 const symbol = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) {
lib/std/debug/SelfInfo/Windows.zig+10-35
......@@ -33,7 +33,7 @@ pub const SymbolIterator = struct {
3333
3434 pub fn deinit(self: *SymbolIterator, io: Io) void {
3535 if (self.lock) |lock| lock.unlockShared(io);
36 self.symbols.deinit();
36 self.symbols.deinit(io);
3737 self.* = undefined;
3838 }
3939
......@@ -105,29 +105,7 @@ pub const SymbolIterator = struct {
105105 .source_location = pdb.getLineNumberInfo(info.module, info.addr) catch null,
106106 };
107107 },
108 .dwarf => |info| {
109 // The failure cases are unreachable because we only set the dwarf field if these
110 // are set
111 const di = if (self.module.di.?) |*di| di else |_| unreachable;
112 const dwarf = if (di.dwarf) |*dwarf| dwarf else unreachable;
113
114 // Return the main symbol and then return the iterator
115 defer self.symbols = .none;
116 const gpa = std.debug.getDebugInfoAllocator();
117 return dwarf.getSymbol(gpa, native_endian, info.addr) catch |err| switch (err) {
118 error.MissingDebugInfo => return null,
119
120 error.InvalidDebugInfo,
121 error.OutOfMemory,
122 => |e| return e,
123
124 error.ReadFailed,
125 error.EndOfStream,
126 error.Overflow,
127 error.StreamTooLong,
128 => return error.InvalidDebugInfo,
129 };
130 },
108 .dwarf => |*info| return info.next(),
131109 .none => return null,
132110 }
133111 }
......@@ -368,7 +346,7 @@ const Module = struct {
368346 /// iteration, e.g. because they only wanted the topmost call.
369347 inline_sites: std.ArrayList(*align(1) const std.pdb.InlineSiteSym),
370348 },
371 dwarf: struct { addr: u64 },
349 dwarf: std.debug.Dwarf.SymbolIterator,
372350 none: void,
373351
374352 fn init(di: *DebugInfo, vaddr: usize) Error!Symbols {
......@@ -425,23 +403,20 @@ const Module = struct {
425403
426404 // Dwarf
427405 dwarf: {
428 if (di.dwarf == null) break :dwarf;
406 const dwarf = &(di.dwarf orelse break :dwarf);
429407 const addr = vaddr + di.coff_image_base;
430 return .{ .dwarf = .{
431 .addr = addr,
432 } };
408 return .{ .dwarf = dwarf.getSymbols(gpa, native_endian, addr) };
433409 }
434410
435411 return error.MissingDebugInfo;
436412 }
437413
438 fn deinit(self: *Symbols) void {
414 fn deinit(self: *Symbols, io: Io) void {
415 const gpa = std.debug.getDebugInfoAllocator();
439416 switch (self.*) {
440 .pdb => |*info| {
441 const gpa = std.debug.getDebugInfoAllocator();
442 info.inline_sites.deinit(gpa);
443 },
444 .dwarf, .none => {},
417 .pdb => |*info| info.inline_sites.deinit(gpa),
418 .dwarf => |*info| info.deinit(io),
419 .none => {},
445420 }
446421 }
447422 };