| ... | ... | @@ -62,6 +62,7 @@ fn wantTtyColor() bool { |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. |
| 65 | /// TODO multithreaded awareness |
| 65 | 66 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 66 | 67 | const stderr = getStderrStream() catch return; |
| 67 | 68 | const debug_info = getSelfDebugInfo() catch |err| { |
| ... | ... | @@ -75,6 +76,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 75 | 76 | } |
| 76 | 77 | |
| 77 | 78 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. |
| 79 | /// TODO multithreaded awareness |
| 78 | 80 | pub fn dumpStackTrace(stack_trace: *const builtin.StackTrace) void { |
| 79 | 81 | const stderr = getStderrStream() catch return; |
| 80 | 82 | const debug_info = getSelfDebugInfo() catch |err| { |
| ... | ... | @@ -460,6 +462,7 @@ fn openSelfDebugInfoMacOs(allocator: *mem.Allocator) !DebugInfo { |
| 460 | 462 | std.sort.sort(MachoSymbol, symbols, MachoSymbol.addressLessThan); |
| 461 | 463 | |
| 462 | 464 | return DebugInfo{ |
| 465 | .ofiles = DebugInfo.OFileTable.init(allocator), |
| 463 | 466 | .symbols = symbols, |
| 464 | 467 | .strings = strings, |
| 465 | 468 | }; |
| ... | ... | @@ -511,10 +514,22 @@ const MachoSymbol = struct { |
| 511 | 514 | } |
| 512 | 515 | }; |
| 513 | 516 | |
| 517 | const MachOFile = struct { |
| 518 | bytes: []align(@alignOf(std.c.mach_header_64)) const u8, |
| 519 | }; |
| 520 | |
| 514 | 521 | pub const DebugInfo = switch (builtin.os) { |
| 515 | 522 | builtin.Os.macosx => struct { |
| 516 | 523 | symbols: []const MachoSymbol, |
| 517 | 524 | strings: []const u8, |
| 525 | ofiles: OFileTable, |
| 526 | |
| 527 | const OFileTable = std.HashMap( |
| 528 | *std.c.nlist_64, |
| 529 | MachOFile, |
| 530 | std.hash_map.getHashPtrAddrFn(*std.c.nlist_64), |
| 531 | std.hash_map.getTrivialEqlFn(*std.c.nlist_64), |
| 532 | ); |
| 518 | 533 | }, |
| 519 | 534 | else => struct { |
| 520 | 535 | self_exe_file: os.File, |
| ... | ... | @@ -940,6 +955,44 @@ fn parseDie(st: *DebugInfo, abbrev_table: *const AbbrevTable, is_64: bool) !Die |
| 940 | 955 | } |
| 941 | 956 | |
| 942 | 957 | fn getLineNumberInfoMacOs(di: *DebugInfo, symbol: MachoSymbol, target_address: usize) !LineInfo { |
| 958 | const ofile = symbol.ofile orelse return error.MissingDebugInfo; |
| 959 | const gop = try di.ofiles.getOrPut(ofile); |
| 960 | const mach_o_file = if (gop.found_existing) &gop.kv.value else blk: { |
| 961 | errdefer _ = di.ofiles.remove(ofile); |
| 962 | const ofile_path = mem.toSliceConst(u8, di.strings.ptr + ofile.n_strx); |
| 963 | std.debug.warn("reading .o file: {}\n", ofile_path); |
| 964 | |
| 965 | gop.kv.value = MachOFile{ |
| 966 | .bytes = try std.io.readFileAllocAligned(di.ofiles.allocator, ofile_path, @alignOf(std.c.mach_header_64)), |
| 967 | }; |
| 968 | const hdr = @ptrCast(*const std.c.mach_header_64, gop.kv.value.bytes.ptr); |
| 969 | assert(hdr.magic == std.c.MH_MAGIC_64); |
| 970 | |
| 971 | const hdr_base = @ptrCast([*]const u8, hdr); |
| 972 | var ptr = hdr_base + @sizeOf(std.c.mach_header_64); |
| 973 | var ncmd: u32 = hdr.ncmds; |
| 974 | const segcmd = while (ncmd != 0) : (ncmd -= 1) { |
| 975 | const lc = @ptrCast(*const std.c.load_command, ptr); |
| 976 | switch (lc.cmd) { |
| 977 | std.c.LC_SEGMENT_64 => break @ptrCast(*const std.c.segment_command_64, ptr), |
| 978 | else => {}, |
| 979 | } |
| 980 | ptr += lc.cmdsize; // TODO https://github.com/ziglang/zig/issues/1403 |
| 981 | } else { |
| 982 | return error.MissingDebugInfo; |
| 983 | }; |
| 984 | const sections = @ptrCast([*]const std.c.section_64, ptr + @sizeOf(std.c.segment_command_64))[0..segcmd.nsects]; |
| 985 | for (sections) |sect| { |
| 986 | if (sect.flags & std.c.SECTION_TYPE == std.c.S_REGULAR and |
| 987 | (sect.flags & std.c.SECTION_ATTRIBUTES) & std.c.S_ATTR_DEBUG == std.c.S_ATTR_DEBUG) { |
| 988 | const sect_name = mem.toSliceConst(u8, &sect.sectname); |
| 989 | std.debug.warn("sect: {}\n", sect_name); |
| 990 | } |
| 991 | } |
| 992 | |
| 993 | break :blk &gop.kv.value; |
| 994 | }; |
| 995 | |
| 943 | 996 | return error.MissingDebugInfo; |
| 944 | 997 | } |
| 945 | 998 | |