diff options
| author | LemonBoy <thatlemon@gmail.com> | 2020-02-22 12:44:21 +0100 |
|---|---|---|
| committer | LemonBoy <thatlemon@gmail.com> | 2020-02-22 12:44:21 +0100 |
| commit | 495e894225d3bb5695681be87ed0cd1b7f9825a2 (patch) | |
| tree | fba03aa09c92f65c62cb4bbf485a781e5017530b /lib/std/debug.zig | |
| parent | 41bca1ce760f415df5bc89acb0f609659e9bdad8 (diff) | |
| download | zig-495e894225d3bb5695681be87ed0cd1b7f9825a2.tar.gz zig-495e894225d3bb5695681be87ed0cd1b7f9825a2.zip | |
delete extra code, more forgiveness
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 229 |
1 files changed, 37 insertions, 192 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 6b71a14fa6..cce3cd7917 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -390,179 +390,6 @@ pub fn writeCurrentStackTraceWindows( } } -/// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented, -/// make this `noasync fn` and remove the individual noasync calls. -pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { - // if (builtin.os == .windows) { - // return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_config); - // } - return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_config); -} - -/// TODO resources https://github.com/ziglang/zig/issues/4353 -fn printSourceAtAddressWindows( - debug_info: *DebugInfo, - out_stream: var, - address: usize, - tty_config: TTY.Config, -) !void { - const allocator = debug_info.allocator; - - const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { - error.MissingDebugInfo, error.InvalidDebugInfo => { - return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs); - }, - else => return err, - }; - const relocated_address = address - module.base_address; - - var coff_section: *coff.Section = undefined; - const mod_index = for (module.sect_contribs) |sect_contrib| { - if (sect_contrib.Section > module.coff.sections.len) continue; - // Remember that SectionContribEntry.Section is 1-based. - coff_section = &module.coff.sections.toSlice()[sect_contrib.Section - 1]; - - const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset; - const vaddr_end = vaddr_start + sect_contrib.Size; - if (relocated_address >= vaddr_start and relocated_address < vaddr_end) { - break sect_contrib.ModuleIndex; - } - } else { - // we have no information to add to the address - return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs); - }; - - const mod = &module.modules[mod_index]; - try populateModule(module, mod); - const obj_basename = fs.path.basename(mod.obj_file_name); - - var symbol_i: usize = 0; - const symbol_name = if (!mod.populated) "???" else while (symbol_i != mod.symbols.len) { - const prefix = @ptrCast(*pdb.RecordPrefix, &mod.symbols[symbol_i]); - if (prefix.RecordLen < 2) - return error.InvalidDebugInfo; - switch (prefix.RecordKind) { - .S_LPROC32, .S_GPROC32 => { - const proc_sym = @ptrCast(*pdb.ProcSym, &mod.symbols[symbol_i + @sizeOf(pdb.RecordPrefix)]); - const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset; - const vaddr_end = vaddr_start + proc_sym.CodeSize; - if (relocated_address >= vaddr_start and relocated_address < vaddr_end) { - break mem.toSliceConst(u8, @ptrCast([*:0]u8, proc_sym) + @sizeOf(pdb.ProcSym)); - } - }, - else => {}, - } - symbol_i += prefix.RecordLen + @sizeOf(u16); - if (symbol_i > mod.symbols.len) - return error.InvalidDebugInfo; - } else "???"; - - const subsect_info = mod.subsect_info; - - var sect_offset: usize = 0; - var skip_len: usize = undefined; - const opt_line_info = subsections: { - const checksum_offset = mod.checksum_offset orelse break :subsections null; - while (sect_offset != subsect_info.len) : (sect_offset += skip_len) { - const subsect_hdr = @ptrCast(*pdb.DebugSubsectionHeader, &subsect_info[sect_offset]); - skip_len = subsect_hdr.Length; - sect_offset += @sizeOf(pdb.DebugSubsectionHeader); - - switch (subsect_hdr.Kind) { - pdb.DebugSubsectionKind.Lines => { - var line_index = sect_offset; - - const line_hdr = @ptrCast(*pdb.LineFragmentHeader, &subsect_info[line_index]); - if (line_hdr.RelocSegment == 0) return error.MissingDebugInfo; - line_index += @sizeOf(pdb.LineFragmentHeader); - const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset; - const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize; - - if (relocated_address >= frag_vaddr_start and relocated_address < frag_vaddr_end) { - // There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records) - // from now on. We will iterate through them, and eventually find a LineInfo that we're interested in, - // breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection. - const subsection_end_index = sect_offset + subsect_hdr.Length; - - while (line_index < subsection_end_index) { - const block_hdr = @ptrCast(*pdb.LineBlockFragmentHeader, &subsect_info[line_index]); - line_index += @sizeOf(pdb.LineBlockFragmentHeader); - const start_line_index = line_index; - - const has_column = line_hdr.Flags.LF_HaveColumns; - - // All line entries are stored inside their line block by ascending start address. - // Heuristic: we want to find the last line entry - // that has a vaddr_start <= relocated_address. - // This is done with a simple linear search. - var line_i: u32 = 0; - while (line_i < block_hdr.NumLines) : (line_i += 1) { - const line_num_entry = @ptrCast(*pdb.LineNumberEntry, &subsect_info[line_index]); - line_index += @sizeOf(pdb.LineNumberEntry); - - const vaddr_start = frag_vaddr_start + line_num_entry.Offset; - if (relocated_address < vaddr_start) { - break; - } - } - - // line_i == 0 would mean that no matching LineNumberEntry was found. - if (line_i > 0) { - const subsect_index = checksum_offset + block_hdr.NameIndex; - const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[subsect_index]); - const strtab_offset = @sizeOf(pdb.PDBStringTableHeader) + chksum_hdr.FileNameOffset; - try module.pdb.string_table.seekTo(strtab_offset); - const source_file_name = try module.pdb.string_table.readNullTermString(allocator); - - const line_entry_idx = line_i - 1; - - const column = if (has_column) blk: { - const start_col_index = start_line_index + @sizeOf(pdb.LineNumberEntry) * block_hdr.NumLines; - const col_index = start_col_index + @sizeOf(pdb.ColumnNumberEntry) * line_entry_idx; - const col_num_entry = @ptrCast(*pdb.ColumnNumberEntry, &subsect_info[col_index]); - break :blk col_num_entry.StartColumn; - } else 0; - - const found_line_index = start_line_index + line_entry_idx * @sizeOf(pdb.LineNumberEntry); - const line_num_entry = @ptrCast(*pdb.LineNumberEntry, &subsect_info[found_line_index]); - const flags = @ptrCast(*pdb.LineNumberEntry.Flags, &line_num_entry.Flags); - - break :subsections LineInfo{ - .allocator = allocator, - .file_name = source_file_name, - .line = flags.Start, - .column = column, - }; - } - } - - // Checking that we are not reading garbage after the (possibly) multiple block fragments. - if (line_index != subsection_end_index) { - return error.InvalidDebugInfo; - } - } - }, - else => {}, - } - - if (sect_offset > subsect_info.len) - return error.InvalidDebugInfo; - } else { - break :subsections null; - } - }; - - try printLineInfo( - out_stream, - opt_line_info, - relocated_address, - symbol_name, - obj_basename, - tty_config, - printLineFromFileAnyOs, - ); -} - pub const TTY = struct { pub const Color = enum { Red, @@ -698,23 +525,32 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach return null; } -pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { +/// TODO resources https://github.com/ziglang/zig/issues/4353 +pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { const module = debug_info.getModuleForAddress(address) catch |err| switch (err) { error.MissingDebugInfo, error.InvalidDebugInfo => { - return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs); + return printLineInfo( + out_stream, + null, + address, + "???", + "???", + tty_config, + printLineFromFileAnyOs, + ); }, else => return err, }; - const info = try module.getSymbolAtAddress(address); - defer info.deinit(); + const symbol_info = try module.getSymbolAtAddress(address); + defer symbol_info.deinit(); return printLineInfo( out_stream, - info.line_info, + symbol_info.line_info, address, - info.symbol_name, - info.compile_unit_name, + symbol_info.symbol_name, + symbol_info.compile_unit_name, tty_config, printLineFromFileAnyOs, ); @@ -972,7 +808,7 @@ fn chopSlice(ptr: []const u8, offset: u64, size: u64) ![]const u8 { /// TODO resources https://github.com/ziglang/zig/issues/4353 pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !ModuleDebugInfo { - const mapped_mem = mapWholeFile(elf_file_path) catch |_| return error.InvalidDebugInfo; + const mapped_mem = try mapWholeFile(elf_file_path); var seekable_stream = io.SliceSeekableInStream.init(mapped_mem); var efile = try elf.Elf.openStream( @@ -1015,7 +851,7 @@ pub fn openElfDebugInfo(allocator: *mem.Allocator, elf_file_path: []const u8) !M /// TODO resources https://github.com/ziglang/zig/issues/4353 fn openMachODebugInfo(allocator: *mem.Allocator, macho_file_path: []const u8) !ModuleDebugInfo { - const mapped_mem = mapWholeFile(macho_file_path) catch |_| return error.InvalidDebugInfo; + const mapped_mem = try mapWholeFile(macho_file_path); const hdr = @ptrCast( *const macho.mach_header_64, @@ -1228,12 +1064,15 @@ pub const DebugInfo = struct { const obj_di = try self.allocator.create(ModuleDebugInfo); errdefer self.allocator.destroy(obj_di); - try self.address_map.putNoClobber(base_address, obj_di); - const macho_path = mem.toSliceConst(u8, std.c._dyld_get_image_name(i)); - obj_di.* = try openMachODebugInfo(self.allocator, macho_path); + obj_di.* = openMachODebugInfo(self.allocator, macho_path) catch |err| switch (err) { + error.FileNotFound => return error.MissingDebugInfo, + else => return err, + }; obj_di.base_address = base_address; + try self.address_map.putNoClobber(base_address, obj_di); + return obj_di; } } @@ -1307,11 +1146,14 @@ pub const DebugInfo = struct { const obj_di = try self.allocator.create(ModuleDebugInfo); errdefer self.allocator.destroy(obj_di); - try self.address_map.putNoClobber(seg_start, obj_di); - - obj_di.* = try openCoffDebugInfo(self.allocator, name_buffer[0..:0]); + obj_di.* = openCoffDebugInfo(self.allocator, name_buffer[0..:0]) catch |err| switch (err) { + error.FileNotFound => return error.MissingDebugInfo, + else => return err, + }; obj_di.base_address = seg_start; + try self.address_map.putNoClobber(seg_start, obj_di); + return obj_di; } } @@ -1376,11 +1218,14 @@ pub const DebugInfo = struct { const obj_di = try self.allocator.create(ModuleDebugInfo); errdefer self.allocator.destroy(obj_di); - try self.address_map.putNoClobber(ctx.base_address, obj_di); - - obj_di.* = try openElfDebugInfo(self.allocator, elf_path); + obj_di.* = openElfDebugInfo(self.allocator, elf_path) catch |err| switch (err) { + error.FileNotFound => return error.MissingDebugInfo, + else => return err, + }; obj_di.base_address = ctx.base_address; + try self.address_map.putNoClobber(ctx.base_address, obj_di); + return obj_di; } }; @@ -1412,7 +1257,7 @@ pub const ModuleDebugInfo = switch (builtin.os) { } fn loadOFile(self: *@This(), o_file_path: []const u8) !DW.DwarfInfo { - const mapped_mem = mapWholeFile(o_file_path) catch |_| return error.InvalidDebugInfo; + const mapped_mem = try mapWholeFile(o_file_path); const hdr = @ptrCast( *const macho.mach_header_64, |
