| ... | @@ -42,8 +42,8 @@ pub fn getStderrStream() !*io.OutStream(io.FileOutStream.Error) { | ... | @@ -42,8 +42,8 @@ pub fn getStderrStream() !*io.OutStream(io.FileOutStream.Error) { |
| 42 | } | 42 | } |
| 43 | } | 43 | } |
| 44 | | 44 | |
| 45 | var self_debug_info: ?*ElfStackTrace = null; | 45 | var self_debug_info: ?*DebugInfo = null; |
| 46 | pub fn getSelfDebugInfo() !*ElfStackTrace { | 46 | pub fn getSelfDebugInfo() !*DebugInfo { |
| 47 | if (self_debug_info) |info| { | 47 | if (self_debug_info) |info| { |
| 48 | return info; | 48 | return info; |
| 49 | } else { | 49 | } else { |
| ... | @@ -155,7 +155,7 @@ const WHITE = "\x1b[37;1m"; | ... | @@ -155,7 +155,7 @@ const WHITE = "\x1b[37;1m"; |
| 155 | const DIM = "\x1b[2m"; | 155 | const DIM = "\x1b[2m"; |
| 156 | const RESET = "\x1b[0m"; | 156 | const RESET = "\x1b[0m"; |
| 157 | | 157 | |
| 158 | pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var, allocator: *mem.Allocator, debug_info: *ElfStackTrace, tty_color: bool) !void { | 158 | pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo, tty_color: bool) !void { |
| 159 | var frame_index: usize = undefined; | 159 | var frame_index: usize = undefined; |
| 160 | var frames_left: usize = undefined; | 160 | var frames_left: usize = undefined; |
| 161 | if (stack_trace.index < stack_trace.instruction_addresses.len) { | 161 | if (stack_trace.index < stack_trace.instruction_addresses.len) { |
| ... | @@ -185,7 +185,7 @@ pub inline fn getReturnAddress(frame_count: usize) usize { | ... | @@ -185,7 +185,7 @@ pub inline fn getReturnAddress(frame_count: usize) usize { |
| 185 | return @intToPtr(*const usize, fp + @sizeOf(usize)).*; | 185 | return @intToPtr(*const usize, fp + @sizeOf(usize)).*; |
| 186 | } | 186 | } |
| 187 | | 187 | |
| 188 | pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_info: *ElfStackTrace, tty_color: bool, start_addr: ?usize) !void { | 188 | pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void { |
| 189 | const AddressState = union(enum) { | 189 | const AddressState = union(enum) { |
| 190 | NotLookingForStartAddress, | 190 | NotLookingForStartAddress, |
| 191 | LookingForStartAddress: usize, | 191 | LookingForStartAddress: usize, |
| ... | @@ -218,7 +218,7 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_ | ... | @@ -218,7 +218,7 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_ |
| 218 | } | 218 | } |
| 219 | } | 219 | } |
| 220 | | 220 | |
| 221 | pub fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize, tty_color: bool) !void { | 221 | pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { |
| 222 | switch (builtin.os) { | 222 | switch (builtin.os) { |
| 223 | builtin.Os.windows => return error.UnsupportedDebugInfo, | 223 | builtin.Os.windows => return error.UnsupportedDebugInfo, |
| 224 | builtin.Os.macosx => { | 224 | builtin.Os.macosx => { |
| ... | @@ -291,10 +291,10 @@ pub fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address | ... | @@ -291,10 +291,10 @@ pub fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address |
| 291 | } | 291 | } |
| 292 | } | 292 | } |
| 293 | | 293 | |
| 294 | pub fn openSelfDebugInfo(allocator: *mem.Allocator) !*ElfStackTrace { | 294 | pub fn openSelfDebugInfo(allocator: *mem.Allocator) !*DebugInfo { |
| 295 | switch (builtin.object_format) { | 295 | switch (builtin.object_format) { |
| 296 | builtin.ObjectFormat.elf => { | 296 | builtin.ObjectFormat.elf => { |
| 297 | const st = try allocator.create(ElfStackTrace{ | 297 | const st = try allocator.create(DebugInfo{ |
| 298 | .self_exe_file = undefined, | 298 | .self_exe_file = undefined, |
| 299 | .elf = undefined, | 299 | .elf = undefined, |
| 300 | .debug_info = undefined, | 300 | .debug_info = undefined, |
| ... | @@ -324,7 +324,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) !*ElfStackTrace { | ... | @@ -324,7 +324,7 @@ pub fn openSelfDebugInfo(allocator: *mem.Allocator) !*ElfStackTrace { |
| 324 | var exe_file = try os.openSelfExe(); | 324 | var exe_file = try os.openSelfExe(); |
| 325 | defer exe_file.close(); | 325 | defer exe_file.close(); |
| 326 | | 326 | |
| 327 | const st = try allocator.create(ElfStackTrace{ .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)) }); | 327 | const st = try allocator.create(DebugInfo{ .symbol_table = try macho.loadSymbols(allocator, &io.FileInStream.init(&exe_file)) }); |
| 328 | errdefer allocator.destroy(st); | 328 | errdefer allocator.destroy(st); |
| 329 | return st; | 329 | return st; |
| 330 | }, | 330 | }, |
| ... | @@ -372,11 +372,11 @@ fn printLineFromFile(out_stream: var, line_info: *const LineInfo) !void { | ... | @@ -372,11 +372,11 @@ fn printLineFromFile(out_stream: var, line_info: *const LineInfo) !void { |
| 372 | } | 372 | } |
| 373 | } | 373 | } |
| 374 | | 374 | |
| 375 | pub const ElfStackTrace = switch (builtin.os) { | 375 | pub const DebugInfo = switch (builtin.os) { |
| 376 | builtin.Os.macosx => struct { | 376 | builtin.Os.macosx => struct { |
| 377 | symbol_table: macho.SymbolTable, | 377 | symbol_table: macho.SymbolTable, |
| 378 | | 378 | |
| 379 | pub fn close(self: *ElfStackTrace) void { | 379 | pub fn close(self: *DebugInfo) void { |
| 380 | self.symbol_table.deinit(); | 380 | self.symbol_table.deinit(); |
| 381 | } | 381 | } |
| 382 | }, | 382 | }, |
| ... | @@ -391,17 +391,17 @@ pub const ElfStackTrace = switch (builtin.os) { | ... | @@ -391,17 +391,17 @@ pub const ElfStackTrace = switch (builtin.os) { |
| 391 | abbrev_table_list: ArrayList(AbbrevTableHeader), | 391 | abbrev_table_list: ArrayList(AbbrevTableHeader), |
| 392 | compile_unit_list: ArrayList(CompileUnit), | 392 | compile_unit_list: ArrayList(CompileUnit), |
| 393 | | 393 | |
| 394 | pub fn allocator(self: *const ElfStackTrace) *mem.Allocator { | 394 | pub fn allocator(self: *const DebugInfo) *mem.Allocator { |
| 395 | return self.abbrev_table_list.allocator; | 395 | return self.abbrev_table_list.allocator; |
| 396 | } | 396 | } |
| 397 | | 397 | |
| 398 | pub fn readString(self: *ElfStackTrace) ![]u8 { | 398 | pub fn readString(self: *DebugInfo) ![]u8 { |
| 399 | var in_file_stream = io.FileInStream.init(&self.self_exe_file); | 399 | var in_file_stream = io.FileInStream.init(&self.self_exe_file); |
| 400 | const in_stream = &in_file_stream.stream; | 400 | const in_stream = &in_file_stream.stream; |
| 401 | return readStringRaw(self.allocator(), in_stream); | 401 | return readStringRaw(self.allocator(), in_stream); |
| 402 | } | 402 | } |
| 403 | | 403 | |
| 404 | pub fn close(self: *ElfStackTrace) void { | 404 | pub fn close(self: *DebugInfo) void { |
| 405 | self.self_exe_file.close(); | 405 | self.self_exe_file.close(); |
| 406 | self.elf.close(); | 406 | self.elf.close(); |
| 407 | } | 407 | } |
| ... | @@ -508,7 +508,7 @@ const Die = struct { | ... | @@ -508,7 +508,7 @@ const Die = struct { |
| 508 | }; | 508 | }; |
| 509 | } | 509 | } |
| 510 | | 510 | |
| 511 | fn getAttrString(self: *const Die, st: *ElfStackTrace, id: u64) ![]u8 { | 511 | fn getAttrString(self: *const Die, st: *DebugInfo, id: u64) ![]u8 { |
| 512 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; | 512 | const form_value = self.getAttr(id) orelse return error.MissingDebugInfo; |
| 513 | return switch (form_value.*) { | 513 | return switch (form_value.*) { |
| 514 | FormValue.String => |value| value, | 514 | FormValue.String => |value| value, |
| ... | @@ -623,7 +623,7 @@ fn readStringRaw(allocator: *mem.Allocator, in_stream: var) ![]u8 { | ... | @@ -623,7 +623,7 @@ fn readStringRaw(allocator: *mem.Allocator, in_stream: var) ![]u8 { |
| 623 | return buf.toSlice(); | 623 | return buf.toSlice(); |
| 624 | } | 624 | } |
| 625 | | 625 | |
| 626 | fn getString(st: *ElfStackTrace, offset: u64) ![]u8 { | 626 | fn getString(st: *DebugInfo, offset: u64) ![]u8 { |
| 627 | const pos = st.debug_str.offset + offset; | 627 | const pos = st.debug_str.offset + offset; |
| 628 | try st.self_exe_file.seekTo(pos); | 628 | try st.self_exe_file.seekTo(pos); |
| 629 | return st.readString(); | 629 | return st.readString(); |
| ... | @@ -730,7 +730,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 | ... | @@ -730,7 +730,7 @@ fn parseFormValue(allocator: *mem.Allocator, in_stream: var, form_id: u64, is_64 |
| 730 | }; | 730 | }; |
| 731 | } | 731 | } |
| 732 | | 732 | |
| 733 | fn parseAbbrevTable(st: *ElfStackTrace) !AbbrevTable { | 733 | fn parseAbbrevTable(st: *DebugInfo) !AbbrevTable { |
| 734 | const in_file = &st.self_exe_file; | 734 | const in_file = &st.self_exe_file; |
| 735 | var in_file_stream = io.FileInStream.init(in_file); | 735 | var in_file_stream = io.FileInStream.init(in_file); |
| 736 | const in_stream = &in_file_stream.stream; | 736 | const in_stream = &in_file_stream.stream; |
| ... | @@ -760,7 +760,7 @@ fn parseAbbrevTable(st: *ElfStackTrace) !AbbrevTable { | ... | @@ -760,7 +760,7 @@ fn parseAbbrevTable(st: *ElfStackTrace) !AbbrevTable { |
| 760 | | 760 | |
| 761 | /// Gets an already existing AbbrevTable given the abbrev_offset, or if not found, | 761 | /// Gets an already existing AbbrevTable given the abbrev_offset, or if not found, |
| 762 | /// seeks in the stream and parses it. | 762 | /// seeks in the stream and parses it. |
| 763 | fn getAbbrevTable(st: *ElfStackTrace, abbrev_offset: u64) !*const AbbrevTable { | 763 | fn getAbbrevTable(st: *DebugInfo, abbrev_offset: u64) !*const AbbrevTable { |
| 764 | for (st.abbrev_table_list.toSlice()) |*header| { | 764 | for (st.abbrev_table_list.toSlice()) |*header| { |
| 765 | if (header.offset == abbrev_offset) { | 765 | if (header.offset == abbrev_offset) { |
| 766 | return &header.table; | 766 | return &header.table; |
| ... | @@ -781,7 +781,7 @@ fn getAbbrevTableEntry(abbrev_table: *const AbbrevTable, abbrev_code: u64) ?*con | ... | @@ -781,7 +781,7 @@ fn getAbbrevTableEntry(abbrev_table: *const AbbrevTable, abbrev_code: u64) ?*con |
| 781 | return null; | 781 | return null; |
| 782 | } | 782 | } |
| 783 | | 783 | |
| 784 | fn parseDie(st: *ElfStackTrace, abbrev_table: *const AbbrevTable, is_64: bool) !Die { | 784 | fn parseDie(st: *DebugInfo, abbrev_table: *const AbbrevTable, is_64: bool) !Die { |
| 785 | const in_file = &st.self_exe_file; | 785 | const in_file = &st.self_exe_file; |
| 786 | var in_file_stream = io.FileInStream.init(in_file); | 786 | var in_file_stream = io.FileInStream.init(in_file); |
| 787 | const in_stream = &in_file_stream.stream; | 787 | const in_stream = &in_file_stream.stream; |
| ... | @@ -803,7 +803,7 @@ fn parseDie(st: *ElfStackTrace, abbrev_table: *const AbbrevTable, is_64: bool) ! | ... | @@ -803,7 +803,7 @@ fn parseDie(st: *ElfStackTrace, abbrev_table: *const AbbrevTable, is_64: bool) ! |
| 803 | return result; | 803 | return result; |
| 804 | } | 804 | } |
| 805 | | 805 | |
| 806 | fn getLineNumberInfo(st: *ElfStackTrace, compile_unit: *const CompileUnit, target_address: usize) !LineInfo { | 806 | fn getLineNumberInfo(st: *DebugInfo, compile_unit: *const CompileUnit, target_address: usize) !LineInfo { |
| 807 | const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir); | 807 | const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir); |
| 808 | | 808 | |
| 809 | const in_file = &st.self_exe_file; | 809 | const in_file = &st.self_exe_file; |
| ... | @@ -982,7 +982,7 @@ fn getLineNumberInfo(st: *ElfStackTrace, compile_unit: *const CompileUnit, targe | ... | @@ -982,7 +982,7 @@ fn getLineNumberInfo(st: *ElfStackTrace, compile_unit: *const CompileUnit, targe |
| 982 | return error.MissingDebugInfo; | 982 | return error.MissingDebugInfo; |
| 983 | } | 983 | } |
| 984 | | 984 | |
| 985 | fn scanAllCompileUnits(st: *ElfStackTrace) !void { | 985 | fn scanAllCompileUnits(st: *DebugInfo) !void { |
| 986 | const debug_info_end = st.debug_info.offset + st.debug_info.size; | 986 | const debug_info_end = st.debug_info.offset + st.debug_info.size; |
| 987 | var this_unit_offset = st.debug_info.offset; | 987 | var this_unit_offset = st.debug_info.offset; |
| 988 | var cu_index: usize = 0; | 988 | var cu_index: usize = 0; |
| ... | @@ -1052,7 +1052,7 @@ fn scanAllCompileUnits(st: *ElfStackTrace) !void { | ... | @@ -1052,7 +1052,7 @@ fn scanAllCompileUnits(st: *ElfStackTrace) !void { |
| 1052 | } | 1052 | } |
| 1053 | } | 1053 | } |
| 1054 | | 1054 | |
| 1055 | fn findCompileUnit(st: *ElfStackTrace, target_address: u64) !*const CompileUnit { | 1055 | fn findCompileUnit(st: *DebugInfo, target_address: u64) !*const CompileUnit { |
| 1056 | var in_file_stream = io.FileInStream.init(&st.self_exe_file); | 1056 | var in_file_stream = io.FileInStream.init(&st.self_exe_file); |
| 1057 | const in_stream = &in_file_stream.stream; | 1057 | const in_stream = &in_file_stream.stream; |
| 1058 | for (st.compile_unit_list.toSlice()) |*compile_unit| { | 1058 | for (st.compile_unit_list.toSlice()) |*compile_unit| { |