| ... | @@ -156,7 +156,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var, | ... | @@ -156,7 +156,7 @@ pub fn writeStackTrace(stack_trace: *const builtin.StackTrace, out_stream: var, |
| 156 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; | 156 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; |
| 157 | }) { | 157 | }) { |
| 158 | const return_address = stack_trace.instruction_addresses[frame_index]; | 158 | const return_address = stack_trace.instruction_addresses[frame_index]; |
| 159 | try printSourceAtAddress(debug_info, out_stream, return_address); | 159 | try printSourceAtAddress(debug_info, out_stream, return_address, tty_color); |
| 160 | } | 160 | } |
| 161 | } | 161 | } |
| 162 | | 162 | |
| ... | @@ -189,13 +189,11 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_ | ... | @@ -189,13 +189,11 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_ |
| 189 | } | 189 | } |
| 190 | }, | 190 | }, |
| 191 | } | 191 | } |
| 192 | try printSourceAtAddress(debug_info, out_stream, return_address); | 192 | try printSourceAtAddress(debug_info, out_stream, return_address, tty_color); |
| 193 | } | 193 | } |
| 194 | } | 194 | } |
| 195 | | 195 | |
| 196 | fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize) !void { | 196 | fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: usize, tty_color: bool) !void { |
| 197 | const ptr_hex = "0x{x}"; | | |
| 198 | | | |
| 199 | switch (builtin.os) { | 197 | switch (builtin.os) { |
| 200 | builtin.Os.windows => return error.UnsupportedDebugInfo, | 198 | builtin.Os.windows => return error.UnsupportedDebugInfo, |
| 201 | builtin.Os.macosx => { | 199 | builtin.Os.macosx => { |
| ... | @@ -209,36 +207,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us | ... | @@ -209,36 +207,58 @@ fn printSourceAtAddress(debug_info: *ElfStackTrace, out_stream: var, address: us |
| 209 | .address = address, | 207 | .address = address, |
| 210 | }; | 208 | }; |
| 211 | const symbol = debug_info.symbol_table.search(address) orelse &unknown; | 209 | const symbol = debug_info.symbol_table.search(address) orelse &unknown; |
| 212 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address); | 210 | try out_stream.print(WHITE ++ "{}" ++ RESET ++ ": " ++ DIM ++ "0x{x}" ++ " in ??? (???)" ++ RESET ++ "\n", symbol.name, address); |
| 213 | }, | 211 | }, |
| 214 | else => { | 212 | else => { |
| 215 | const compile_unit = findCompileUnit(debug_info, address) catch { | 213 | const compile_unit = findCompileUnit(debug_info, address) catch { |
| 216 | try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n", address); | 214 | if (tty_color) { |
| | 215 | try out_stream.print("???:?:?: " ++ DIM ++ "0x{x} in ??? (???)" ++ RESET ++ "\n ???\n\n", address); |
| | 216 | } else { |
| | 217 | try out_stream.print("???:?:?: 0x{x} in ??? (???)\n ???\n\n", address); |
| | 218 | } |
| 217 | return; | 219 | return; |
| 218 | }; | 220 | }; |
| 219 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); | 221 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); |
| 220 | if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| { | 222 | if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| { |
| 221 | defer line_info.deinit(); | 223 | defer line_info.deinit(); |
| 222 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", line_info.file_name, line_info.line, line_info.column, address, compile_unit_name); | 224 | if (tty_color) { |
| 223 | if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) { | 225 | try out_stream.print( |
| 224 | if (line_info.column == 0) { | 226 | WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ DIM ++ "0x{x} in ??? ({})" ++ RESET ++ "\n", |
| 225 | try out_stream.write("\n"); | 227 | line_info.file_name, |
| 226 | } else { | 228 | line_info.line, |
| 227 | { | 229 | line_info.column, |
| 228 | var col_i: usize = 1; | 230 | address, |
| 229 | while (col_i < line_info.column) : (col_i += 1) { | 231 | compile_unit_name, |
| 230 | try out_stream.writeByte(' '); | 232 | ); |
| | 233 | if (printLineFromFile(debug_info.allocator(), out_stream, line_info)) { |
| | 234 | if (line_info.column == 0) { |
| | 235 | try out_stream.write("\n"); |
| | 236 | } else { |
| | 237 | { |
| | 238 | var col_i: usize = 1; |
| | 239 | while (col_i < line_info.column) : (col_i += 1) { |
| | 240 | try out_stream.writeByte(' '); |
| | 241 | } |
| 231 | } | 242 | } |
| | 243 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); |
| 232 | } | 244 | } |
| 233 | try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n"); | 245 | } else |err| switch (err) { |
| | 246 | error.EndOfFile => {}, |
| | 247 | else => return err, |
| 234 | } | 248 | } |
| 235 | } else |err| switch (err) { | 249 | } else { |
| 236 | error.EndOfFile => {}, | 250 | try out_stream.print( |
| 237 | else => return err, | 251 | "{}:{}:{}: 0x{x} in ??? ({})\n", |
| | 252 | line_info.file_name, |
| | 253 | line_info.line, |
| | 254 | line_info.column, |
| | 255 | address, |
| | 256 | compile_unit_name, |
| | 257 | ); |
| 238 | } | 258 | } |
| 239 | } else |err| switch (err) { | 259 | } else |err| switch (err) { |
| 240 | error.MissingDebugInfo, error.InvalidDebugInfo => { | 260 | error.MissingDebugInfo, error.InvalidDebugInfo => { |
| 241 | try out_stream.print(ptr_hex ++ " in ??? ({})\n", address, compile_unit_name); | 261 | try out_stream.print("0x{x} in ??? ({})\n", address, compile_unit_name); |
| 242 | }, | 262 | }, |
| 243 | else => return err, | 263 | else => return err, |
| 244 | } | 264 | } |