| ... | ... | @@ -102,9 +102,9 @@ pub fn getStderrMutex() *std.Thread.Mutex { |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | 104 | /// TODO multithreaded awareness |
| 105 | | var self_debug_info: ?DebugInfo = null; |
| 105 | var self_debug_info: ?Info = null; |
| 106 | 106 | |
| 107 | | pub fn getSelfDebugInfo() !*DebugInfo { |
| 107 | pub fn getSelfDebugInfo() !*Info { |
| 108 | 108 | if (self_debug_info) |*info| { |
| 109 | 109 | return info; |
| 110 | 110 | } else { |
| ... | ... | @@ -346,7 +346,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT |
| 346 | 346 | stack_trace.index = slice.len; |
| 347 | 347 | } else { |
| 348 | 348 | // TODO: This should use the DWARF unwinder if .eh_frame_hdr is available (so that full debug info parsing isn't required). |
| 349 | | // A new path for loading DebugInfo needs to be created which will only attempt to parse in-memory sections, because |
| 349 | // A new path for loading Info needs to be created which will only attempt to parse in-memory sections, because |
| 350 | 350 | // stopping to load other debug info (ie. source line info) from disk here is not required for unwinding. |
| 351 | 351 | var it = StackIterator.init(first_address, null); |
| 352 | 352 | defer it.deinit(); |
| ... | ... | @@ -524,7 +524,7 @@ pub fn writeStackTrace( |
| 524 | 524 | stack_trace: std.builtin.StackTrace, |
| 525 | 525 | out_stream: anytype, |
| 526 | 526 | allocator: mem.Allocator, |
| 527 | | debug_info: *DebugInfo, |
| 527 | debug_info: *Info, |
| 528 | 528 | tty_config: io.tty.Config, |
| 529 | 529 | ) !void { |
| 530 | 530 | _ = allocator; |
| ... | ... | @@ -561,11 +561,11 @@ pub const StackIterator = struct { |
| 561 | 561 | fp: usize, |
| 562 | 562 | ma: MemoryAccessor = MemoryAccessor.init, |
| 563 | 563 | |
| 564 | | // When DebugInfo and a register context is available, this iterator can unwind |
| 564 | // When Info and a register context is available, this iterator can unwind |
| 565 | 565 | // stacks with frames that don't use a frame pointer (ie. -fomit-frame-pointer), |
| 566 | 566 | // using DWARF and MachO unwind info. |
| 567 | 567 | unwind_state: if (have_ucontext) ?struct { |
| 568 | | debug_info: *DebugInfo, |
| 568 | debug_info: *Info, |
| 569 | 569 | dwarf_context: DW.UnwindContext, |
| 570 | 570 | last_error: ?UnwindError = null, |
| 571 | 571 | failed: bool = false, |
| ... | ... | @@ -590,7 +590,7 @@ pub const StackIterator = struct { |
| 590 | 590 | }; |
| 591 | 591 | } |
| 592 | 592 | |
| 593 | | pub fn initWithContext(first_address: ?usize, debug_info: *DebugInfo, context: *const posix.ucontext_t) !StackIterator { |
| 593 | pub fn initWithContext(first_address: ?usize, debug_info: *Info, context: *const posix.ucontext_t) !StackIterator { |
| 594 | 594 | // The implementation of DWARF unwinding on aarch64-macos is not complete. However, Apple mandates that |
| 595 | 595 | // the frame pointer register is always used, so on this platform we can safely use the FP-based unwinder. |
| 596 | 596 | if (comptime builtin.target.isDarwin() and native_arch == .aarch64) { |
| ... | ... | @@ -850,7 +850,7 @@ const have_msync = switch (native_os) { |
| 850 | 850 | |
| 851 | 851 | pub fn writeCurrentStackTrace( |
| 852 | 852 | out_stream: anytype, |
| 853 | | debug_info: *DebugInfo, |
| 853 | debug_info: *Info, |
| 854 | 854 | tty_config: io.tty.Config, |
| 855 | 855 | start_addr: ?usize, |
| 856 | 856 | ) !void { |
| ... | ... | @@ -936,7 +936,7 @@ pub noinline fn walkStackWindows(addresses: []usize, existing_context: ?*const w |
| 936 | 936 | |
| 937 | 937 | pub fn writeStackTraceWindows( |
| 938 | 938 | out_stream: anytype, |
| 939 | | debug_info: *DebugInfo, |
| 939 | debug_info: *Info, |
| 940 | 940 | tty_config: io.tty.Config, |
| 941 | 941 | context: *const windows.CONTEXT, |
| 942 | 942 | start_addr: ?usize, |
| ... | ... | @@ -1000,7 +1000,7 @@ test machoSearchSymbols { |
| 1000 | 1000 | try testing.expectEqual(&symbols[2], machoSearchSymbols(&symbols, 5000).?); |
| 1001 | 1001 | } |
| 1002 | 1002 | |
| 1003 | | fn printUnknownSource(debug_info: *DebugInfo, out_stream: anytype, address: usize, tty_config: io.tty.Config) !void { |
| 1003 | fn printUnknownSource(debug_info: *Info, out_stream: anytype, address: usize, tty_config: io.tty.Config) !void { |
| 1004 | 1004 | const module_name = debug_info.getModuleNameForAddress(address); |
| 1005 | 1005 | return printLineInfo( |
| 1006 | 1006 | out_stream, |
| ... | ... | @@ -1013,14 +1013,14 @@ fn printUnknownSource(debug_info: *DebugInfo, out_stream: anytype, address: usiz |
| 1013 | 1013 | ); |
| 1014 | 1014 | } |
| 1015 | 1015 | |
| 1016 | | fn printLastUnwindError(it: *StackIterator, debug_info: *DebugInfo, out_stream: anytype, tty_config: io.tty.Config) void { |
| 1016 | fn printLastUnwindError(it: *StackIterator, debug_info: *Info, out_stream: anytype, tty_config: io.tty.Config) void { |
| 1017 | 1017 | if (!have_ucontext) return; |
| 1018 | 1018 | if (it.getLastError()) |unwind_error| { |
| 1019 | 1019 | printUnwindError(debug_info, out_stream, unwind_error.address, unwind_error.err, tty_config) catch {}; |
| 1020 | 1020 | } |
| 1021 | 1021 | } |
| 1022 | 1022 | |
| 1023 | | fn printUnwindError(debug_info: *DebugInfo, out_stream: anytype, address: usize, err: UnwindError, tty_config: io.tty.Config) !void { |
| 1023 | fn printUnwindError(debug_info: *Info, out_stream: anytype, address: usize, err: UnwindError, tty_config: io.tty.Config) !void { |
| 1024 | 1024 | const module_name = debug_info.getModuleNameForAddress(address) orelse "???"; |
| 1025 | 1025 | try tty_config.setColor(out_stream, .dim); |
| 1026 | 1026 | if (err == error.MissingDebugInfo) { |
| ... | ... | @@ -1031,7 +1031,7 @@ fn printUnwindError(debug_info: *DebugInfo, out_stream: anytype, address: usize, |
| 1031 | 1031 | try tty_config.setColor(out_stream, .reset); |
| 1032 | 1032 | } |
| 1033 | 1033 | |
| 1034 | | pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: anytype, address: usize, tty_config: io.tty.Config) !void { |
| 1034 | pub fn printSourceAtAddress(debug_info: *Info, out_stream: anytype, address: usize, tty_config: io.tty.Config) !void { |
| 1035 | 1035 | const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { |
| 1036 | 1036 | error.MissingDebugInfo, error.InvalidDebugInfo => return printUnknownSource(debug_info, out_stream, address, tty_config), |
| 1037 | 1037 | else => return err, |
| ... | ... | @@ -1105,9 +1105,9 @@ fn printLineInfo( |
| 1105 | 1105 | pub const OpenSelfDebugInfoError = error{ |
| 1106 | 1106 | MissingDebugInfo, |
| 1107 | 1107 | UnsupportedOperatingSystem, |
| 1108 | | } || @typeInfo(@typeInfo(@TypeOf(DebugInfo.init)).Fn.return_type.?).ErrorUnion.error_set; |
| 1108 | } || @typeInfo(@typeInfo(@TypeOf(Info.init)).Fn.return_type.?).ErrorUnion.error_set; |
| 1109 | 1109 | |
| 1110 | | pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugInfo { |
| 1110 | pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!Info { |
| 1111 | 1111 | nosuspend { |
| 1112 | 1112 | if (builtin.strip_debug_info) |
| 1113 | 1113 | return error.MissingDebugInfo; |
| ... | ... | @@ -1124,7 +1124,7 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugI |
| 1124 | 1124 | .solaris, |
| 1125 | 1125 | .illumos, |
| 1126 | 1126 | .windows, |
| 1127 | | => return try DebugInfo.init(allocator), |
| 1127 | => return try Info.init(allocator), |
| 1128 | 1128 | else => return error.UnsupportedOperatingSystem, |
| 1129 | 1129 | } |
| 1130 | 1130 | } |
| ... | ... | @@ -1759,13 +1759,13 @@ pub const WindowsModuleInfo = struct { |
| 1759 | 1759 | } = null, |
| 1760 | 1760 | }; |
| 1761 | 1761 | |
| 1762 | | pub const DebugInfo = struct { |
| 1762 | pub const Info = struct { |
| 1763 | 1763 | allocator: mem.Allocator, |
| 1764 | 1764 | address_map: std.AutoHashMap(usize, *ModuleDebugInfo), |
| 1765 | 1765 | modules: if (native_os == .windows) std.ArrayListUnmanaged(WindowsModuleInfo) else void, |
| 1766 | 1766 | |
| 1767 | | pub fn init(allocator: mem.Allocator) !DebugInfo { |
| 1768 | | var debug_info = DebugInfo{ |
| 1767 | pub fn init(allocator: mem.Allocator) !Info { |
| 1768 | var debug_info = Info{ |
| 1769 | 1769 | .allocator = allocator, |
| 1770 | 1770 | .address_map = std.AutoHashMap(usize, *ModuleDebugInfo).init(allocator), |
| 1771 | 1771 | .modules = if (native_os == .windows) .{} else {}, |
| ... | ... | @@ -1808,7 +1808,7 @@ pub const DebugInfo = struct { |
| 1808 | 1808 | return debug_info; |
| 1809 | 1809 | } |
| 1810 | 1810 | |
| 1811 | | pub fn deinit(self: *DebugInfo) void { |
| 1811 | pub fn deinit(self: *Info) void { |
| 1812 | 1812 | var it = self.address_map.iterator(); |
| 1813 | 1813 | while (it.next()) |entry| { |
| 1814 | 1814 | const mdi = entry.value_ptr.*; |
| ... | ... | @@ -1825,7 +1825,7 @@ pub const DebugInfo = struct { |
| 1825 | 1825 | } |
| 1826 | 1826 | } |
| 1827 | 1827 | |
| 1828 | | pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 1828 | pub fn getModuleForAddress(self: *Info, address: usize) !*ModuleDebugInfo { |
| 1829 | 1829 | if (comptime builtin.target.isDarwin()) { |
| 1830 | 1830 | return self.lookupModuleDyld(address); |
| 1831 | 1831 | } else if (native_os == .windows) { |
| ... | ... | @@ -1842,7 +1842,7 @@ pub const DebugInfo = struct { |
| 1842 | 1842 | // Returns the module name for a given address. |
| 1843 | 1843 | // This can be called when getModuleForAddress fails, so implementations should provide |
| 1844 | 1844 | // a path that doesn't rely on any side-effects of a prior successful module lookup. |
| 1845 | | pub fn getModuleNameForAddress(self: *DebugInfo, address: usize) ?[]const u8 { |
| 1845 | pub fn getModuleNameForAddress(self: *Info, address: usize) ?[]const u8 { |
| 1846 | 1846 | if (comptime builtin.target.isDarwin()) { |
| 1847 | 1847 | return self.lookupModuleNameDyld(address); |
| 1848 | 1848 | } else if (native_os == .windows) { |
| ... | ... | @@ -1856,7 +1856,7 @@ pub const DebugInfo = struct { |
| 1856 | 1856 | } |
| 1857 | 1857 | } |
| 1858 | 1858 | |
| 1859 | | fn lookupModuleDyld(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 1859 | fn lookupModuleDyld(self: *Info, address: usize) !*ModuleDebugInfo { |
| 1860 | 1860 | const image_count = std.c._dyld_image_count(); |
| 1861 | 1861 | |
| 1862 | 1862 | var i: u32 = 0; |
| ... | ... | @@ -1922,7 +1922,7 @@ pub const DebugInfo = struct { |
| 1922 | 1922 | return error.MissingDebugInfo; |
| 1923 | 1923 | } |
| 1924 | 1924 | |
| 1925 | | fn lookupModuleNameDyld(self: *DebugInfo, address: usize) ?[]const u8 { |
| 1925 | fn lookupModuleNameDyld(self: *Info, address: usize) ?[]const u8 { |
| 1926 | 1926 | _ = self; |
| 1927 | 1927 | const image_count = std.c._dyld_image_count(); |
| 1928 | 1928 | |
| ... | ... | @@ -1960,7 +1960,7 @@ pub const DebugInfo = struct { |
| 1960 | 1960 | return null; |
| 1961 | 1961 | } |
| 1962 | 1962 | |
| 1963 | | fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 1963 | fn lookupModuleWin32(self: *Info, address: usize) !*ModuleDebugInfo { |
| 1964 | 1964 | for (self.modules.items) |*module| { |
| 1965 | 1965 | if (address >= module.base_address and address < module.base_address + module.size) { |
| 1966 | 1966 | if (self.address_map.get(module.base_address)) |obj_di| { |
| ... | ... | @@ -2050,7 +2050,7 @@ pub const DebugInfo = struct { |
| 2050 | 2050 | return error.MissingDebugInfo; |
| 2051 | 2051 | } |
| 2052 | 2052 | |
| 2053 | | fn lookupModuleNameWin32(self: *DebugInfo, address: usize) ?[]const u8 { |
| 2053 | fn lookupModuleNameWin32(self: *Info, address: usize) ?[]const u8 { |
| 2054 | 2054 | for (self.modules.items) |module| { |
| 2055 | 2055 | if (address >= module.base_address and address < module.base_address + module.size) { |
| 2056 | 2056 | return module.name; |
| ... | ... | @@ -2059,7 +2059,7 @@ pub const DebugInfo = struct { |
| 2059 | 2059 | return null; |
| 2060 | 2060 | } |
| 2061 | 2061 | |
| 2062 | | fn lookupModuleNameDl(self: *DebugInfo, address: usize) ?[]const u8 { |
| 2062 | fn lookupModuleNameDl(self: *Info, address: usize) ?[]const u8 { |
| 2063 | 2063 | _ = self; |
| 2064 | 2064 | |
| 2065 | 2065 | var ctx: struct { |
| ... | ... | @@ -2097,7 +2097,7 @@ pub const DebugInfo = struct { |
| 2097 | 2097 | return null; |
| 2098 | 2098 | } |
| 2099 | 2099 | |
| 2100 | | fn lookupModuleDl(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 2100 | fn lookupModuleDl(self: *Info, address: usize) !*ModuleDebugInfo { |
| 2101 | 2101 | var ctx: struct { |
| 2102 | 2102 | // Input |
| 2103 | 2103 | address: usize, |
| ... | ... | @@ -2191,13 +2191,13 @@ pub const DebugInfo = struct { |
| 2191 | 2191 | return obj_di; |
| 2192 | 2192 | } |
| 2193 | 2193 | |
| 2194 | | fn lookupModuleHaiku(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 2194 | fn lookupModuleHaiku(self: *Info, address: usize) !*ModuleDebugInfo { |
| 2195 | 2195 | _ = self; |
| 2196 | 2196 | _ = address; |
| 2197 | 2197 | @panic("TODO implement lookup module for Haiku"); |
| 2198 | 2198 | } |
| 2199 | 2199 | |
| 2200 | | fn lookupModuleWasm(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 2200 | fn lookupModuleWasm(self: *Info, address: usize) !*ModuleDebugInfo { |
| 2201 | 2201 | _ = self; |
| 2202 | 2202 | _ = address; |
| 2203 | 2203 | @panic("TODO implement lookup module for Wasm"); |