Acquires the mutex on success.
fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!*Module
fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!*Module {
const text_base: *anyopaque = switch (builtin.target.os.tag) {
.macos => base: {
// This function is marked as deprecated; however, it is significantly more performant
// than `dladdr` (since the latter also does a very slow symbol lookup), so let's just
// use it for the better performance since it's still available.
break :base std.c._dyld_get_image_header_containing_address(
@ptrFromInt(address),
) orelse return error.MissingDebugInfo;
},
else => base: {
// On other Darwin systems, the function used above is entirely unavailable, so we have
// no choice but to use the slow `dladdr`.
var info: std.c.dl_info = undefined;
if (std.c.dladdr(@ptrFromInt(address), &info) == 0) {
return error.MissingDebugInfo;
}
break :base info.fbase;
},
};
try si.mutex.lock(io);
errdefer si.mutex.unlock(io);
const gop = try si.modules.getOrPutAdapted(gpa, @intFromPtr(text_base), Module.Adapter{});
errdefer comptime unreachable;
if (!gop.found_existing) gop.key_ptr.* = .{
.text_base = @intFromPtr(text_base),
.unwind = null,
.file = null,
};
return gop.key_ptr;
}