authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-21 00:45:01+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-21 00:45:01+02:00
log96c1314443bdf26442a2c9fdffa03f2afffbcb8e
tree2f6e3a0e7f5700d44a6def055d196d721c82c45d
parent26153ce73a1b9c49bdf89055b8ab7f4d3173f153

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.

1 files changed, 22 insertions(+), 10 deletions(-)

lib/std/debug.zig+22-10
......@@ -692,7 +692,7 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address
692692 else => return err,
693693 };
694694
695 const symbol_info = try module.getSymbolAtAddress(address);
695 const symbol_info = try module.getSymbolAtAddress(debug_info.allocator, address);
696696 defer symbol_info.deinit(debug_info.allocator);
697697
698698 return printLineInfo(
......@@ -1142,7 +1142,12 @@ pub const DebugInfo = struct {
11421142 }
11431143
11441144 pub fn deinit(self: *DebugInfo) void {
1145 // TODO: resources https://github.com/ziglang/zig/issues/4353
1145 var it = self.address_map.iterator();
1146 while (it.next()) |entry| {
1147 const mdi = entry.value_ptr.*;
1148 mdi.deinit(self.allocator);
1149 self.allocator.destroy(mdi);
1150 }
11461151 self.address_map.deinit();
11471152 }
11481153
......@@ -1392,11 +1397,18 @@ pub const ModuleDebugInfo = switch (native_os) {
13921397 addr_table: std.StringHashMap(u64),
13931398 };
13941399
1395 pub fn allocator(self: @This()) mem.Allocator {
1396 return self.ofiles.allocator;
1400 fn deinit(self: *@This(), allocator: mem.Allocator) void {
1401 var it = self.ofiles.iterator();
1402 while (it.next()) |entry| {
1403 const ofile = entry.value_ptr;
1404 ofile.di.deinit(allocator);
1405 ofile.addr_table.deinit();
1406 }
1407 self.ofiles.deinit();
1408 allocator.free(self.symbols);
13971409 }
13981410
1399 fn loadOFile(self: *@This(), o_file_path: []const u8) !OFileInfo {
1411 fn loadOFile(self: *@This(), allocator: mem.Allocator, o_file_path: []const u8) !OFileInfo {
14001412 const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking });
14011413 const mapped_mem = try mapWholeFile(o_file);
14021414
......@@ -1448,7 +1460,7 @@ pub const ModuleDebugInfo = switch (native_os) {
14481460 )[0..symtabcmd.?.nsyms];
14491461
14501462 // TODO handle tentative (common) symbols
1451 var addr_table = std.StringHashMap(u64).init(self.allocator());
1463 var addr_table = std.StringHashMap(u64).init(allocator);
14521464 try addr_table.ensureTotalCapacity(@intCast(u32, symtab.len));
14531465 for (symtab) |sym| {
14541466 if (sym.n_strx == 0) continue;
......@@ -1517,7 +1529,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15171529 null,
15181530 };
15191531
1520 try DW.openDwarfDebugInfo(&di, self.allocator());
1532 try DW.openDwarfDebugInfo(&di, allocator);
15211533 var info = OFileInfo{
15221534 .di = di,
15231535 .addr_table = addr_table,
......@@ -1529,7 +1541,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15291541 return info;
15301542 }
15311543
1532 pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {
1544 pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
15331545 nosuspend {
15341546 // Translate the VA into an address into this object
15351547 const relocated_address = address - self.base_address;
......@@ -1546,7 +1558,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15461558
15471559 // Check if its debug infos are already in the cache
15481560 var o_file_info = self.ofiles.get(o_file_path) orelse
1549 (self.loadOFile(o_file_path) catch |err| switch (err) {
1561 (self.loadOFile(allocator, o_file_path) catch |err| switch (err) {
15501562 error.FileNotFound,
15511563 error.MissingDebugInfo,
15521564 error.InvalidDebugInfo,
......@@ -1573,7 +1585,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15731585 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
15741586 },
15751587 .line_info = o_file_di.getLineNumberInfo(
1576 self.allocator(),
1588 allocator,
15771589 compile_unit.*,
15781590 relocated_address_o + addr_off,
15791591 ) catch |err| switch (err) {