| ... | @@ -93,12 +93,28 @@ pub fn getSymbols( | ... | @@ -93,12 +93,28 @@ pub fn getSymbols( |
| 93 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { | 93 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { |
| 94 | _ = si; | 94 | _ = si; |
| 95 | _ = io; | 95 | _ = io; |
| 96 | // This function is marked as deprecated; however, it is significantly more | 96 | return getModuleNameInner(address) orelse return error.MissingDebugInfo; |
| 97 | // performant than `dladdr` (since the latter also does a very slow symbol | 97 | } |
| 98 | // lookup), so let's use it since it's still available. | 98 | fn getModuleNameInner(address: usize) ?[]const u8 { |
| 99 | return std.mem.span(std.c.dyld_image_path_containing_address( | 99 | switch (builtin.target.os.tag) { |
| 100 | @ptrFromInt(address), | 100 | .macos => { |
| 101 | ) orelse return error.MissingDebugInfo); | 101 | // This function is marked as deprecated; however, it is significantly more performant |
| | 102 | // than `dladdr` (since the latter also does a very slow symbol lookup), so let's just |
| | 103 | // use it for the better performance since it's still available. |
| | 104 | return std.mem.span(std.c.dyld_image_path_containing_address( |
| | 105 | @ptrFromInt(address), |
| | 106 | ) orelse return null); |
| | 107 | }, |
| | 108 | else => { |
| | 109 | // On other Darwin systems, the function used above is entirely unavailable, so we have |
| | 110 | // no choice but to use the slow `dladdr`. |
| | 111 | var info: std.c.dl_info = undefined; |
| | 112 | if (std.c.dladdr(@ptrFromInt(address), &info) == 0) { |
| | 113 | return null; |
| | 114 | } |
| | 115 | return std.mem.span(info.fname); |
| | 116 | }, |
| | 117 | } |
| 102 | } | 118 | } |
| 103 | pub fn getModuleSlide(si: *SelfInfo, io: Io, address: usize) Error!usize { | 119 | pub fn getModuleSlide(si: *SelfInfo, io: Io, address: usize) Error!usize { |
| 104 | const gpa = std.debug.getDebugInfoAllocator(); | 120 | const gpa = std.debug.getDebugInfoAllocator(); |
| ... | @@ -446,12 +462,25 @@ fn unwindFrameInner(si: *SelfInfo, io: Io, context: *UnwindContext) !usize { | ... | @@ -446,12 +462,25 @@ fn unwindFrameInner(si: *SelfInfo, io: Io, context: *UnwindContext) !usize { |
| 446 | | 462 | |
| 447 | /// Acquires the mutex on success. | 463 | /// Acquires the mutex on success. |
| 448 | fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!*Module { | 464 | fn findModule(si: *SelfInfo, gpa: Allocator, io: Io, address: usize) Error!*Module { |
| 449 | // This function is marked as deprecated; however, it is significantly more | 465 | const text_base: *anyopaque = switch (builtin.target.os.tag) { |
| 450 | // performant than `dladdr` (since the latter also does a very slow symbol | 466 | .macos => base: { |
| 451 | // lookup), so let's use it since it's still available. | 467 | // This function is marked as deprecated; however, it is significantly more performant |
| 452 | const text_base = std.c._dyld_get_image_header_containing_address( | 468 | // than `dladdr` (since the latter also does a very slow symbol lookup), so let's just |
| 453 | @ptrFromInt(address), | 469 | // use it for the better performance since it's still available. |
| 454 | ) orelse return error.MissingDebugInfo; | 470 | break :base std.c._dyld_get_image_header_containing_address( |
| | 471 | @ptrFromInt(address), |
| | 472 | ) orelse return error.MissingDebugInfo; |
| | 473 | }, |
| | 474 | else => base: { |
| | 475 | // On other Darwin systems, the function used above is entirely unavailable, so we have |
| | 476 | // no choice but to use the slow `dladdr`. |
| | 477 | var info: std.c.dl_info = undefined; |
| | 478 | if (std.c.dladdr(@ptrFromInt(address), &info) == 0) { |
| | 479 | return error.MissingDebugInfo; |
| | 480 | } |
| | 481 | break :base info.fbase; |
| | 482 | }, |
| | 483 | }; |
| 455 | try si.mutex.lock(io); | 484 | try si.mutex.lock(io); |
| 456 | errdefer si.mutex.unlock(io); | 485 | errdefer si.mutex.unlock(io); |
| 457 | const gop = try si.modules.getOrPutAdapted(gpa, @intFromPtr(text_base), Module.Adapter{}); | 486 | const gop = try si.modules.getOrPutAdapted(gpa, @intFromPtr(text_base), Module.Adapter{}); |
| ... | @@ -563,9 +592,7 @@ const Module = struct { | ... | @@ -563,9 +592,7 @@ const Module = struct { |
| 563 | | 592 | |
| 564 | fn getFile(module: *Module, gpa: Allocator, io: Io) Error!*MachOFile { | 593 | fn getFile(module: *Module, gpa: Allocator, io: Io) Error!*MachOFile { |
| 565 | if (module.file == null) { | 594 | if (module.file == null) { |
| 566 | const path = std.mem.span( | 595 | const path = getModuleNameInner(module.text_base).?; |
| 567 | std.c.dyld_image_path_containing_address(@ptrFromInt(module.text_base)).?, | | |
| 568 | ); | | |
| 569 | module.file = MachOFile.load(gpa, io, path, builtin.cpu.arch) catch |err| switch (err) { | 596 | module.file = MachOFile.load(gpa, io, path, builtin.cpu.arch) catch |err| switch (err) { |
| 570 | error.InvalidMachO, error.InvalidDwarf => error.InvalidDebugInfo, | 597 | error.InvalidMachO, error.InvalidDwarf => error.InvalidDebugInfo, |
| 571 | error.MissingDebugInfo, error.OutOfMemory, error.UnsupportedDebugInfo, error.ReadFailed => |e| e, | 598 | error.MissingDebugInfo, error.OutOfMemory, error.UnsupportedDebugInfo, error.ReadFailed => |e| e, |