| author | |
| committer | |
| log | 4efbb27aa2b841357c03d6ab158418ccad022415 |
| tree | 2e61e2cdcb42580a7c892d120f6d2ac2effbfbab |
| parent | 9edbf00ddfb3f8316d82e191b7aca281a0939ac0 |
Also fixes some memory management issues5 files changed, 93 insertions(+), 85 deletions(-)
lib/std/debug.zig+13-9| ... | @@ -38,12 +38,8 @@ pub const cpu_context = @import("debug/cpu_context.zig"); | ... | @@ -38,12 +38,8 @@ pub const cpu_context = @import("debug/cpu_context.zig"); |
| 38 | /// pub const init: SelfInfo; | 38 | /// pub const init: SelfInfo; |
| 39 | /// pub fn deinit(si: *SelfInfo, io: Io) void; | 39 | /// pub fn deinit(si: *SelfInfo, io: Io) void; |
| 40 | /// | 40 | /// |
| 41 | /// /// Returns the the symbols and source locations of the instruction at `address`. Often this | 41 | /// /// Returns the the symbols and source locations of the instruction at `address`. |
| 42 | /// /// will return a single result, but in the case of inlines it may return multiple. When | 42 | /// pub fn getSymbols(si: *SelfInfo, io: Io, address: usize, include_inline_callers: bool) SelfInfoError![]Symbol; |
| 43 | /// /// multiple results are returned, they are sorted from innermost to outermost. | ||
| 44 | /// pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) SelfInfoError![]const Symbol; | ||
| 45 | /// /// Frees symbols returned from `getSymbols`. | ||
| 46 | /// pub fn freeSymbols(si: *SelfInfo, symbols: []const Symbol) void; | ||
| 47 | /// /// Returns a name for the "module" (e.g. shared library or executable image) containing `address`. | 43 | /// /// Returns a name for the "module" (e.g. shared library or executable image) containing `address`. |
| 48 | /// pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) SelfInfoError![]const u8; | 44 | /// pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) SelfInfoError![]const u8; |
| 49 | /// pub fn getModuleSlide(si: *SelfInfo, io: Io, address: usize) SelfInfoError!usize; | 45 | /// pub fn getModuleSlide(si: *SelfInfo, io: Io, address: usize) SelfInfoError!usize; |
| ... | @@ -233,6 +229,11 @@ pub const Symbol = struct { | ... | @@ -233,6 +229,11 @@ pub const Symbol = struct { |
| 233 | .compile_unit_name = null, | 229 | .compile_unit_name = null, |
| 234 | .source_location = null, | 230 | .source_location = null, |
| 235 | }; | 231 | }; |
| 232 | |||
| 233 | pub fn deinit(self: *Symbol, gpa: Allocator) void { | ||
| 234 | if (self.source_location) |sl| gpa.free(sl.file_name); | ||
| 235 | self.* = undefined; | ||
| 236 | } | ||
| 236 | }; | 237 | }; |
| 237 | 238 | ||
| 238 | /// Deprecated because it returns the optimization mode of the standard | 239 | /// Deprecated because it returns the optimization mode of the standard |
| ... | @@ -1192,7 +1193,8 @@ fn printSourceAtAddress( | ... | @@ -1192,7 +1193,8 @@ fn printSourceAtAddress( |
| 1192 | t: Io.Terminal, | 1193 | t: Io.Terminal, |
| 1193 | options: PrintSourceAddressOptions, | 1194 | options: PrintSourceAddressOptions, |
| 1194 | ) Writer.Error!void { | 1195 | ) Writer.Error!void { |
| 1195 | const symbols: []const Symbol = debug_info.getSymbols(io, options.address) catch |err| { | 1196 | const gpa = getDebugInfoAllocator(); |
| 1197 | const symbols: []Symbol = debug_info.getSymbols(io, options.address, options.resolve_inline_callers) catch |err| { | ||
| 1196 | t.setColor(.dim) catch {}; | 1198 | t.setColor(.dim) catch {}; |
| 1197 | defer t.setColor(.reset) catch {}; | 1199 | defer t.setColor(.reset) catch {}; |
| 1198 | switch (err) { | 1200 | switch (err) { |
| ... | @@ -1211,7 +1213,10 @@ fn printSourceAtAddress( | ... | @@ -1211,7 +1213,10 @@ fn printSourceAtAddress( |
| 1211 | } | 1213 | } |
| 1212 | return printLineInfo(io, t, debug_info, null, options.address, null, null); | 1214 | return printLineInfo(io, t, debug_info, null, options.address, null, null); |
| 1213 | }; | 1215 | }; |
| 1214 | defer debug_info.freeSymbols(symbols); | 1216 | defer { |
| 1217 | for (symbols) |*symbol| symbol.deinit(gpa); | ||
| 1218 | gpa.free(symbols); | ||
| 1219 | } | ||
| 1215 | for (symbols) |symbol| { | 1220 | for (symbols) |symbol| { |
| 1216 | try printLineInfo( | 1221 | try printLineInfo( |
| 1217 | io, | 1222 | io, |
| ... | @@ -1222,7 +1227,6 @@ fn printSourceAtAddress( | ... | @@ -1222,7 +1227,6 @@ fn printSourceAtAddress( |
| 1222 | symbol.name, | 1227 | symbol.name, |
| 1223 | symbol.compile_unit_name, | 1228 | symbol.compile_unit_name, |
| 1224 | ); | 1229 | ); |
| 1225 | if (!options.resolve_inline_callers) break; | ||
| 1226 | } | 1230 | } |
| 1227 | } | 1231 | } |
| 1228 | fn printLineInfo( | 1232 | fn printLineInfo( |
lib/std/debug/Dwarf.zig+13-8| ... | @@ -1545,17 +1545,22 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 { | ... | @@ -1545,17 +1545,22 @@ fn getStringGeneric(opt_str: ?[]const u8, offset: u64) ![:0]const u8 { |
| 1545 | return str[casted_offset..last :0]; | 1545 | return str[casted_offset..last :0]; |
| 1546 | } | 1546 | } |
| 1547 | 1547 | ||
| 1548 | pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) std.debug.SelfInfoError![]const std.debug.Symbol { | 1548 | pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64, resolve_inline_callers: bool) std.debug.SelfInfoError![]std.debug.Symbol { |
| 1549 | const symbol = try gpa.create(std.debug.Symbol); | 1549 | _ = resolve_inline_callers; |
| 1550 | errdefer gpa.destroy(symbol); | 1550 | |
| 1551 | var symbols: std.ArrayList(std.debug.Symbol) = try .initCapacity(gpa, 1); | ||
| 1552 | errdefer { | ||
| 1553 | for (symbols.items) |*symbol| symbol.deinit(gpa); | ||
| 1554 | symbols.deinit(gpa); | ||
| 1555 | } | ||
| 1551 | const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) { | 1556 | const compile_unit = di.findCompileUnit(endian, address) catch |err| switch (err) { |
| 1552 | error.EndOfStream, error.Overflow => { | 1557 | error.EndOfStream, error.Overflow => { |
| 1553 | symbol.* = .unknown; | 1558 | symbols.appendAssumeCapacity(.unknown); |
| 1554 | return symbol[0..1]; | 1559 | return symbols.toOwnedSlice(gpa); |
| 1555 | }, | 1560 | }, |
| 1556 | else => |e| return e, | 1561 | else => |e| return e, |
| 1557 | }; | 1562 | }; |
| 1558 | symbol.* = .{ | 1563 | symbols.appendAssumeCapacity(.{ |
| 1559 | .name = di.getSymbolName(address), | 1564 | .name = di.getSymbolName(address), |
| 1560 | .compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) { | 1565 | .compile_unit_name = compile_unit.die.getAttrString(di, endian, std.dwarf.AT.name, di.section(.debug_str), compile_unit) catch |err| switch (err) { |
| 1561 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | 1566 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
| ... | @@ -1569,8 +1574,8 @@ pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) std. | ... | @@ -1569,8 +1574,8 @@ pub fn getSymbols(di: *Dwarf, gpa: Allocator, endian: Endian, address: u64) std. |
| 1569 | => return error.InvalidDebugInfo, | 1574 | => return error.InvalidDebugInfo, |
| 1570 | else => |e| return e, | 1575 | else => |e| return e, |
| 1571 | }, | 1576 | }, |
| 1572 | }; | 1577 | }); |
| 1573 | return symbol[0..1]; | 1578 | return symbols.toOwnedSlice(gpa); |
| 1574 | } | 1579 | } |
| 1575 | 1580 | ||
| 1576 | /// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and | 1581 | /// DWARF5 7.4: "In the 32-bit DWARF format, all values that represent lengths of DWARF sections and |
lib/std/debug/SelfInfo/Elf.zig+10-17| ... | @@ -30,7 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void { | ... | @@ -30,7 +30,7 @@ pub fn deinit(si: *SelfInfo, io: Io) void { |
| 30 | if (si.unwind_cache) |cache| gpa.free(cache); | 30 | if (si.unwind_cache) |cache| gpa.free(cache); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug.Symbol { | 33 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize, resolve_inline_callers: bool) Error![]std.debug.Symbol { |
| 34 | const gpa = std.debug.getDebugInfoAllocator(); | 34 | const gpa = std.debug.getDebugInfoAllocator(); |
| 35 | const module = try si.findModule(gpa, io, address, .exclusive); | 35 | const module = try si.findModule(gpa, io, address, .exclusive); |
| 36 | defer si.rwlock.unlock(io); | 36 | defer si.rwlock.unlock(io); |
| ... | @@ -53,27 +53,20 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug | ... | @@ -53,27 +53,20 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug |
| 53 | }; | 53 | }; |
| 54 | loaded_elf.scanned_dwarf = true; | 54 | loaded_elf.scanned_dwarf = true; |
| 55 | } | 55 | } |
| 56 | return dwarf.getSymbols(gpa, native_endian, vaddr); | 56 | return dwarf.getSymbols(gpa, native_endian, vaddr, resolve_inline_callers); |
| 57 | } | 57 | } |
| 58 | // When DWARF is unavailable, fall back to searching the symtab. | 58 | // When DWARF is unavailable, fall back to searching the symtab. |
| 59 | const symbol = try gpa.create(std.debug.Symbol); | 59 | var symbols: std.ArrayList(std.debug.Symbol) = try .initCapacity(gpa, 1); |
| 60 | errdefer gpa.destroy(symbol); | 60 | errdefer { |
| 61 | symbol.* = loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { | 61 | for (symbols.items) |*symbol| symbol.deinit(gpa); |
| 62 | symbols.deinit(gpa); | ||
| 63 | } | ||
| 64 | symbols.appendAssumeCapacity(loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { | ||
| 62 | error.NoSymtab, error.NoStrtab => return error.MissingDebugInfo, | 65 | error.NoSymtab, error.NoStrtab => return error.MissingDebugInfo, |
| 63 | error.BadSymtab => return error.InvalidDebugInfo, | 66 | error.BadSymtab => return error.InvalidDebugInfo, |
| 64 | error.OutOfMemory => |e| return e, | 67 | error.OutOfMemory => |e| return e, |
| 65 | }; | 68 | }); |
| 66 | return symbol[0..1]; | 69 | return symbols.toOwnedSlice(gpa); |
| 67 | } | ||
| 68 | pub fn freeSymbols(si: *SelfInfo, symbols: []const std.debug.Symbol) void { | ||
| 69 | _ = si; | ||
| 70 | const gpa = std.debug.getDebugInfoAllocator(); | ||
| 71 | for (symbols) |symbol| { | ||
| 72 | if (symbol.source_location) |source_location| { | ||
| 73 | gpa.free(source_location.file_name); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | gpa.free(symbols); | ||
| 77 | } | 70 | } |
| 78 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { | 71 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { |
| 79 | const gpa = std.debug.getDebugInfoAllocator(); | 72 | const gpa = std.debug.getDebugInfoAllocator(); |
lib/std/debug/SelfInfo/MachO.zig+17-22| ... | @@ -36,15 +36,20 @@ pub const SymbolIterator = struct { | ... | @@ -36,15 +36,20 @@ pub const SymbolIterator = struct { |
| 36 | } | 36 | } |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug.Symbol { | 39 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize, resolve_inline_callers: bool) Error![]std.debug.Symbol { |
| 40 | _ = resolve_inline_callers; | ||
| 41 | |||
| 40 | const gpa = std.debug.getDebugInfoAllocator(); | 42 | const gpa = std.debug.getDebugInfoAllocator(); |
| 41 | const module = try si.findModule(gpa, io, address); | 43 | const module = try si.findModule(gpa, io, address); |
| 42 | defer si.mutex.unlock(io); | 44 | defer si.mutex.unlock(io); |
| 43 | 45 | ||
| 44 | const file = try module.getFile(gpa, io); | 46 | const file = try module.getFile(gpa, io); |
| 45 | 47 | ||
| 46 | const symbol = try gpa.create(std.debug.Symbol); | 48 | var symbols: std.ArrayList(std.debug.Symbol) = try .initCapacity(gpa, 1); |
| 47 | errdefer gpa.destroy(symbol); | 49 | errdefer { |
| 50 | for (symbols.items) |*symbol| symbol.deinit(gpa); | ||
| 51 | symbols.deinit(gpa); | ||
| 52 | } | ||
| 48 | 53 | ||
| 49 | // This is not necessarily the same as the vmaddr_slide that dyld would report. This is | 54 | // This is not necessarily the same as the vmaddr_slide that dyld would report. This is |
| 50 | // because the segments in the file on disk might differ from the ones in memory. Normally | 55 | // because the segments in the file on disk might differ from the ones in memory. Normally |
| ... | @@ -60,25 +65,25 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug | ... | @@ -60,25 +65,25 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug |
| 60 | 65 | ||
| 61 | const ofile_dwarf, const ofile_vaddr = file.getDwarfForAddress(gpa, io, vaddr) catch { | 66 | const ofile_dwarf, const ofile_vaddr = file.getDwarfForAddress(gpa, io, vaddr) catch { |
| 62 | // Return at least the symbol name if available. | 67 | // Return at least the symbol name if available. |
| 63 | symbol.* = .{ | 68 | symbols.appendAssumeCapacity(.{ |
| 64 | .name = try file.lookupSymbolName(vaddr), | 69 | .name = try file.lookupSymbolName(vaddr), |
| 65 | .compile_unit_name = null, | 70 | .compile_unit_name = null, |
| 66 | .source_location = null, | 71 | .source_location = null, |
| 67 | }; | 72 | }); |
| 68 | return symbol[0..1]; | 73 | return symbols.toOwnedSlice(gpa); |
| 69 | }; | 74 | }; |
| 70 | 75 | ||
| 71 | const compile_unit = ofile_dwarf.findCompileUnit(native_endian, ofile_vaddr) catch { | 76 | const compile_unit = ofile_dwarf.findCompileUnit(native_endian, ofile_vaddr) catch { |
| 72 | // Return at least the symbol name if available. | 77 | // Return at least the symbol name if available. |
| 73 | symbol.* = .{ | 78 | symbols.appendAssumeCapacity(.{ |
| 74 | .name = try file.lookupSymbolName(vaddr), | 79 | .name = try file.lookupSymbolName(vaddr), |
| 75 | .compile_unit_name = null, | 80 | .compile_unit_name = null, |
| 76 | .source_location = null, | 81 | .source_location = null, |
| 77 | }; | 82 | }); |
| 78 | return symbol[0..1]; | 83 | return symbols.toOwnedSlice(gpa); |
| 79 | }; | 84 | }; |
| 80 | 85 | ||
| 81 | symbol.* = .{ | 86 | symbols.appendAssumeCapacity(.{ |
| 82 | .name = ofile_dwarf.getSymbolName(ofile_vaddr) orelse | 87 | .name = ofile_dwarf.getSymbolName(ofile_vaddr) orelse |
| 83 | try file.lookupSymbolName(vaddr), | 88 | try file.lookupSymbolName(vaddr), |
| 84 | .compile_unit_name = compile_unit.die.getAttrString( | 89 | .compile_unit_name = compile_unit.die.getAttrString( |
| ... | @@ -96,18 +101,8 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug | ... | @@ -96,18 +101,8 @@ pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug |
| 96 | compile_unit, | 101 | compile_unit, |
| 97 | ofile_vaddr, | 102 | ofile_vaddr, |
| 98 | ) catch null, | 103 | ) catch null, |
| 99 | }; | 104 | }); |
| 100 | return symbol[0..1]; | 105 | return symbols.toOwnedSlice(gpa); |
| 101 | } | ||
| 102 | pub fn freeSymbols(si: *SelfInfo, symbols: []const std.debug.Symbol) void { | ||
| 103 | _ = si; | ||
| 104 | const gpa = std.debug.getDebugInfoAllocator(); | ||
| 105 | for (symbols) |symbol| { | ||
| 106 | if (symbol.source_location) |source_location| { | ||
| 107 | gpa.free(source_location.file_name); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | gpa.free(symbols); | ||
| 111 | } | 106 | } |
| 112 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { | 107 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { |
| 113 | _ = si; | 108 | _ = si; |
lib/std/debug/SelfInfo/Windows.zig+40-29| ... | @@ -25,24 +25,13 @@ pub fn deinit(si: *SelfInfo, io: Io) void { | ... | @@ -25,24 +25,13 @@ pub fn deinit(si: *SelfInfo, io: Io) void { |
| 25 | si.modules.deinit(gpa); | 25 | si.modules.deinit(gpa); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize) Error![]const std.debug.Symbol { | 28 | pub fn getSymbols(si: *SelfInfo, io: Io, address: usize, resolve_inline_callers: bool) Error![]std.debug.Symbol { |
| 29 | const gpa = std.debug.getDebugInfoAllocator(); | 29 | const gpa = std.debug.getDebugInfoAllocator(); |
| 30 | try si.lock.lockShared(io); | 30 | try si.lock.lockShared(io); |
| 31 | defer si.lock.unlockShared(io); | 31 | defer si.lock.unlockShared(io); |
| 32 | const module = try si.findModule(gpa, address); | 32 | const module = try si.findModule(gpa, address); |
| 33 | const di = try module.getDebugInfo(gpa, io); | 33 | const di = try module.getDebugInfo(gpa, io); |
| 34 | return di.getSymbols(gpa, address - @intFromPtr(module.entry.DllBase)); | 34 | return di.getSymbols(gpa, address - @intFromPtr(module.entry.DllBase), resolve_inline_callers); |
| 35 | } | ||
| 36 | |||
| 37 | pub fn freeSymbols(si: *SelfInfo, symbols: []const std.debug.Symbol) void { | ||
| 38 | _ = si; | ||
| 39 | const gpa = std.debug.getDebugInfoAllocator(); | ||
| 40 | for (symbols) |symbol| { | ||
| 41 | if (symbol.source_location) |source_location| { | ||
| 42 | gpa.free(source_location.file_name); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | gpa.free(symbols); | ||
| 46 | } | 35 | } |
| 47 | 36 | ||
| 48 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { | 37 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { |
| ... | @@ -252,7 +241,7 @@ const Module = struct { | ... | @@ -252,7 +241,7 @@ const Module = struct { |
| 252 | arena.deinit(); | 241 | arena.deinit(); |
| 253 | } | 242 | } |
| 254 | 243 | ||
| 255 | fn getSymbols(di: *DebugInfo, gpa: Allocator, vaddr: usize) Error![]const std.debug.Symbol { | 244 | fn getSymbols(di: *DebugInfo, gpa: Allocator, vaddr: usize, resolve_inline_callers: bool) Error![]std.debug.Symbol { |
| 256 | pdb: { | 245 | pdb: { |
| 257 | const pdb = &(di.pdb orelse break :pdb); | 246 | const pdb = &(di.pdb orelse break :pdb); |
| 258 | var coff_section: *align(1) const coff.SectionHeader = undefined; | 247 | var coff_section: *align(1) const coff.SectionHeader = undefined; |
| ... | @@ -285,8 +274,12 @@ const Module = struct { | ... | @@ -285,8 +274,12 @@ const Module = struct { |
| 285 | 274 | ||
| 286 | const addr = vaddr - coff_section.virtual_address; | 275 | const addr = vaddr - coff_section.virtual_address; |
| 287 | const maybe_proc = pdb.getProcSym(module, addr); | 276 | const maybe_proc = pdb.getProcSym(module, addr); |
| 288 | var symbols: std.ArrayList(std.debug.Symbol) = .empty; | 277 | const compile_unit_name = fs.path.basename(module.obj_file_name); |
| 289 | errdefer symbols.deinit(gpa); | 278 | var symbols: std.ArrayList(std.debug.Symbol) = try .initCapacity(gpa, 1); |
| 279 | errdefer { | ||
| 280 | for (symbols.items) |*symbol| symbol.deinit(gpa); | ||
| 281 | symbols.deinit(gpa); | ||
| 282 | } | ||
| 290 | 283 | ||
| 291 | if (maybe_proc) |proc| { | 284 | if (maybe_proc) |proc| { |
| 292 | const offset_in_func = addr - proc.code_offset; | 285 | const offset_in_func = addr - proc.code_offset; |
| ... | @@ -315,25 +308,43 @@ const Module = struct { | ... | @@ -315,25 +308,43 @@ const Module = struct { |
| 315 | if (inline_site.inlinee == last_inlinee) continue; | 308 | if (inline_site.inlinee == last_inlinee) continue; |
| 316 | last_inlinee = inline_site.inlinee; | 309 | last_inlinee = inline_site.inlinee; |
| 317 | 310 | ||
| 311 | // If we're appending this symbol, resolve the name. If we're replacing the | ||
| 312 | // last symbol, clear the previous symbols and wait to resolve the name | ||
| 313 | // until we've reached the last symbol to avoid doing work and then | ||
| 314 | // throwing it out. | ||
| 315 | const name = b: { | ||
| 316 | if (resolve_inline_callers) break :b pdb.findInlineeName(inline_site.inlinee); | ||
| 317 | symbols.items.len = 0; | ||
| 318 | break :b null; | ||
| 319 | }; | ||
| 320 | |||
| 318 | try symbols.append(gpa, .{ | 321 | try symbols.append(gpa, .{ |
| 319 | .name = pdb.findInlineeName(inline_site.inlinee), | 322 | .name = name, |
| 320 | .compile_unit_name = fs.path.basename(module.obj_file_name), | 323 | .compile_unit_name = compile_unit_name, |
| 321 | .source_location = loc, | 324 | .source_location = loc, |
| 322 | }); | 325 | }); |
| 323 | } | 326 | } |
| 324 | 327 | ||
| 325 | // Inline sites are stored in the pdb in reverse order, so we reverse the | 328 | if (resolve_inline_callers) { |
| 326 | // matching sites here. We could alternatively use the parent fields to | 329 | // Inline sites are stored in the pdb in reverse order, so we reverse the |
| 327 | // determine the order, but this would introduce seemingly unecessary | 330 | // matching sites here. We could alternatively use the parent fields to |
| 328 | // complexity. | 331 | // determine the order, but this would introduce seemingly unecessary |
| 329 | std.mem.reverse(std.debug.Symbol, symbols.items); | 332 | // complexity. |
| 333 | std.mem.reverse(std.debug.Symbol, symbols.items); | ||
| 334 | } else if (last_inlinee) |inlinee| { | ||
| 335 | // If we haven't resolved the name yet, resolve it now | ||
| 336 | symbols.items[symbols.items.len - 1].name = pdb.findInlineeName(inlinee); | ||
| 337 | } | ||
| 330 | } | 338 | } |
| 331 | 339 | ||
| 332 | try symbols.append(gpa, .{ | 340 | // If there's room for another symbol, add the actual proc |
| 333 | .name = if (maybe_proc) |proc| pdb.getSymbolName(proc) else null, | 341 | if (resolve_inline_callers or symbols.items.len == 0) { |
| 334 | .compile_unit_name = fs.path.basename(module.obj_file_name), | 342 | try symbols.append(gpa, .{ |
| 335 | .source_location = pdb.getLineNumberInfo(module, addr) catch null, | 343 | .name = if (maybe_proc) |proc| pdb.getSymbolName(proc) else null, |
| 336 | }); | 344 | .compile_unit_name = compile_unit_name, |
| 345 | .source_location = pdb.getLineNumberInfo(module, addr) catch null, | ||
| 346 | }); | ||
| 347 | } | ||
| 337 | 348 | ||
| 338 | return symbols.toOwnedSlice(gpa); | 349 | return symbols.toOwnedSlice(gpa); |
| 339 | } | 350 | } |
| ... | @@ -341,7 +352,7 @@ const Module = struct { | ... | @@ -341,7 +352,7 @@ const Module = struct { |
| 341 | dwarf: { | 352 | dwarf: { |
| 342 | const dwarf = &(di.dwarf orelse break :dwarf); | 353 | const dwarf = &(di.dwarf orelse break :dwarf); |
| 343 | const addr = vaddr + di.coff_image_base; | 354 | const addr = vaddr + di.coff_image_base; |
| 344 | return dwarf.getSymbols(gpa, native_endian, addr); | 355 | return dwarf.getSymbols(gpa, native_endian, addr, resolve_inline_callers); |
| 345 | } | 356 | } |
| 346 | 357 | ||
| 347 | return error.MissingDebugInfo; | 358 | return error.MissingDebugInfo; |