| ... | @@ -379,16 +379,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres | ... | @@ -379,16 +379,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres |
| 379 | } | 379 | } |
| 380 | } else { | 380 | } else { |
| 381 | // we have no information to add to the address | 381 | // we have no information to add to the address |
| 382 | if (tty_color) { | 382 | return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_color, printLineFromFileAnyOs); |
| 383 | try out_stream.print("???:?:?: ", .{}); | | |
| 384 | setTtyColor(TtyColor.Dim); | | |
| 385 | try out_stream.print("0x{x} in ??? (???)", .{relocated_address}); | | |
| 386 | setTtyColor(TtyColor.Reset); | | |
| 387 | try out_stream.print("\n\n\n", .{}); | | |
| 388 | } else { | | |
| 389 | try out_stream.print("???:?:?: 0x{x} in ??? (???)\n\n\n", .{relocated_address}); | | |
| 390 | } | | |
| 391 | return; | | |
| 392 | }; | 383 | }; |
| 393 | | 384 | |
| 394 | const mod = &di.modules[mod_index]; | 385 | const mod = &di.modules[mod_index]; |
| ... | @@ -510,66 +501,15 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres | ... | @@ -510,66 +501,15 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres |
| 510 | } | 501 | } |
| 511 | }; | 502 | }; |
| 512 | | 503 | |
| 513 | if (tty_color) { | 504 | try printLineInfo( |
| 514 | setTtyColor(TtyColor.White); | 505 | out_stream, |
| 515 | if (opt_line_info) |li| { | 506 | opt_line_info, |
| 516 | try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column }); | 507 | relocated_address, |
| 517 | } else { | 508 | symbol_name, |
| 518 | try out_stream.print("???:?:?", .{}); | 509 | obj_basename, |
| 519 | } | 510 | tty_color, |
| 520 | setTtyColor(TtyColor.Reset); | 511 | printLineFromFileAnyOs, |
| 521 | try out_stream.print(": ", .{}); | 512 | ); |
| 522 | setTtyColor(TtyColor.Dim); | | |
| 523 | try out_stream.print("0x{x} in {} ({})", .{ relocated_address, symbol_name, obj_basename }); | | |
| 524 | setTtyColor(TtyColor.Reset); | | |
| 525 | | | |
| 526 | if (opt_line_info) |line_info| { | | |
| 527 | try out_stream.print("\n", .{}); | | |
| 528 | if (printLineFromFileAnyOs(out_stream, line_info)) { | | |
| 529 | if (line_info.column == 0) { | | |
| 530 | try out_stream.write("\n"); | | |
| 531 | } else { | | |
| 532 | { | | |
| 533 | var col_i: usize = 1; | | |
| 534 | while (col_i < line_info.column) : (col_i += 1) { | | |
| 535 | try out_stream.writeByte(' '); | | |
| 536 | } | | |
| 537 | } | | |
| 538 | setTtyColor(TtyColor.Green); | | |
| 539 | try out_stream.write("^"); | | |
| 540 | setTtyColor(TtyColor.Reset); | | |
| 541 | try out_stream.write("\n"); | | |
| 542 | } | | |
| 543 | } else |err| switch (err) { | | |
| 544 | error.EndOfFile => {}, | | |
| 545 | error.FileNotFound => { | | |
| 546 | setTtyColor(TtyColor.Dim); | | |
| 547 | try out_stream.write("file not found\n\n"); | | |
| 548 | setTtyColor(TtyColor.White); | | |
| 549 | }, | | |
| 550 | else => return err, | | |
| 551 | } | | |
| 552 | } else { | | |
| 553 | try out_stream.print("\n\n\n", .{}); | | |
| 554 | } | | |
| 555 | } else { | | |
| 556 | if (opt_line_info) |li| { | | |
| 557 | try out_stream.print("{}:{}:{}: 0x{x} in {} ({})\n\n\n", .{ | | |
| 558 | li.file_name, | | |
| 559 | li.line, | | |
| 560 | li.column, | | |
| 561 | relocated_address, | | |
| 562 | symbol_name, | | |
| 563 | obj_basename, | | |
| 564 | }); | | |
| 565 | } else { | | |
| 566 | try out_stream.print("???:?:?: 0x{x} in {} ({})\n\n\n", .{ | | |
| 567 | relocated_address, | | |
| 568 | symbol_name, | | |
| 569 | obj_basename, | | |
| 570 | }); | | |
| 571 | } | | |
| 572 | } | | |
| 573 | } | 513 | } |
| 574 | | 514 | |
| 575 | const TtyColor = enum { | 515 | const TtyColor = enum { |
| ... | @@ -605,7 +545,11 @@ fn setTtyColor(tty_color: TtyColor) void { | ... | @@ -605,7 +545,11 @@ fn setTtyColor(tty_color: TtyColor) void { |
| 605 | stderr_file.write(RESET) catch return; | 545 | stderr_file.write(RESET) catch return; |
| 606 | }, | 546 | }, |
| 607 | } | 547 | } |
| 608 | } else { | 548 | |
| | 549 | return; |
| | 550 | } |
| | 551 | |
| | 552 | if (builtin.os == .windows) { |
| 609 | const S = struct { | 553 | const S = struct { |
| 610 | var attrs: windows.WORD = undefined; | 554 | var attrs: windows.WORD = undefined; |
| 611 | var init_attrs = false; | 555 | var init_attrs = false; |
| ... | @@ -711,12 +655,7 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt | ... | @@ -711,12 +655,7 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt |
| 711 | const adjusted_addr = 0x100000000 + (address - base_addr); | 655 | const adjusted_addr = 0x100000000 + (address - base_addr); |
| 712 | | 656 | |
| 713 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { | 657 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { |
| 714 | if (tty_color) { | 658 | return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFileAnyOs); |
| 715 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n\n\n", .{address}); | | |
| 716 | } else { | | |
| 717 | try out_stream.print("???:?:?: 0x{x} in ??? (???)\n\n\n", .{address}); | | |
| 718 | } | | |
| 719 | return; | | |
| 720 | }; | 659 | }; |
| 721 | | 660 | |
| 722 | const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx)); | 661 | const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx)); |
| ... | @@ -724,29 +663,22 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt | ... | @@ -724,29 +663,22 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt |
| 724 | const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + ofile.n_strx)); | 663 | const ofile_path = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + ofile.n_strx)); |
| 725 | break :blk fs.path.basename(ofile_path); | 664 | break :blk fs.path.basename(ofile_path); |
| 726 | } else "???"; | 665 | } else "???"; |
| 727 | if (getLineNumberInfoMacOs(di, symbol.*, adjusted_addr)) |line_info| { | 666 | |
| 728 | defer line_info.deinit(); | 667 | const line_info = getLineNumberInfoMacOs(di, symbol.*, adjusted_addr) catch |err| switch (err) { |
| 729 | try printLineInfo( | 668 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
| 730 | out_stream, | | |
| 731 | line_info, | | |
| 732 | address, | | |
| 733 | symbol_name, | | |
| 734 | compile_unit_name, | | |
| 735 | tty_color, | | |
| 736 | printLineFromFileAnyOs, | | |
| 737 | ); | | |
| 738 | } else |err| switch (err) { | | |
| 739 | error.MissingDebugInfo, error.InvalidDebugInfo => { | | |
| 740 | if (tty_color) { | | |
| 741 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in {} ({})" ++ RESET ++ "\n\n\n", .{ | | |
| 742 | address, symbol_name, compile_unit_name, | | |
| 743 | }); | | |
| 744 | } else { | | |
| 745 | try out_stream.print("???:?:?: 0x{x} in {} ({})\n\n\n", .{ address, symbol_name, compile_unit_name }); | | |
| 746 | } | | |
| 747 | }, | | |
| 748 | else => return err, | 669 | else => return err, |
| 749 | } | 670 | }; |
| | 671 | defer if (line_info) |li| li.deinit(); |
| | 672 | |
| | 673 | try printLineInfo( |
| | 674 | out_stream, |
| | 675 | line_info, |
| | 676 | address, |
| | 677 | symbol_name, |
| | 678 | compile_unit_name, |
| | 679 | tty_color, |
| | 680 | printLineFromFileAnyOs, |
| | 681 | ); |
| 750 | } | 682 | } |
| 751 | | 683 | |
| 752 | pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 684 | pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { |
| ... | @@ -755,47 +687,46 @@ pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, addres | ... | @@ -755,47 +687,46 @@ pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, addres |
| 755 | | 687 | |
| 756 | fn printLineInfo( | 688 | fn printLineInfo( |
| 757 | out_stream: var, | 689 | out_stream: var, |
| 758 | line_info: LineInfo, | 690 | line_info: ?LineInfo, |
| 759 | address: usize, | 691 | address: usize, |
| 760 | symbol_name: []const u8, | 692 | symbol_name: []const u8, |
| 761 | compile_unit_name: []const u8, | 693 | compile_unit_name: []const u8, |
| 762 | tty_color: bool, | 694 | tty_color: bool, |
| 763 | comptime printLineFromFile: var, | 695 | comptime printLineFromFile: var, |
| 764 | ) !void { | 696 | ) !void { |
| 765 | if (tty_color) { | 697 | if (tty_color) setTtyColor(.White); |
| 766 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ "0x{x} in {} ({})" ++ RESET ++ "\n", .{ | 698 | |
| 767 | line_info.file_name, | 699 | if (line_info) |*li| { |
| 768 | line_info.line, | 700 | try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column }); |
| 769 | line_info.column, | 701 | } else { |
| 770 | address, | 702 | try out_stream.print("???:?:?", .{}); |
| 771 | symbol_name, | 703 | } |
| 772 | compile_unit_name, | 704 | |
| 773 | }); | 705 | if (tty_color) setTtyColor(.Reset); |
| 774 | if (printLineFromFile(out_stream, line_info)) { | 706 | try out_stream.write(": "); |
| 775 | if (line_info.column == 0) { | 707 | if (tty_color) setTtyColor(.Dim); |
| 776 | try out_stream.write("\n"); | 708 | try out_stream.print("0x{x} in {} ({})", .{ address, symbol_name, compile_unit_name }); |
| 777 | } else { | 709 | if (tty_color) setTtyColor(.Reset); |
| 778 | { | 710 | try out_stream.write("\n"); |
| 779 | var col_i: usize = 1; | 711 | |
| 780 | while (col_i < line_info.column) : (col_i += 1) { | 712 | // Show the matching source code line if possible |
| 781 | try out_stream.writeByte(' '); | 713 | if (line_info) |li| { |
| 782 | } | 714 | if (printLineFromFile(out_stream, li)) { |
| 783 | } | 715 | if (li.column > 0) { |
| 784 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | 716 | // The caret already takes one char |
| | 717 | const space_needed = @intCast(usize, li.column - 1); |
| | 718 | |
| | 719 | try out_stream.writeByteNTimes(' ', space_needed); |
| | 720 | if (tty_color) setTtyColor(.Green); |
| | 721 | try out_stream.write("^"); |
| | 722 | if (tty_color) setTtyColor(.Reset); |
| 785 | } | 723 | } |
| | 724 | try out_stream.write("\n"); |
| 786 | } else |err| switch (err) { | 725 | } else |err| switch (err) { |
| 787 | error.EndOfFile, error.FileNotFound => {}, | 726 | error.EndOfFile, error.FileNotFound => {}, |
| | 727 | error.BadPathName => {}, |
| 788 | else => return err, | 728 | else => return err, |
| 789 | } | 729 | } |
| 790 | } else { | | |
| 791 | try out_stream.print("{}:{}:{}: 0x{x} in {} ({})\n", .{ | | |
| 792 | line_info.file_name, | | |
| 793 | line_info.line, | | |
| 794 | line_info.column, | | |
| 795 | address, | | |
| 796 | symbol_name, | | |
| 797 | compile_unit_name, | | |
| 798 | }); | | |
| 799 | } | 730 | } |
| 800 | } | 731 | } |
| 801 | | 732 | |
| ... | @@ -1240,38 +1171,26 @@ pub const DwarfInfo = struct { | ... | @@ -1240,38 +1171,26 @@ pub const DwarfInfo = struct { |
| 1240 | comptime printLineFromFile: var, | 1171 | comptime printLineFromFile: var, |
| 1241 | ) !void { | 1172 | ) !void { |
| 1242 | const compile_unit = self.findCompileUnit(address) catch { | 1173 | const compile_unit = self.findCompileUnit(address) catch { |
| 1243 | if (tty_color) { | 1174 | return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFile); |
| 1244 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n\n\n", .{address}); | | |
| 1245 | } else { | | |
| 1246 | try out_stream.print("???:?:?: 0x{x} in ??? (???)\n\n\n", .{address}); | | |
| 1247 | } | | |
| 1248 | return; | | |
| 1249 | }; | 1175 | }; |
| | 1176 | |
| 1250 | const compile_unit_name = try compile_unit.die.getAttrString(self, DW.AT_name); | 1177 | const compile_unit_name = try compile_unit.die.getAttrString(self, DW.AT_name); |
| 1251 | if (self.getLineNumberInfo(compile_unit.*, address)) |line_info| { | 1178 | const symbol_name = self.getSymbolName(address) orelse "???"; |
| 1252 | defer line_info.deinit(); | 1179 | const line_info = self.getLineNumberInfo(compile_unit.*, address) catch |err| switch (err) { |
| 1253 | const symbol_name = self.getSymbolName(address) orelse "???"; | 1180 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
| 1254 | try printLineInfo( | | |
| 1255 | out_stream, | | |
| 1256 | line_info, | | |
| 1257 | address, | | |
| 1258 | symbol_name, | | |
| 1259 | compile_unit_name, | | |
| 1260 | tty_color, | | |
| 1261 | printLineFromFile, | | |
| 1262 | ); | | |
| 1263 | } else |err| switch (err) { | | |
| 1264 | error.MissingDebugInfo, error.InvalidDebugInfo => { | | |
| 1265 | if (tty_color) { | | |
| 1266 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? ({})" ++ RESET ++ "\n\n\n", .{ | | |
| 1267 | address, compile_unit_name, | | |
| 1268 | }); | | |
| 1269 | } else { | | |
| 1270 | try out_stream.print("???:?:?: 0x{x} in ??? ({})\n\n\n", .{ address, compile_unit_name }); | | |
| 1271 | } | | |
| 1272 | }, | | |
| 1273 | else => return err, | 1181 | else => return err, |
| 1274 | } | 1182 | }; |
| | 1183 | defer if (line_info) |li| li.deinit(); |
| | 1184 | |
| | 1185 | try printLineInfo( |
| | 1186 | out_stream, |
| | 1187 | line_info, |
| | 1188 | address, |
| | 1189 | symbol_name, |
| | 1190 | compile_unit_name, |
| | 1191 | tty_color, |
| | 1192 | printLineFromFile, |
| | 1193 | ); |
| 1275 | } | 1194 | } |
| 1276 | | 1195 | |
| 1277 | fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 { | 1196 | fn getSymbolName(di: *DwarfInfo, address: u64) ?[]const u8 { |