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...@@ -692,7 +692,7 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address
692 else => return err,692 else => return err,
693 };693 };
694694
695 const symbol_info = try module.getSymbolAtAddress(address);695 const symbol_info = try module.getSymbolAtAddress(debug_info.allocator, address);
696 defer symbol_info.deinit(debug_info.allocator);696 defer symbol_info.deinit(debug_info.allocator);
697697
698 return printLineInfo(698 return printLineInfo(
...@@ -1142,7 +1142,12 @@ pub const DebugInfo = struct {...@@ -1142,7 +1142,12 @@ pub const DebugInfo = struct {
1142 }1142 }
11431143
1144 pub fn deinit(self: *DebugInfo) void {1144 pub fn deinit(self: *DebugInfo) void {
1145 // TODO: resources https://github.com/ziglang/zig/issues/43531145 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 }
1146 self.address_map.deinit();1151 self.address_map.deinit();
1147 }1152 }
11481153
...@@ -1392,11 +1397,18 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1392,11 +1397,18 @@ pub const ModuleDebugInfo = switch (native_os) {
1392 addr_table: std.StringHashMap(u64),1397 addr_table: std.StringHashMap(u64),
1393 };1398 };
13941399
1395 pub fn allocator(self: @This()) mem.Allocator {1400 fn deinit(self: *@This(), allocator: mem.Allocator) void {
1396 return self.ofiles.allocator;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);
1397 }1409 }
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 {
1400 const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking });1412 const o_file = try fs.cwd().openFile(o_file_path, .{ .intended_io_mode = .blocking });
1401 const mapped_mem = try mapWholeFile(o_file);1413 const mapped_mem = try mapWholeFile(o_file);
14021414
...@@ -1448,7 +1460,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1448,7 +1460,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1448 )[0..symtabcmd.?.nsyms];1460 )[0..symtabcmd.?.nsyms];
14491461
1450 // TODO handle tentative (common) symbols1462 // TODO handle tentative (common) symbols
1451 var addr_table = std.StringHashMap(u64).init(self.allocator());1463 var addr_table = std.StringHashMap(u64).init(allocator);
1452 try addr_table.ensureTotalCapacity(@intCast(u32, symtab.len));1464 try addr_table.ensureTotalCapacity(@intCast(u32, symtab.len));
1453 for (symtab) |sym| {1465 for (symtab) |sym| {
1454 if (sym.n_strx == 0) continue;1466 if (sym.n_strx == 0) continue;
...@@ -1517,7 +1529,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1517,7 +1529,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1517 null,1529 null,
1518 };1530 };
15191531
1520 try DW.openDwarfDebugInfo(&di, self.allocator());1532 try DW.openDwarfDebugInfo(&di, allocator);
1521 var info = OFileInfo{1533 var info = OFileInfo{
1522 .di = di,1534 .di = di,
1523 .addr_table = addr_table,1535 .addr_table = addr_table,
...@@ -1529,7 +1541,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1529,7 +1541,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1529 return info;1541 return info;
1530 }1542 }
15311543
1532 pub fn getSymbolAtAddress(self: *@This(), address: usize) !SymbolInfo {1544 pub fn getSymbolAtAddress(self: *@This(), allocator: mem.Allocator, address: usize) !SymbolInfo {
1533 nosuspend {1545 nosuspend {
1534 // Translate the VA into an address into this object1546 // Translate the VA into an address into this object
1535 const relocated_address = address - self.base_address;1547 const relocated_address = address - self.base_address;
...@@ -1546,7 +1558,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1546,7 +1558,7 @@ pub const ModuleDebugInfo = switch (native_os) {
15461558
1547 // Check if its debug infos are already in the cache1559 // Check if its debug infos are already in the cache
1548 var o_file_info = self.ofiles.get(o_file_path) orelse1560 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) {
1550 error.FileNotFound,1562 error.FileNotFound,
1551 error.MissingDebugInfo,1563 error.MissingDebugInfo,
1552 error.InvalidDebugInfo,1564 error.InvalidDebugInfo,
...@@ -1573,7 +1585,7 @@ pub const ModuleDebugInfo = switch (native_os) {...@@ -1573,7 +1585,7 @@ pub const ModuleDebugInfo = switch (native_os) {
1573 error.MissingDebugInfo, error.InvalidDebugInfo => "???",1585 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
1574 },1586 },
1575 .line_info = o_file_di.getLineNumberInfo(1587 .line_info = o_file_di.getLineNumberInfo(
1576 self.allocator(),1588 allocator,
1577 compile_unit.*,1589 compile_unit.*,
1578 relocated_address_o + addr_off,1590 relocated_address_o + addr_off,
1579 ) catch |err| switch (err) {1591 ) catch |err| switch (err) {