| ... | @@ -46,20 +46,30 @@ pub fn getSymbols( | ... | @@ -46,20 +46,30 @@ pub fn getSymbols( |
| 46 | const vaddr = address - module.load_offset; | 46 | const vaddr = address - module.load_offset; |
| 47 | | 47 | |
| 48 | const loaded_elf = try module.getLoadedElf(gpa, io); | 48 | const loaded_elf = try module.getLoadedElf(gpa, io); |
| 49 | if (loaded_elf.file.dwarf) |*dwarf| { | 49 | const dwarf_err: ?Error = err: { |
| 50 | if (!loaded_elf.scanned_dwarf) { | 50 | const dwarf = &(loaded_elf.file.dwarf orelse break :err null); |
| 51 | dwarf.open(gpa, native_endian) catch |err| switch (err) { | 51 | switch (loaded_elf.dwarf) { |
| | 52 | .not_scanned => if (dwarf.open(gpa, native_endian)) { |
| | 53 | loaded_elf.dwarf = .ok; |
| | 54 | } else |err| switch (err) { |
| 52 | error.InvalidDebugInfo, | 55 | error.InvalidDebugInfo, |
| 53 | error.MissingDebugInfo, | | |
| 54 | error.OutOfMemory, | | |
| 55 | => |e| return e, | | |
| 56 | error.EndOfStream, | 56 | error.EndOfStream, |
| 57 | error.Overflow, | 57 | error.Overflow, |
| 58 | error.ReadFailed, | 58 | error.ReadFailed, |
| 59 | error.StreamTooLong, | 59 | error.StreamTooLong, |
| 60 | => return error.InvalidDebugInfo, | 60 | => { |
| 61 | }; | 61 | loaded_elf.dwarf = .invalid; |
| 62 | loaded_elf.scanned_dwarf = true; | 62 | break :err error.InvalidDebugInfo; |
| | 63 | }, |
| | 64 | error.MissingDebugInfo => { |
| | 65 | loaded_elf.dwarf = .missing; |
| | 66 | break :err error.MissingDebugInfo; |
| | 67 | }, |
| | 68 | error.OutOfMemory => |e| return e, |
| | 69 | }, |
| | 70 | .invalid => break :err error.InvalidDebugInfo, |
| | 71 | .missing => break :err error.MissingDebugInfo, |
| | 72 | .ok => {}, |
| 63 | } | 73 | } |
| 64 | return dwarf.getSymbols( | 74 | return dwarf.getSymbols( |
| 65 | symbol_allocator, | 75 | symbol_allocator, |
| ... | @@ -68,14 +78,27 @@ pub fn getSymbols( | ... | @@ -68,14 +78,27 @@ pub fn getSymbols( |
| 68 | vaddr, | 78 | vaddr, |
| 69 | resolve_inline_callers, | 79 | resolve_inline_callers, |
| 70 | symbols, | 80 | symbols, |
| 71 | ); | 81 | ) catch |err| switch (err) { |
| 72 | } | 82 | error.InvalidDebugInfo, |
| | 83 | error.MissingDebugInfo, |
| | 84 | error.UnsupportedDebugInfo, |
| | 85 | => |e| break :err e, |
| | 86 | |
| | 87 | error.ReadFailed, |
| | 88 | error.OutOfMemory, |
| | 89 | error.Canceled, |
| | 90 | error.Unexpected, |
| | 91 | => |e| return e, |
| | 92 | }; |
| | 93 | }; |
| 73 | // When DWARF is unavailable, fall back to searching the symtab. | 94 | // When DWARF is unavailable, fall back to searching the symtab. |
| 74 | try symbols.append(symbol_allocator, loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { | 95 | try symbols.append(symbol_allocator, loaded_elf.file.searchSymtab(gpa, vaddr) catch |err| switch (err) { |
| 75 | error.NoSymtab, error.NoStrtab => return error.MissingDebugInfo, | 96 | error.NoSymtab, error.NoStrtab => return error.MissingDebugInfo, |
| 76 | error.BadSymtab => return error.InvalidDebugInfo, | 97 | error.BadSymtab => return error.InvalidDebugInfo, |
| 77 | error.OutOfMemory => |e| return e, | 98 | error.OutOfMemory => |e| return e, |
| 78 | }); | 99 | }); |
| | 100 | // After searching the symtab, still report the DWARF error. |
| | 101 | if (dwarf_err) |e| return e; |
| 79 | } | 102 | } |
| 80 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { | 103 | pub fn getModuleName(si: *SelfInfo, io: Io, address: usize) Error![]const u8 { |
| 81 | const gpa = std.debug.getDebugInfoAllocator(); | 104 | const gpa = std.debug.getDebugInfoAllocator(); |
| ... | @@ -251,7 +274,7 @@ const Module = struct { | ... | @@ -251,7 +274,7 @@ const Module = struct { |
| 251 | | 274 | |
| 252 | const LoadedElf = struct { | 275 | const LoadedElf = struct { |
| 253 | file: std.debug.ElfFile, | 276 | file: std.debug.ElfFile, |
| 254 | scanned_dwarf: bool, | 277 | dwarf: enum { not_scanned, invalid, missing, ok }, |
| 255 | }; | 278 | }; |
| 256 | | 279 | |
| 257 | const UnwindSections = struct { | 280 | const UnwindSections = struct { |
| ... | @@ -377,7 +400,7 @@ const Module = struct { | ... | @@ -377,7 +400,7 @@ const Module = struct { |
| 377 | | 400 | |
| 378 | return .{ | 401 | return .{ |
| 379 | .file = elf_file, | 402 | .file = elf_file, |
| 380 | .scanned_dwarf = false, | 403 | .dwarf = .not_scanned, |
| 381 | }; | 404 | }; |
| 382 | } | 405 | } |
| 383 | }; | 406 | }; |