diff options
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/debug/SelfInfo.zig | 29 | ||||
| -rw-r--r-- | lib/std/debug/SelfInfo/DarwinModule.zig | 26 | ||||
| -rw-r--r-- | lib/std/debug/SelfInfo/ElfModule.zig | 7 | ||||
| -rw-r--r-- | lib/std/debug/SelfInfo/WindowsModule.zig | 19 |
4 files changed, 43 insertions, 38 deletions
diff --git a/lib/std/debug/SelfInfo.zig b/lib/std/debug/SelfInfo.zig index 32382ac1e1..9ca1b32f4e 100644 --- a/lib/std/debug/SelfInfo.zig +++ b/lib/std/debug/SelfInfo.zig @@ -18,7 +18,7 @@ const regValueNative = Dwarf.abi.regValueNative; const SelfInfo = @This(); -modules: std.AutoHashMapUnmanaged(usize, Module.DebugInfo), +modules: std.AutoArrayHashMapUnmanaged(usize, Module.DebugInfo), lookup_cache: Module.LookupCache, /// Indicates whether the `SelfInfo` implementation has support for this target. @@ -68,18 +68,18 @@ comptime { pub const init: SelfInfo = .{ .modules = .empty, - .lookup_cache = .init, + .lookup_cache = if (Module.LookupCache != void) .init, }; -pub fn deinit(self: *SelfInfo) void { - // MLUGG TODO: that's amusing, this function is straight-up unused. i... wonder if it even should be used anywhere? perhaps not... so perhaps it should not even exist...???? - var it = self.modules.iterator(); - while (it.next()) |entry| { - const mdi = entry.value_ptr.*; - mdi.deinit(self.allocator); - self.allocator.destroy(mdi); - } - self.modules.deinit(self.allocator); +pub fn deinit(self: *SelfInfo, gpa: Allocator) void { + for (self.modules.values()) |*di| di.deinit(gpa); + self.modules.deinit(gpa); + if (Module.LookupCache != void) self.lookup_cache.deinit(gpa); +} +comptime { + // `std.debug` does not currently utilize `deinit`, as it keeps hold of debug info for the + // whole lifetime of the program. Let's try to avoid it bitrotting. + _ = &deinit; } pub fn unwindFrame(self: *SelfInfo, gpa: Allocator, context: *UnwindContext) !usize { @@ -110,11 +110,12 @@ pub fn getModuleNameForAddress(self: *SelfInfo, gpa: Allocator, address: usize) /// This type contains the target-specific implementation. It must expose the following declarations: /// -/// * `LookupCache: type` -/// * `LookupCache.init: LookupCache` +/// * `LookupCache: type`, with the following declarations unless `LookupCache == void`: +/// * `init: LookupCache` +/// * `deinit: fn (*LookupCache, Allocator) void` /// * `lookup: fn (*LookupCache, Allocator, address: usize) !Module` /// * `key: fn (*const Module) usize` -/// * `DebugInfo: type` +/// * `DebugInfo: type`, with the following declarations: /// * `DebugInfo.init: DebugInfo` /// * `getSymbolAtAddress: fn (*const Module, Allocator, *DebugInfo, address: usize) !std.debug.Symbol` /// diff --git a/lib/std/debug/SelfInfo/DarwinModule.zig b/lib/std/debug/SelfInfo/DarwinModule.zig index d0cb47281f..976893e0af 100644 --- a/lib/std/debug/SelfInfo/DarwinModule.zig +++ b/lib/std/debug/SelfInfo/DarwinModule.zig @@ -578,9 +578,7 @@ fn unwindFrameMachO( return new_ip; } /// No cache needed, because `_dyld_get_image_header` etc are already fast. -pub const LookupCache = struct { - pub const init: LookupCache = .{}; -}; +pub const LookupCache = void; pub const DebugInfo = struct { unwind: ?struct { // Backed by the in-memory sections mapped by the loader @@ -601,22 +599,24 @@ pub const DebugInfo = struct { .full = null, }; + pub fn deinit(di: *DebugInfo, gpa: Allocator) void { + if (di.full) |*full| { + for (full.ofiles.values()) |*ofile| { + ofile.dwarf.deinit(gpa); + ofile.addr_table.deinit(gpa); + } + full.ofiles.deinit(gpa); + gpa.free(full.symbols); + posix.munmap(full.mapped_memory); + } + } + const OFile = struct { dwarf: Dwarf, // MLUGG TODO: this could use an adapter to just index straight into the strtab! addr_table: std.StringArrayHashMapUnmanaged(u64), }; - fn deinit(di: *DebugInfo, gpa: Allocator) void { - for (di.full.ofiles.values()) |*ofile| { - ofile.dwarf.deinit(gpa); - ofile.addr_table.deinit(gpa); - } - di.full.ofiles.deinit(); - gpa.free(di.full.symbols); - posix.munmap(di.full.mapped_memory); - } - fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile { const mapped_mem = try mapDebugInfoFile(o_file_path); errdefer posix.munmap(mapped_mem); diff --git a/lib/std/debug/SelfInfo/ElfModule.zig b/lib/std/debug/SelfInfo/ElfModule.zig index 41ea722962..4f64b147e1 100644 --- a/lib/std/debug/SelfInfo/ElfModule.zig +++ b/lib/std/debug/SelfInfo/ElfModule.zig @@ -4,9 +4,7 @@ build_id: ?[]const u8, gnu_eh_frame: ?[]const u8, /// No cache needed, because `dl_iterate_phdr` is already fast. -pub const LookupCache = struct { - pub const init: LookupCache = .{}; -}; +pub const LookupCache = void; pub const DebugInfo = struct { loaded_elf: ?Dwarf.ElfModule, @@ -15,6 +13,9 @@ pub const DebugInfo = struct { .loaded_elf = null, .unwind = null, }; + pub fn deinit(di: *DebugInfo, gpa: Allocator) void { + if (di.loaded_elf) |*loaded_elf| loaded_elf.deinit(gpa); + } }; pub fn key(m: ElfModule) usize { diff --git a/lib/std/debug/SelfInfo/WindowsModule.zig b/lib/std/debug/SelfInfo/WindowsModule.zig index ab322c201a..4f9d98353b 100644 --- a/lib/std/debug/SelfInfo/WindowsModule.zig +++ b/lib/std/debug/SelfInfo/WindowsModule.zig @@ -167,6 +167,9 @@ fn loadLocationInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo pub const LookupCache = struct { modules: std.ArrayListUnmanaged(windows.MODULEENTRY32), pub const init: LookupCache = .{ .modules = .empty }; + pub fn deinit(lc: *LookupCache, gpa: Allocator) void { + lc.modules.deinit(gpa); + } }; pub const DebugInfo = struct { loaded: bool, @@ -176,12 +179,6 @@ pub const DebugInfo = struct { file: fs.File, section_handle: windows.HANDLE, section_view: []const u8, - fn deinit(mapped: @This()) void { - const process_handle = windows.GetCurrentProcess(); - assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mapped.section_view.ptr)) == .SUCCESS); - windows.CloseHandle(mapped.section_handle); - mapped.file.close(); - } }, dwarf: ?Dwarf, @@ -199,11 +196,17 @@ pub const DebugInfo = struct { .coff_section_headers = &.{}, }; - fn deinit(di: *DebugInfo, gpa: Allocator) void { + pub fn deinit(di: *DebugInfo, gpa: Allocator) void { + if (!di.loaded) return; if (di.dwarf) |*dwarf| dwarf.deinit(gpa); if (di.pdb) |*pdb| pdb.deinit(); gpa.free(di.coff_section_headers); - if (di.mapped_file) |mapped| mapped.deinit(); + if (di.mapped_file) |mapped| { + const process_handle = windows.GetCurrentProcess(); + assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mapped.section_view.ptr)) == .SUCCESS); + windows.CloseHandle(mapped.section_handle); + mapped.file.close(); + } } fn getSymbolFromPdb(di: *DebugInfo, relocated_address: usize) !?std.debug.Symbol { |
