diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2022-04-21 00:45:01 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2022-04-21 00:45:01 +0200 |
| commit | 96c1314443bdf26442a2c9fdffa03f2afffbcb8e (patch) | |
| tree | 2f6e3a0e7f5700d44a6def055d196d721c82c45d /lib/std/debug.zig | |
| parent | 26153ce73a1b9c49bdf89055b8ab7f4d3173f153 (diff) | |
| download | zig-96c1314443bdf26442a2c9fdffa03f2afffbcb8e.tar.gz zig-96c1314443bdf26442a2c9fdffa03f2afffbcb8e.zip | |
debug: fix resource (de)allocation for MachO targets
With this change, it is now possible to safely call
`var di = std.debug.openSelfDebugInfo(gpa)`. Calling then
`di.deinit()` on the object will correctly free all allocated
resources.
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index c6ee812c19..58038ef522 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -692,7 +692,7 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address else => return err, }; - const symbol_info = try module.getSymbolAtAddress(address); + const symbol_info = try module.getSymbolAtAddress(debug_info.allocator, address); defer symbol_info.deinit(debug_info.allocator); return printLineInfo( @@ -1142,7 +1142,12 @@ pub const DebugInfo = struct { } pub fn deinit(self: *DebugInfo) void { - // TODO: resources https://github.com/ziglang/zig/issues/4353 + var it = self.address_map.iterator(); + while (it.next()) |entry| { + const mdi = entry.value_ptr.*; + mdi.deinit(self.allocator); + self.allocator.destroy(mdi); + } self.address_map.deinit(); } @@ -1392,11 +1397,18 @@ pub const ModuleDebugInfo = switch (native_os) { addr_table: std.StringHashMap(u64), }; - pub fn allocator(self: @This()) mem.Allocator { - return self.ofiles.allocator; + fn deinit(self: *@This(), allocator: mem.Allocator) void { + var it = self.ofiles.iterator(); + while (it.next()) |entry| { + const ofile = entry.value_ptr; + ofile.di.deinit(allocator); + ofile.addr_table.deinit(); + } + self.ofiles.deinit(); + allocator.free(self.symbols); } - fn loadOFile(self: *@This(), o_file_path: []const u8) !OFileInfo { + fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !OFileInfo { const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking }); const mapped_mem = try mapWholeFile(o_file); @@ -1448,7 +1460,7 @@ pub const ModuleDebugInfo = switch (native_os) { )[0..symtabcmd.?.nsyms]; // TODO handle tentative (common) symbols - var addr_table = std.StringHashMap(u64).init(self.allocator()); + var addr_table = std.StringHashMap(u64).init(allocator); try addr_table.ensureTotalCapacity(@intCast(u32, symtab.len)); for (symtab) |sym| { if (sym.n_strx == 0) continue; @@ -1517,7 +1529,7 @@ pub const ModuleDebugInfo = switch (native_os) { null, }; - try DW.openDwarfDebugInfo(&di, self.allocator()); + try DW.openDwarfDebugInfo(&di, allocator); var info = OFileInfo{ .di = di, .addr_table = addr_table, @@ -1529,7 +1541,7 @@ pub const ModuleDebugInfo = switch (native_os) { return info; } - pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo { + pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo { nosuspend { // Translate the VA into an address into this object const relocated_address = address - self.base_address; @@ -1546,7 +1558,7 @@ pub const ModuleDebugInfo = switch (native_os) { // Check if its debug infos are already in the cache var o_file_info = self.ofiles.get(o_file_path) orelse - (self.loadOFile(o_file_path) catch |err| switch (err) { + (self.loadOFile(allocator, o_file_path) catch |err| switch (err) { error.FileNotFound, error.MissingDebugInfo, error.InvalidDebugInfo, @@ -1573,7 +1585,7 @@ pub const ModuleDebugInfo = switch (native_os) { error.MissingDebugInfo, error.InvalidDebugInfo => "???", }, .line_info = o_file_di.getLineNumberInfo( - self.allocator(), + allocator, compile_unit.*, relocated_address_o + addr_off, ) catch |err| switch (err) { |
