aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2022-04-21 00:45:01 +0200
committerJakub Konka <kubkon@jakubkonka.com>2022-04-21 00:45:01 +0200
commit96c1314443bdf26442a2c9fdffa03f2afffbcb8e (patch)
tree2f6e3a0e7f5700d44a6def055d196d721c82c45d /lib/std/debug.zig
parent26153ce73a1b9c49bdf89055b8ab7f4d3173f153 (diff)
downloadzig-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.zig32
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) {