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...@@ -404,26 +404,30 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: us
404404
405/// TODO resources https://github.com/ziglang/zig/issues/4353405/// TODO resources https://github.com/ziglang/zig/issues/4353
406fn printSourceAtAddressWindows(406fn printSourceAtAddressWindows(
407 di1: *DebugInfo,407 debug_info: *DebugInfo,
408 out_stream: var,408 out_stream: var,
409 relocated_address: usize,409 address: usize,
410 tty_config: TTY.Config,410 tty_config: TTY.Config,
411) !void {411) !void {
412 const di = try di1.lookupByAddress(relocated_address);412 const allocator = debug_info.allocator;
413413
414 const allocator = getDebugInfoAllocator();414 const module = debug_info.lookupByAddress(address) catch |err| switch (err) {
415 const base_address = di.base_address;415 error.MissingDebugInfo, error.InvalidDebugInfo => {
416 const relative_address = relocated_address - base_address;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
418 var coff_section: *coff.Section = undefined;422 var coff_section: *coff.Section = undefined;
419 const mod_index = for (di.sect_contribs) |sect_contrib| {423 const mod_index = for (module.sect_contribs) |sect_contrib| {
420 if (sect_contrib.Section > di.coff.sections.len) continue;424 if (sect_contrib.Section > module.coff.sections.len) continue;
421 // Remember that SectionContribEntry.Section is 1-based.425 // 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
424 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;428 const vaddr_start = coff_section.header.virtual_address + sect_contrib.Offset;
425 const vaddr_end = vaddr_start + sect_contrib.Size;429 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) {
427 break sect_contrib.ModuleIndex;431 break sect_contrib.ModuleIndex;
428 }432 }
429 } else {433 } else {
...@@ -431,8 +435,8 @@ fn printSourceAtAddressWindows(...@@ -431,8 +435,8 @@ fn printSourceAtAddressWindows(
431 return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs);435 return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs);
432 };436 };
433437
434 const mod = &di.modules[mod_index];438 const mod = &module.modules[mod_index];
435 try populateModule(di, mod);439 try populateModule(module, mod);
436 const obj_basename = fs.path.basename(mod.obj_file_name);440 const obj_basename = fs.path.basename(mod.obj_file_name);
437441
438 var symbol_i: usize = 0;442 var symbol_i: usize = 0;
...@@ -445,7 +449,7 @@ fn printSourceAtAddressWindows(...@@ -445,7 +449,7 @@ fn printSourceAtAddressWindows(
445 const proc_sym = @ptrCast(*pdb.ProcSym, &mod.symbols[symbol_i + @sizeOf(pdb.RecordPrefix)]);449 const proc_sym = @ptrCast(*pdb.ProcSym, &mod.symbols[symbol_i + @sizeOf(pdb.RecordPrefix)]);
446 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;450 const vaddr_start = coff_section.header.virtual_address + proc_sym.CodeOffset;
447 const vaddr_end = vaddr_start + proc_sym.CodeSize;451 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) {
449 break mem.toSliceConst(u8, @ptrCast([*:0]u8, proc_sym) + @sizeOf(pdb.ProcSym));453 break mem.toSliceConst(u8, @ptrCast([*:0]u8, proc_sym) + @sizeOf(pdb.ProcSym));
450 }454 }
451 },455 },
...@@ -477,7 +481,7 @@ fn printSourceAtAddressWindows(...@@ -477,7 +481,7 @@ fn printSourceAtAddressWindows(
477 const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;481 const frag_vaddr_start = coff_section.header.virtual_address + line_hdr.RelocOffset;
478 const frag_vaddr_end = frag_vaddr_start + line_hdr.CodeSize;482 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) {
481 // There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)485 // There is an unknown number of LineBlockFragmentHeaders (and their accompanying line and column records)
482 // from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,486 // from now on. We will iterate through them, and eventually find a LineInfo that we're interested in,
483 // breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.487 // breaking out to :subsections. If not, we will make sure to not read anything outside of this subsection.
...@@ -491,7 +495,8 @@ fn printSourceAtAddressWindows(...@@ -491,7 +495,8 @@ fn printSourceAtAddressWindows(
491 const has_column = line_hdr.Flags.LF_HaveColumns;495 const has_column = line_hdr.Flags.LF_HaveColumns;
492496
493 // All line entries are stored inside their line block by ascending start address.497 // 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.
495 // This is done with a simple linear search.500 // This is done with a simple linear search.
496 var line_i: u32 = 0;501 var line_i: u32 = 0;
497 while (line_i < block_hdr.NumLines) : (line_i += 1) {502 while (line_i < block_hdr.NumLines) : (line_i += 1) {
...@@ -499,7 +504,7 @@ fn printSourceAtAddressWindows(...@@ -499,7 +504,7 @@ fn printSourceAtAddressWindows(
499 line_index += @sizeOf(pdb.LineNumberEntry);504 line_index += @sizeOf(pdb.LineNumberEntry);
500505
501 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;506 const vaddr_start = frag_vaddr_start + line_num_entry.Offset;
502 if (relative_address < vaddr_start) {507 if (relocated_address < vaddr_start) {
503 break;508 break;
504 }509 }
505 }510 }
...@@ -509,8 +514,8 @@ fn printSourceAtAddressWindows(...@@ -509,8 +514,8 @@ fn printSourceAtAddressWindows(
509 const subsect_index = checksum_offset + block_hdr.NameIndex;514 const subsect_index = checksum_offset + block_hdr.NameIndex;
510 const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[subsect_index]);515 const chksum_hdr = @ptrCast(*pdb.FileChecksumEntryHeader, &mod.subsect_info[subsect_index]);
511 const strtab_offset = @sizeOf(pdb.PDBStringTableHeader) + chksum_hdr.FileNameOffset;516 const strtab_offset = @sizeOf(pdb.PDBStringTableHeader) + chksum_hdr.FileNameOffset;
512 try di.pdb.string_table.seekTo(strtab_offset);517 try module.pdb.string_table.seekTo(strtab_offset);
513 const source_file_name = try di.pdb.string_table.readNullTermString(allocator);518 const source_file_name = try module.pdb.string_table.readNullTermString(allocator);
514519
515 const line_entry_idx = line_i - 1;520 const line_entry_idx = line_i - 1;
516521
...@@ -696,24 +701,28 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach...@@ -696,24 +701,28 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach
696 return null;701 return null;
697}702}
698703
699fn printSourceAtAddressMacOs(di1: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {704fn printSourceAtAddressMacOs(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
700 const di = try di1.lookupByAddress(address);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;712 const relocated_address = address - module.base_address;
703 const adjusted_addr = address - base_addr;713 assert(relocated_address >= 0x100000000);
704 assert(adjusted_addr >= 0x100000000);
705714
706 const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse {715 const symbol = machoSearchSymbols(module.symbols, relocated_address) orelse {
707 return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);716 return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs);
708 };717 };
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));
711 const compile_unit_name = if (symbol.ofile) |ofile| blk: {720 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));
713 break :blk fs.path.basename(ofile_path);722 break :blk fs.path.basename(ofile_path);
714 } else "???";723 } 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) {
717 error.MissingDebugInfo, error.InvalidDebugInfo => null,726 error.MissingDebugInfo, error.InvalidDebugInfo => null,
718 else => return err,727 else => return err,
719 };728 };
...@@ -731,37 +740,41 @@ fn printSourceAtAddressMacOs(di1: *DebugInfo, out_stream: var, address: usize, t...@@ -731,37 +740,41 @@ fn printSourceAtAddressMacOs(di1: *DebugInfo, out_stream: var, address: usize, t
731}740}
732741
733pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {742pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void {
734 // XXX Print as much as possible anyway743 var symbol_name: []const u8 = "";
735 const module = try debug_info.lookupByAddress(address);744 var compile_unit_name: []const u8 = "";
736745 var line_info: ?LineInfo = null;
737 const reloc_address = address - module.base_address;746
738747 if (debug_info.lookupByAddress(address)) |module| {
739 if (module.dwarf.findCompileUnit(reloc_address) catch null) |compile_unit| {748 // Translate the VA into an address into this object
740 const compile_unit_name = try compile_unit.die.getAttrString(&module.dwarf, DW.AT_name);749 const relocated_address = address - module.base_address;
741 const symbol_name = module.dwarf.getSymbolName(reloc_address) orelse "???";750
742 const line_info = module.dwarf.getLineNumberInfo(compile_unit.*, reloc_address) catch |err| switch (err) {751 if (module.dwarf.findCompileUnit(relocated_address)) |compile_unit| {
743 error.MissingDebugInfo, error.InvalidDebugInfo => null,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 => {},
744 else => return err,763 else => return err,
745 };764 }
746 defer if (line_info) |li| li.deinit();765 } else |err| switch (err) {
747766 error.MissingDebugInfo, error.InvalidDebugInfo => {},
748 return printLineInfo(767 else => return err,
749 out_stream,
750 line_info,
751 address,
752 symbol_name,
753 compile_unit_name,
754 tty_config,
755 printLineFromFileAnyOs,
756 );
757 }768 }
758769
770 defer if (line_info) |li| li.deinit();
771
759 return printLineInfo(772 return printLineInfo(
760 out_stream,773 out_stream,
761 null,774 line_info,
762 address,775 address,
763 "???",776 symbol_name,
764 "???",777 compile_unit_name,
765 tty_config,778 tty_config,
766 printLineFromFileAnyOs,779 printLineFromFileAnyOs,
767 );780 );
...@@ -1286,7 +1299,7 @@ pub const DebugInfo = struct {...@@ -1286,7 +1299,7 @@ pub const DebugInfo = struct {
1286 }1299 }
1287 }1300 }
12881301
1289 return error.DebugInfoNotFound;1302 return error.MissingDebugInfo;
1290 }1303 }
12911304
1292 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {1305 fn lookupModuleWin32(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
...@@ -1301,7 +1314,7 @@ pub const DebugInfo = struct {...@@ -1301,7 +1314,7 @@ pub const DebugInfo = struct {
1301 0,1314 0,
1302 &bytes_needed,1315 &bytes_needed,
1303 ) == 0)1316 ) == 0)
1304 return error.DebugInfoNotFound;1317 return error.MissingDebugInfo;
13051318
1306 const needed_modules = bytes_needed / @sizeOf(windows.HMODULE);1319 const needed_modules = bytes_needed / @sizeOf(windows.HMODULE);
13071320
...@@ -1314,7 +1327,7 @@ pub const DebugInfo = struct {...@@ -1314,7 +1327,7 @@ pub const DebugInfo = struct {
1314 try math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)),1327 try math.cast(windows.DWORD, modules.len * @sizeOf(windows.HMODULE)),
1315 &bytes_needed,1328 &bytes_needed,
1316 ) == 0)1329 ) == 0)
1317 return error.DebugInfoNotFound;1330 return error.MissingDebugInfo;
13181331
1319 // There's an unavoidable TOCTOU problem here, the module list may have1332 // There's an unavoidable TOCTOU problem here, the module list may have
1320 // changed between the two EnumProcessModules call.1333 // changed between the two EnumProcessModules call.
...@@ -1330,7 +1343,7 @@ pub const DebugInfo = struct {...@@ -1330,7 +1343,7 @@ pub const DebugInfo = struct {
1330 &info,1343 &info,
1331 @sizeOf(@TypeOf(info)),1344 @sizeOf(@TypeOf(info)),
1332 ) == 0)1345 ) == 0)
1333 return error.DebugInfoNotFound;1346 return error.MissingDebugInfo;
13341347
1335 const seg_start = @ptrToInt(info.lpBaseOfDll);1348 const seg_start = @ptrToInt(info.lpBaseOfDll);
1336 const seg_end = seg_start + info.SizeOfImage;1349 const seg_end = seg_start + info.SizeOfImage;
...@@ -1363,7 +1376,7 @@ pub const DebugInfo = struct {...@@ -1363,7 +1376,7 @@ pub const DebugInfo = struct {
1363 }1376 }
1364 }1377 }
13651378
1366 return error.DebugInfoNotFound;1379 return error.MissingDebugInfo;
1367 }1380 }
13681381
1369 fn lookupModuleDl(self: *DebugInfo, address: usize) !*ObjectDebugInfo {1382 fn lookupModuleDl(self: *DebugInfo, address: usize) !*ObjectDebugInfo {
...@@ -1403,10 +1416,10 @@ pub const DebugInfo = struct {...@@ -1403,10 +1416,10 @@ pub const DebugInfo = struct {
1403 }1416 }
1404 }1417 }
1405 }.callback)) {1418 }.callback)) {
1406 return error.DebugInfoNotFound;1419 return error.MissingDebugInfo;
1407 } else |err| switch (err) {1420 } else |err| switch (err) {
1408 error.Found => {},1421 error.Found => {},
1409 else => return error.DebugInfoNotFound,1422 else => return error.MissingDebugInfo,
1410 }1423 }
14111424
1412 if (self.address_map.getValue(ctx.base_address)) |obj_di| {1425 if (self.address_map.getValue(ctx.base_address)) |obj_di| {