| author | |
| committer | |
| log | 665f13b0cde4b9c2e69b139a87d272a67a9489e1 |
| tree | 88598b5eb7d17a86ea15a93ca15dbab5be6594d2 |
| parent | ba3f38959a31ace9af1816f16cda6c0717518b7f |
| signature |
4 files changed, 43 insertions(+), 38 deletions(-)
lib/std/debug/SelfInfo.zig+15-14| ... | @@ -18,7 +18,7 @@ const regValueNative = Dwarf.abi.regValueNative; | ... | @@ -18,7 +18,7 @@ const regValueNative = Dwarf.abi.regValueNative; |
| 18 | 18 | ||
| 19 | const SelfInfo = @This(); | 19 | const SelfInfo = @This(); |
| 20 | 20 | ||
| 21 | modules: std.AutoHashMapUnmanaged(usize, Module.DebugInfo), | 21 | modules: std.AutoArrayHashMapUnmanaged(usize, Module.DebugInfo), |
| 22 | lookup_cache: Module.LookupCache, | 22 | lookup_cache: Module.LookupCache, |
| 23 | 23 | ||
| 24 | /// Indicates whether the `SelfInfo` implementation has support for this target. | 24 | /// Indicates whether the `SelfInfo` implementation has support for this target. |
| ... | @@ -68,18 +68,18 @@ comptime { | ... | @@ -68,18 +68,18 @@ comptime { |
| 68 | 68 | ||
| 69 | pub const init: SelfInfo = .{ | 69 | pub const init: SelfInfo = .{ |
| 70 | .modules = .empty, | 70 | .modules = .empty, |
| 71 | .lookup_cache = .init, | 71 | .lookup_cache = if (Module.LookupCache != void) .init, |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | pub fn deinit(self: *SelfInfo) void { | 74 | pub fn deinit(self: *SelfInfo, gpa: Allocator) void { |
| 75 | // 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...???? | 75 | for (self.modules.values()) |*di| di.deinit(gpa); |
| 76 | var it = self.modules.iterator(); | 76 | self.modules.deinit(gpa); |
| 77 | while (it.next()) |entry| { | 77 | if (Module.LookupCache != void) self.lookup_cache.deinit(gpa); |
| 78 | const mdi = entry.value_ptr.*; | 78 | } |
| 79 | mdi.deinit(self.allocator); | 79 | comptime { |
| 80 | self.allocator.destroy(mdi); | 80 | // `std.debug` does not currently utilize `deinit`, as it keeps hold of debug info for the |
| 81 | } | 81 | // whole lifetime of the program. Let's try to avoid it bitrotting. |
| 82 | self.modules.deinit(self.allocator); | 82 | _ = &deinit; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | pub fn unwindFrame(self: *SelfInfo, gpa: Allocator, context: *UnwindContext) !usize { | 85 | pub fn unwindFrame(self: *SelfInfo, gpa: Allocator, context: *UnwindContext) !usize { |
| ... | @@ -110,11 +110,12 @@ pub fn getModuleNameForAddress(self: *SelfInfo, gpa: Allocator, address: usize) | ... | @@ -110,11 +110,12 @@ pub fn getModuleNameForAddress(self: *SelfInfo, gpa: Allocator, address: usize) |
| 110 | 110 | ||
| 111 | /// This type contains the target-specific implementation. It must expose the following declarations: | 111 | /// This type contains the target-specific implementation. It must expose the following declarations: |
| 112 | /// | 112 | /// |
| 113 | /// * `LookupCache: type` | 113 | /// * `LookupCache: type`, with the following declarations unless `LookupCache == void`: |
| 114 | /// * `LookupCache.init: LookupCache` | 114 | /// * `init: LookupCache` |
| 115 | /// * `deinit: fn (*LookupCache, Allocator) void` | ||
| 115 | /// * `lookup: fn (*LookupCache, Allocator, address: usize) !Module` | 116 | /// * `lookup: fn (*LookupCache, Allocator, address: usize) !Module` |
| 116 | /// * `key: fn (*const Module) usize` | 117 | /// * `key: fn (*const Module) usize` |
| 117 | /// * `DebugInfo: type` | 118 | /// * `DebugInfo: type`, with the following declarations: |
| 118 | /// * `DebugInfo.init: DebugInfo` | 119 | /// * `DebugInfo.init: DebugInfo` |
| 119 | /// * `getSymbolAtAddress: fn (*const Module, Allocator, *DebugInfo, address: usize) !std.debug.Symbol` | 120 | /// * `getSymbolAtAddress: fn (*const Module, Allocator, *DebugInfo, address: usize) !std.debug.Symbol` |
| 120 | /// | 121 | /// |
lib/std/debug/SelfInfo/DarwinModule.zig+13-13| ... | @@ -578,9 +578,7 @@ fn unwindFrameMachO( | ... | @@ -578,9 +578,7 @@ fn unwindFrameMachO( |
| 578 | return new_ip; | 578 | return new_ip; |
| 579 | } | 579 | } |
| 580 | /// No cache needed, because `_dyld_get_image_header` etc are already fast. | 580 | /// No cache needed, because `_dyld_get_image_header` etc are already fast. |
| 581 | pub const LookupCache = struct { | 581 | pub const LookupCache = void; |
| 582 | pub const init: LookupCache = .{}; | ||
| 583 | }; | ||
| 584 | pub const DebugInfo = struct { | 582 | pub const DebugInfo = struct { |
| 585 | unwind: ?struct { | 583 | unwind: ?struct { |
| 586 | // Backed by the in-memory sections mapped by the loader | 584 | // Backed by the in-memory sections mapped by the loader |
| ... | @@ -601,22 +599,24 @@ pub const DebugInfo = struct { | ... | @@ -601,22 +599,24 @@ pub const DebugInfo = struct { |
| 601 | .full = null, | 599 | .full = null, |
| 602 | }; | 600 | }; |
| 603 | 601 | ||
| 602 | pub fn deinit(di: *DebugInfo, gpa: Allocator) void { | ||
| 603 | if (di.full) |*full| { | ||
| 604 | for (full.ofiles.values()) |*ofile| { | ||
| 605 | ofile.dwarf.deinit(gpa); | ||
| 606 | ofile.addr_table.deinit(gpa); | ||
| 607 | } | ||
| 608 | full.ofiles.deinit(gpa); | ||
| 609 | gpa.free(full.symbols); | ||
| 610 | posix.munmap(full.mapped_memory); | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 604 | const OFile = struct { | 614 | const OFile = struct { |
| 605 | dwarf: Dwarf, | 615 | dwarf: Dwarf, |
| 606 | // MLUGG TODO: this could use an adapter to just index straight into the strtab! | 616 | // MLUGG TODO: this could use an adapter to just index straight into the strtab! |
| 607 | addr_table: std.StringArrayHashMapUnmanaged(u64), | 617 | addr_table: std.StringArrayHashMapUnmanaged(u64), |
| 608 | }; | 618 | }; |
| 609 | 619 | ||
| 610 | fn deinit(di: *DebugInfo, gpa: Allocator) void { | ||
| 611 | for (di.full.ofiles.values()) |*ofile| { | ||
| 612 | ofile.dwarf.deinit(gpa); | ||
| 613 | ofile.addr_table.deinit(gpa); | ||
| 614 | } | ||
| 615 | di.full.ofiles.deinit(); | ||
| 616 | gpa.free(di.full.symbols); | ||
| 617 | posix.munmap(di.full.mapped_memory); | ||
| 618 | } | ||
| 619 | |||
| 620 | fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile { | 620 | fn loadOFile(gpa: Allocator, o_file_path: []const u8) !OFile { |
| 621 | const mapped_mem = try mapDebugInfoFile(o_file_path); | 621 | const mapped_mem = try mapDebugInfoFile(o_file_path); |
| 622 | errdefer posix.munmap(mapped_mem); | 622 | errdefer posix.munmap(mapped_mem); |
lib/std/debug/SelfInfo/ElfModule.zig+4-3| ... | @@ -4,9 +4,7 @@ build_id: ?[]const u8, | ... | @@ -4,9 +4,7 @@ build_id: ?[]const u8, |
| 4 | gnu_eh_frame: ?[]const u8, | 4 | gnu_eh_frame: ?[]const u8, |
| 5 | 5 | ||
| 6 | /// No cache needed, because `dl_iterate_phdr` is already fast. | 6 | /// No cache needed, because `dl_iterate_phdr` is already fast. |
| 7 | pub const LookupCache = struct { | 7 | pub const LookupCache = void; |
| 8 | pub const init: LookupCache = .{}; | ||
| 9 | }; | ||
| 10 | 8 | ||
| 11 | pub const DebugInfo = struct { | 9 | pub const DebugInfo = struct { |
| 12 | loaded_elf: ?Dwarf.ElfModule, | 10 | loaded_elf: ?Dwarf.ElfModule, |
| ... | @@ -15,6 +13,9 @@ pub const DebugInfo = struct { | ... | @@ -15,6 +13,9 @@ pub const DebugInfo = struct { |
| 15 | .loaded_elf = null, | 13 | .loaded_elf = null, |
| 16 | .unwind = null, | 14 | .unwind = null, |
| 17 | }; | 15 | }; |
| 16 | pub fn deinit(di: *DebugInfo, gpa: Allocator) void { | ||
| 17 | if (di.loaded_elf) |*loaded_elf| loaded_elf.deinit(gpa); | ||
| 18 | } | ||
| 18 | }; | 19 | }; |
| 19 | 20 | ||
| 20 | pub fn key(m: ElfModule) usize { | 21 | pub fn key(m: ElfModule) usize { |
lib/std/debug/SelfInfo/WindowsModule.zig+11-8| ... | @@ -167,6 +167,9 @@ fn loadLocationInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo | ... | @@ -167,6 +167,9 @@ fn loadLocationInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo |
| 167 | pub const LookupCache = struct { | 167 | pub const LookupCache = struct { |
| 168 | modules: std.ArrayListUnmanaged(windows.MODULEENTRY32), | 168 | modules: std.ArrayListUnmanaged(windows.MODULEENTRY32), |
| 169 | pub const init: LookupCache = .{ .modules = .empty }; | 169 | pub const init: LookupCache = .{ .modules = .empty }; |
| 170 | pub fn deinit(lc: *LookupCache, gpa: Allocator) void { | ||
| 171 | lc.modules.deinit(gpa); | ||
| 172 | } | ||
| 170 | }; | 173 | }; |
| 171 | pub const DebugInfo = struct { | 174 | pub const DebugInfo = struct { |
| 172 | loaded: bool, | 175 | loaded: bool, |
| ... | @@ -176,12 +179,6 @@ pub const DebugInfo = struct { | ... | @@ -176,12 +179,6 @@ pub const DebugInfo = struct { |
| 176 | file: fs.File, | 179 | file: fs.File, |
| 177 | section_handle: windows.HANDLE, | 180 | section_handle: windows.HANDLE, |
| 178 | section_view: []const u8, | 181 | section_view: []const u8, |
| 179 | fn deinit(mapped: @This()) void { | ||
| 180 | const process_handle = windows.GetCurrentProcess(); | ||
| 181 | assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mapped.section_view.ptr)) == .SUCCESS); | ||
| 182 | windows.CloseHandle(mapped.section_handle); | ||
| 183 | mapped.file.close(); | ||
| 184 | } | ||
| 185 | }, | 182 | }, |
| 186 | 183 | ||
| 187 | dwarf: ?Dwarf, | 184 | dwarf: ?Dwarf, |
| ... | @@ -199,11 +196,17 @@ pub const DebugInfo = struct { | ... | @@ -199,11 +196,17 @@ pub const DebugInfo = struct { |
| 199 | .coff_section_headers = &.{}, | 196 | .coff_section_headers = &.{}, |
| 200 | }; | 197 | }; |
| 201 | 198 | ||
| 202 | fn deinit(di: *DebugInfo, gpa: Allocator) void { | 199 | pub fn deinit(di: *DebugInfo, gpa: Allocator) void { |
| 200 | if (!di.loaded) return; | ||
| 203 | if (di.dwarf) |*dwarf| dwarf.deinit(gpa); | 201 | if (di.dwarf) |*dwarf| dwarf.deinit(gpa); |
| 204 | if (di.pdb) |*pdb| pdb.deinit(); | 202 | if (di.pdb) |*pdb| pdb.deinit(); |
| 205 | gpa.free(di.coff_section_headers); | 203 | gpa.free(di.coff_section_headers); |
| 206 | if (di.mapped_file) |mapped| mapped.deinit(); | 204 | if (di.mapped_file) |mapped| { |
| 205 | const process_handle = windows.GetCurrentProcess(); | ||
| 206 | assert(windows.ntdll.NtUnmapViewOfSection(process_handle, @constCast(mapped.section_view.ptr)) == .SUCCESS); | ||
| 207 | windows.CloseHandle(mapped.section_handle); | ||
| 208 | mapped.file.close(); | ||
| 209 | } | ||
| 207 | } | 210 | } |
| 208 | 211 | ||
| 209 | fn getSymbolFromPdb(di: *DebugInfo, relocated_address: usize) !?std.debug.Symbol { | 212 | fn getSymbolFromPdb(di: *DebugInfo, relocated_address: usize) !?std.debug.Symbol { |