authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 20:48:54+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-20 20:48:54+01:00
loga4d0d7f1de78a6d0b4993baeca0b8aa636ba9f33
tree0d2614d4bc032671de1e5564204a4582f5b8a081
parent342a2749487d9952cf2afd6f8fb3e9534d4a210a

soldier on


1 files changed, 72 insertions(+), 59 deletions(-)

lib/std/debug.zig+72-59
......@@ -404,26 +404,30 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: us
404404
405405/// TODO resources https://github.com/ziglang/zig/issues/4353
406406fn printSourceAtAddressWindows(
407 di1: *DebugInfo,
407 debug_info: *DebugInfo,
408408 out_stream: var,
409 relocated_address: usize,
409 address: usize,
410410 tty_config: TTY.Config,
411411) !void {
412 const di = try di1.lookupByAddress(relocated_address);
412 const allocator = debug_info.allocator;
413413
414 const allocator = getDebugInfoAllocator();
415 const base_address = di.base_address;
416 const relative_address = relocated_address - base_address;
414 const module = debug_info.lookupByAddress(address) catch |err| switch (err) {
415 error.MissingDebugInfo, error.InvalidDebugInfo => {
416 return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);
417 },
418 else => return err,
419 };
420 const relocated_address = address - module.base_address;
417421
418422 var coff_section: *coff.Section = undefined;
419 const mod_index = for (di.sect_contribs) |sect_contrib| {
420 if (sect_contrib.Section > di.coff.sections.len) continue;
423 const mod_index = for (module.sect_contribs) |sect_contrib| {
424 if (sect_contrib.Section > module.coff.sections.len) continue;
421425 // Remember that SectionContribEntry.Section is 1-based.
422 coff_section = &di.coff.sections.toSlice()[sect_contrib.Section - 1];
426 coff_section = &module.coff.sections.toSlice()[sect_contrib.Section - 1];
423427
424428 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
425429 const vaddr_end = vaddr_start + sect_contrib.Size;
426 if (relative_address >= vaddr_start and relative_address < vaddr_end) {
430 if (relocated_address >= vaddr_start and relocated_address < vaddr_end) {
427431 break sect_contrib.ModuleIndex;
428432 }
429433 } else {
......@@ -431,8 +435,8 @@ fn printSourceAtAddressWindows(
431435 return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs);
432436 };
433437
434 const mod = &di.modules[mod_index];
435 try populateModule(di, mod);
438 const mod = &module.modules[mod_index];
439 try populateModule(module, mod);
436440 const obj_basename = fs.path.basename(mod.obj_file_name);
437441
438442 var symbol_i: usize = 0;
......@@ -445,7 +449,7 @@ fn printSourceAtAddressWindows(
445449 const proc_sym = @ptrCast(*pdb.ProcSym, &mod.symbols[symbol_i + @sizeOf(pdb.RecordPrefix)]);
446450 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;
447451 const vaddr_end = vaddr_start + proc_sym.CodeSize;
448 if (relative_address >= vaddr_start and relative_address < vaddr_end) {
452 if (relocated_address >= vaddr_start and relocated_address < vaddr_end) {
449453 break mem.toSliceConst(u8, @ptrCast([*:0]u8, proc_sym) + @sizeOf(pdb.ProcSym));
450454 }
451455 },
......@@ -477,7 +481,7 @@ fn printSourceAtAddressWindows(
477481 const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;
478482 const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize;
479483
480 if (relative_address >= frag_vaddr_start and relative_address < frag_vaddr_end) {
484 if (relocated_address >= frag_vaddr_start and relocated_address < frag_vaddr_end) {
481485 // There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)
482486 // from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,
483487 // breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
......@@ -491,7 +495,8 @@ fn printSourceAtAddressWindows(
491495 const has_column = line_hdr.Flags.LF_HaveColumns;
492496
493497 // All line entries are stored inside their line block by ascending start address.
494 // Heuristic: we want to find the last line entry that has a vaddr_start <= relative_address.
498 // Heuristic: we want to find the last line entry
499 // that has a vaddr_start <= relocated_address.
495500 // This is done with a simple linear search.
496501 var line_i: u32 = 0;
497502 while (line_i < block_hdr.NumLines) : (line_i += 1) {
......@@ -499,7 +504,7 @@ fn printSourceAtAddressWindows(
499504 line_index += @sizeOf(pdb.LineNumberEntry);
500505
501506 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;
502 if (relative_address < vaddr_start) {
507 if (relocated_address < vaddr_start) {
503508 break;
504509 }
505510 }
......@@ -509,8 +514,8 @@ fn printSourceAtAddressWindows(
509514 const subsect_index = checksum_offset + block_hdr.NameIndex;
510515 const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[subsect_index]);
511516 const strtab_offset = @sizeOf(pdb.PDBStringTableHeader) + chksum_hdr.FileNameOffset;
512 try di.pdb.string_table.seekTo(strtab_offset);
513 const source_file_name = try di.pdb.string_table.readNullTermString(allocator);
517 try module.pdb.string_table.seekTo(strtab_offset);
518 const source_file_name = try module.pdb.string_table.readNullTermString(allocator);
514519
515520 const line_entry_idx = line_i - 1;
516521
......@@ -696,24 +701,28 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
696701 return null;
697702}
698703
699fn printSourceAtAddressMacOs(di1: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
700 const di = try di1.lookupByAddress(address);
704fn printSourceAtAddressMacOs(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
705 const module = debug_info.lookupByAddress(address) catch |err| switch (err) {
706 error.MissingDebugInfo, error.InvalidDebugInfo => {
707 return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);
708 },
709 else => return err,
710 };
701711
702 const base_addr = di.base_address;
703 const adjusted_addr = address - base_addr;
704 assert(adjusted_addr >= 0x100000000);
712 const relocated_address = address - module.base_address;
713 assert(relocated_address >= 0x100000000);
705714
706 const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse {
715 const symbol = machoSearchSymbols(module.symbols, relocated_address) orelse {
707716 return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);
708717 };
709718
710 const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx));
719 const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, module.strings.ptr + symbol.nlist.n_strx));
711720 const compile_unit_name = if (symbol.ofile) |ofile| blk: {
712 const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + ofile.n_strx));
721 const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, module.strings.ptr + ofile.n_strx));
713722 break :blk fs.path.basename(ofile_path);
714723 } else "???";
715724
716 const line_info = getLineNumberInfoMacOs(di, symbol.*, adjusted_addr) catch |err| switch (err) {
725 const line_info = getLineNumberInfoMacOs(module, symbol.*, relocated_address) catch |err| switch (err) {
717726 error.MissingDebugInfo, error.InvalidDebugInfo => null,
718727 else => return err,
719728 };
......@@ -731,37 +740,41 @@ fn printSourceAtAddressMacOs(di1: *DebugInfo, out_stream: var, address: usize, t
731740}
732741
733742pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
734 // XXX Print as much as possible anyway
735 const module = try debug_info.lookupByAddress(address);
736
737 const reloc_address = address - module.base_address;
738
739 if (module.dwarf.findCompileUnit(reloc_address) catch null) |compile_unit| {
740 const compile_unit_name = try compile_unit.die.getAttrString(&module.dwarf, DW.AT_name);
741 const symbol_name = module.dwarf.getSymbolName(reloc_address) orelse "???";
742 const line_info = module.dwarf.getLineNumberInfo(compile_unit.*, reloc_address) catch |err| switch (err) {
743 error.MissingDebugInfo, error.InvalidDebugInfo => null,
743 var symbol_name: []const u8 = "";
744 var compile_unit_name: []const u8 = "";
745 var line_info: ?LineInfo = null;
746
747 if (debug_info.lookupByAddress(address)) |module| {
748 // Translate the VA into an address into this object
749 const relocated_address = address - module.base_address;
750
751 if (module.dwarf.findCompileUnit(relocated_address)) |compile_unit| {
752 symbol_name = module.dwarf.getSymbolName(relocated_address) orelse "???";
753 compile_unit_name = compile_unit.die.getAttrString(&module.dwarf, DW.AT_name) catch |err| switch (err) {
754 error.MissingDebugInfo, error.InvalidDebugInfo => "???",
755 else => return err,
756 };
757 line_info = module.dwarf.getLineNumberInfo(compile_unit.*, relocated_address) catch |err| switch (err) {
758 error.MissingDebugInfo, error.InvalidDebugInfo => null,
759 else => return err,
760 };
761 } else |err| switch (err) {
762 error.MissingDebugInfo, error.InvalidDebugInfo => {},
744763 else => return err,
745 };
746 defer if (line_info) |li| li.deinit();
747
748 return printLineInfo(
749 out_stream,
750 line_info,
751 address,
752 symbol_name,
753 compile_unit_name,
754 tty_config,
755 printLineFromFileAnyOs,
756 );
764 }
765 } else |err| switch (err) {
766 error.MissingDebugInfo, error.InvalidDebugInfo => {},
767 else => return err,
757768 }
758769
770 defer if (line_info) |li| li.deinit();
771
759772 return printLineInfo(
760773 out_stream,
761 null,
774 line_info,
762775 address,
763 "???",
764 "???",
776 symbol_name,
777 compile_unit_name,
765778 tty_config,
766779 printLineFromFileAnyOs,
767780 );
......@@ -1286,7 +1299,7 @@ pub const DebugInfo = struct {
12861299 }
12871300 }
12881301
1289 return error.DebugInfoNotFound;
1302 return error.MissingDebugInfo;
12901303 }
12911304
12921305 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
......@@ -1301,7 +1314,7 @@ pub const DebugInfo = struct {
13011314 0,
13021315 &bytes_needed,
13031316 ) == 0)
1304 return error.DebugInfoNotFound;
1317 return error.MissingDebugInfo;
13051318
13061319 const needed_modules = bytes_needed / @sizeOf(windows.HMODULE);
13071320
......@@ -1314,7 +1327,7 @@ pub const DebugInfo = struct {
13141327 try math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)),
13151328 &bytes_needed,
13161329 ) == 0)
1317 return error.DebugInfoNotFound;
1330 return error.MissingDebugInfo;
13181331
13191332 // There's an unavoidable TOCTOU problem here, the module list may have
13201333 // changed between the two EnumProcessModules call.
......@@ -1330,7 +1343,7 @@ pub const DebugInfo = struct {
13301343 &info,
13311344 @sizeOf(@TypeOf(info)),
13321345 ) == 0)
1333 return error.DebugInfoNotFound;
1346 return error.MissingDebugInfo;
13341347
13351348 const seg_start = @ptrToInt(info.lpBaseOfDll);
13361349 const seg_end = seg_start + info.SizeOfImage;
......@@ -1363,7 +1376,7 @@ pub const DebugInfo = struct {
13631376 }
13641377 }
13651378
1366 return error.DebugInfoNotFound;
1379 return error.MissingDebugInfo;
13671380 }
13681381
13691382 fn lookupModuleDl(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
......@@ -1403,10 +1416,10 @@ pub const DebugInfo = struct {
14031416 }
14041417 }
14051418 }.callback)) {
1406 return error.DebugInfoNotFound;
1419 return error.MissingDebugInfo;
14071420 } else |err| switch (err) {
14081421 error.Found => {},
1409 else => return error.DebugInfoNotFound,
1422 else => return error.MissingDebugInfo,
14101423 }
14111424
14121425 if (self.address_map.getValue(ctx.base_address)) |obj_di| {