| ... | @@ -81,10 +81,20 @@ pub fn getSelfDebugInfo() !*DebugInfo { | ... | @@ -81,10 +81,20 @@ pub fn getSelfDebugInfo() !*DebugInfo { |
| 81 | } | 81 | } |
| 82 | } | 82 | } |
| 83 | | 83 | |
| 84 | fn wantTtyColor() bool { | 84 | fn detectTTYConfig() TTY.Config { |
| 85 | var bytes: [128]u8 = undefined; | 85 | var bytes: [128]u8 = undefined; |
| 86 | const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator; | 86 | const allocator = &std.heap.FixedBufferAllocator.init(bytes[0..]).allocator; |
| 87 | return if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| true else |_| stderr_file.isTty(); | 87 | if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| { |
| | 88 | return .escape_codes; |
| | 89 | } else |_| { |
| | 90 | if (stderr_file.supportsAnsiEscapeCodes()) { |
| | 91 | return .escape_codes; |
| | 92 | } else if (builtin.os == .windows) { |
| | 93 | return .windows_api; |
| | 94 | } else { |
| | 95 | return .no_color; |
| | 96 | } |
| | 97 | } |
| 88 | } | 98 | } |
| 89 | | 99 | |
| 90 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. | 100 | /// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned. |
| ... | @@ -99,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { | ... | @@ -99,7 +109,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 99 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; | 109 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; |
| 100 | return; | 110 | return; |
| 101 | }; | 111 | }; |
| 102 | writeCurrentStackTrace(stderr, debug_info, wantTtyColor(), start_addr) catch |err| { | 112 | writeCurrentStackTrace(stderr, debug_info, detectTTYConfig(), start_addr) catch |err| { |
| 103 | stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return; | 113 | stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return; |
| 104 | return; | 114 | return; |
| 105 | }; | 115 | }; |
| ... | @@ -118,16 +128,16 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { | ... | @@ -118,16 +128,16 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { |
| 118 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; | 128 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; |
| 119 | return; | 129 | return; |
| 120 | }; | 130 | }; |
| 121 | const tty_color = wantTtyColor(); | 131 | const tty_config = detectTTYConfig(); |
| 122 | printSourceAtAddress(debug_info, stderr, ip, tty_color) catch return; | 132 | printSourceAtAddress(debug_info, stderr, ip, tty_config) catch return; |
| 123 | const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*; | 133 | const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*; |
| 124 | printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_color) catch return; | 134 | printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_config) catch return; |
| 125 | var it = StackIterator{ | 135 | var it = StackIterator{ |
| 126 | .first_addr = null, | 136 | .first_addr = null, |
| 127 | .fp = bp, | 137 | .fp = bp, |
| 128 | }; | 138 | }; |
| 129 | while (it.next()) |return_address| { | 139 | while (it.next()) |return_address| { |
| 130 | printSourceAtAddress(debug_info, stderr, return_address - 1, tty_color) catch return; | 140 | printSourceAtAddress(debug_info, stderr, return_address - 1, tty_config) catch return; |
| 131 | } | 141 | } |
| 132 | } | 142 | } |
| 133 | | 143 | |
| ... | @@ -191,7 +201,7 @@ pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { | ... | @@ -191,7 +201,7 @@ pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { |
| 191 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; | 201 | stderr.print("Unable to dump stack trace: Unable to open debug info: {}\n", .{@errorName(err)}) catch return; |
| 192 | return; | 202 | return; |
| 193 | }; | 203 | }; |
| 194 | writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, wantTtyColor()) catch |err| { | 204 | writeStackTrace(stack_trace, stderr, getDebugInfoAllocator(), debug_info, detectTTYConfig()) catch |err| { |
| 195 | stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return; | 205 | stderr.print("Unable to dump stack trace: {}\n", .{@errorName(err)}) catch return; |
| 196 | return; | 206 | return; |
| 197 | }; | 207 | }; |
| ... | @@ -264,7 +274,7 @@ pub fn writeStackTrace( | ... | @@ -264,7 +274,7 @@ pub fn writeStackTrace( |
| 264 | out_stream: var, | 274 | out_stream: var, |
| 265 | allocator: *mem.Allocator, | 275 | allocator: *mem.Allocator, |
| 266 | debug_info: *DebugInfo, | 276 | debug_info: *DebugInfo, |
| 267 | tty_color: bool, | 277 | tty_config: TTY.Config, |
| 268 | ) !void { | 278 | ) !void { |
| 269 | if (builtin.strip_debug_info) return error.MissingDebugInfo; | 279 | if (builtin.strip_debug_info) return error.MissingDebugInfo; |
| 270 | var frame_index: usize = 0; | 280 | var frame_index: usize = 0; |
| ... | @@ -275,7 +285,7 @@ pub fn writeStackTrace( | ... | @@ -275,7 +285,7 @@ pub fn writeStackTrace( |
| 275 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; | 285 | frame_index = (frame_index + 1) % stack_trace.instruction_addresses.len; |
| 276 | }) { | 286 | }) { |
| 277 | const return_address = stack_trace.instruction_addresses[frame_index]; | 287 | const return_address = stack_trace.instruction_addresses[frame_index]; |
| 278 | try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color); | 288 | try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_config); |
| 279 | } | 289 | } |
| 280 | } | 290 | } |
| 281 | | 291 | |
| ... | @@ -319,20 +329,25 @@ pub const StackIterator = struct { | ... | @@ -319,20 +329,25 @@ pub const StackIterator = struct { |
| 319 | } | 329 | } |
| 320 | }; | 330 | }; |
| 321 | | 331 | |
| 322 | pub fn writeCurrentStackTrace(out_stream: var, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void { | 332 | pub fn writeCurrentStackTrace( |
| | 333 | out_stream: var, |
| | 334 | debug_info: *DebugInfo, |
| | 335 | tty_config: TTY.Config, |
| | 336 | start_addr: ?usize, |
| | 337 | ) !void { |
| 323 | if (builtin.os == .windows) { | 338 | if (builtin.os == .windows) { |
| 324 | return writeCurrentStackTraceWindows(out_stream, debug_info, tty_color, start_addr); | 339 | return writeCurrentStackTraceWindows(out_stream, debug_info, tty_config, start_addr); |
| 325 | } | 340 | } |
| 326 | var it = StackIterator.init(start_addr); | 341 | var it = StackIterator.init(start_addr); |
| 327 | while (it.next()) |return_address| { | 342 | while (it.next()) |return_address| { |
| 328 | try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_color); | 343 | try printSourceAtAddress(debug_info, out_stream, return_address - 1, tty_config); |
| 329 | } | 344 | } |
| 330 | } | 345 | } |
| 331 | | 346 | |
| 332 | pub fn writeCurrentStackTraceWindows( | 347 | pub fn writeCurrentStackTraceWindows( |
| 333 | out_stream: var, | 348 | out_stream: var, |
| 334 | debug_info: *DebugInfo, | 349 | debug_info: *DebugInfo, |
| 335 | tty_color: bool, | 350 | tty_config: TTY.Config, |
| 336 | start_addr: ?usize, | 351 | start_addr: ?usize, |
| 337 | ) !void { | 352 | ) !void { |
| 338 | var addr_buf: [1024]usize = undefined; | 353 | var addr_buf: [1024]usize = undefined; |
| ... | @@ -345,23 +360,28 @@ pub fn writeCurrentStackTraceWindows( | ... | @@ -345,23 +360,28 @@ pub fn writeCurrentStackTraceWindows( |
| 345 | return; | 360 | return; |
| 346 | } else 0; | 361 | } else 0; |
| 347 | for (addrs[start_i..]) |addr| { | 362 | for (addrs[start_i..]) |addr| { |
| 348 | try printSourceAtAddress(debug_info, out_stream, addr, tty_color); | 363 | try printSourceAtAddress(debug_info, out_stream, addr, tty_config); |
| 349 | } | 364 | } |
| 350 | } | 365 | } |
| 351 | | 366 | |
| 352 | /// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented, | 367 | /// TODO once https://github.com/ziglang/zig/issues/3157 is fully implemented, |
| 353 | /// make this `noasync fn` and remove the individual noasync calls. | 368 | /// make this `noasync fn` and remove the individual noasync calls. |
| 354 | pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 369 | pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { |
| 355 | if (builtin.os == .windows) { | 370 | if (builtin.os == .windows) { |
| 356 | return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_color); | 371 | return noasync printSourceAtAddressWindows(debug_info, out_stream, address, tty_config); |
| 357 | } | 372 | } |
| 358 | if (comptime std.Target.current.isDarwin()) { | 373 | if (comptime std.Target.current.isDarwin()) { |
| 359 | return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color); | 374 | return noasync printSourceAtAddressMacOs(debug_info, out_stream, address, tty_config); |
| 360 | } | 375 | } |
| 361 | return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_color); | 376 | return noasync printSourceAtAddressPosix(debug_info, out_stream, address, tty_config); |
| 362 | } | 377 | } |
| 363 | | 378 | |
| 364 | fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_address: usize, tty_color: bool) !void { | 379 | fn printSourceAtAddressWindows( |
| | 380 | di: *DebugInfo, |
| | 381 | out_stream: var, |
| | 382 | relocated_address: usize, |
| | 383 | tty_config: TTY.Config, |
| | 384 | ) !void { |
| 365 | const allocator = getDebugInfoAllocator(); | 385 | const allocator = getDebugInfoAllocator(); |
| 366 | const base_address = process.getBaseAddress(); | 386 | const base_address = process.getBaseAddress(); |
| 367 | const relative_address = relocated_address - base_address; | 387 | const relative_address = relocated_address - base_address; |
| ... | @@ -379,7 +399,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres | ... | @@ -379,7 +399,7 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres |
| 379 | } | 399 | } |
| 380 | } else { | 400 | } else { |
| 381 | // we have no information to add to the address | 401 | // we have no information to add to the address |
| 382 | return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_color, printLineFromFileAnyOs); | 402 | return printLineInfo(out_stream, null, relocated_address, "???", "???", tty_config, printLineFromFileAnyOs); |
| 383 | }; | 403 | }; |
| 384 | | 404 | |
| 385 | const mod = &di.modules[mod_index]; | 405 | const mod = &di.modules[mod_index]; |
| ... | @@ -507,84 +527,80 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres | ... | @@ -507,84 +527,80 @@ fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, relocated_addres |
| 507 | relocated_address, | 527 | relocated_address, |
| 508 | symbol_name, | 528 | symbol_name, |
| 509 | obj_basename, | 529 | obj_basename, |
| 510 | tty_color, | 530 | tty_config, |
| 511 | printLineFromFileAnyOs, | 531 | printLineFromFileAnyOs, |
| 512 | ); | 532 | ); |
| 513 | } | 533 | } |
| 514 | | 534 | |
| 515 | const TtyColor = enum { | 535 | pub const TTY = struct { |
| 516 | Red, | 536 | pub const Color = enum { |
| 517 | Green, | 537 | Red, |
| 518 | Cyan, | 538 | Green, |
| 519 | White, | 539 | Cyan, |
| 520 | Dim, | 540 | White, |
| 521 | Bold, | 541 | Dim, |
| 522 | Reset, | 542 | Bold, |
| 523 | }; | 543 | Reset, |
| 524 | | 544 | }; |
| 525 | /// TODO this is a special case hack right now. clean it up and maybe make it part of std.fmt | | |
| 526 | fn setTtyColor(tty_color: TtyColor) void { | | |
| 527 | if (stderr_file.supportsAnsiEscapeCodes()) { | | |
| 528 | switch (tty_color) { | | |
| 529 | TtyColor.Red => { | | |
| 530 | stderr_file.write(RED) catch return; | | |
| 531 | }, | | |
| 532 | TtyColor.Green => { | | |
| 533 | stderr_file.write(GREEN) catch return; | | |
| 534 | }, | | |
| 535 | TtyColor.Cyan => { | | |
| 536 | stderr_file.write(CYAN) catch return; | | |
| 537 | }, | | |
| 538 | TtyColor.White, TtyColor.Bold => { | | |
| 539 | stderr_file.write(WHITE) catch return; | | |
| 540 | }, | | |
| 541 | TtyColor.Dim => { | | |
| 542 | stderr_file.write(DIM) catch return; | | |
| 543 | }, | | |
| 544 | TtyColor.Reset => { | | |
| 545 | stderr_file.write(RESET) catch return; | | |
| 546 | }, | | |
| 547 | } | | |
| 548 | | | |
| 549 | return; | | |
| 550 | } | | |
| 551 | | 545 | |
| 552 | if (builtin.os == .windows) { | 546 | pub const Config = enum { |
| 553 | const S = struct { | 547 | no_color, |
| 554 | var attrs: windows.WORD = undefined; | 548 | escape_codes, |
| 555 | var init_attrs = false; | 549 | // TODO give this a payload of file handle |
| 556 | }; | 550 | windows_api, |
| 557 | if (!S.init_attrs) { | 551 | |
| 558 | S.init_attrs = true; | 552 | fn setColor(conf: Config, out_stream: var, color: Color) void { |
| 559 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | 553 | switch (conf) { |
| 560 | // TODO handle error | 554 | .no_color => return, |
| 561 | _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info); | 555 | .escape_codes => switch (color) { |
| 562 | S.attrs = info.wAttributes; | 556 | .Red => out_stream.write(RED) catch return, |
| 563 | } | 557 | .Green => out_stream.write(GREEN) catch return, |
| | 558 | .Cyan => out_stream.write(CYAN) catch return, |
| | 559 | .White, .Bold => out_stream.write(WHITE) catch return, |
| | 560 | .Dim => out_stream.write(DIM) catch return, |
| | 561 | .Reset => out_stream.write(RESET) catch return, |
| | 562 | }, |
| | 563 | .windows_api => if (builtin.os == .windows) { |
| | 564 | const S = struct { |
| | 565 | var attrs: windows.WORD = undefined; |
| | 566 | var init_attrs = false; |
| | 567 | }; |
| | 568 | if (!S.init_attrs) { |
| | 569 | S.init_attrs = true; |
| | 570 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| | 571 | // TODO handle error |
| | 572 | _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info); |
| | 573 | S.attrs = info.wAttributes; |
| | 574 | } |
| 564 | | 575 | |
| 565 | // TODO handle errors | 576 | // TODO handle errors |
| 566 | switch (tty_color) { | 577 | switch (color) { |
| 567 | TtyColor.Red => { | 578 | .Red => { |
| 568 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {}; | 579 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {}; |
| 569 | }, | 580 | }, |
| 570 | TtyColor.Green => { | 581 | .Green => { |
| 571 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {}; | 582 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {}; |
| 572 | }, | 583 | }, |
| 573 | TtyColor.Cyan => { | 584 | .Cyan => { |
| 574 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | 585 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; |
| 575 | }, | 586 | }, |
| 576 | TtyColor.White, TtyColor.Bold => { | 587 | .White, .Bold => { |
| 577 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | 588 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; |
| 578 | }, | 589 | }, |
| 579 | TtyColor.Dim => { | 590 | .Dim => { |
| 580 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {}; | 591 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {}; |
| 581 | }, | 592 | }, |
| 582 | TtyColor.Reset => { | 593 | .Reset => { |
| 583 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {}; | 594 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {}; |
| 584 | }, | 595 | }, |
| | 596 | } |
| | 597 | } else { |
| | 598 | unreachable; |
| | 599 | }, |
| | 600 | } |
| 585 | } | 601 | } |
| 586 | } | 602 | }; |
| 587 | } | 603 | }; |
| 588 | | 604 | |
| 589 | fn populateModule(di: *DebugInfo, mod: *Module) !void { | 605 | fn populateModule(di: *DebugInfo, mod: *Module) !void { |
| 590 | if (mod.populated) | 606 | if (mod.populated) |
| ... | @@ -650,12 +666,12 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach | ... | @@ -650,12 +666,12 @@ fn machoSearchSymbols(symbols: []const MachoSymbol, address: usize) ?*const Mach |
| 650 | return null; | 666 | return null; |
| 651 | } | 667 | } |
| 652 | | 668 | |
| 653 | fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 669 | fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { |
| 654 | const base_addr = process.getBaseAddress(); | 670 | const base_addr = process.getBaseAddress(); |
| 655 | const adjusted_addr = 0x100000000 + (address - base_addr); | 671 | const adjusted_addr = 0x100000000 + (address - base_addr); |
| 656 | | 672 | |
| 657 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { | 673 | const symbol = machoSearchSymbols(di.symbols, adjusted_addr) orelse { |
| 658 | return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFileAnyOs); | 674 | return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFileAnyOs); |
| 659 | }; | 675 | }; |
| 660 | | 676 | |
| 661 | const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx)); | 677 | const symbol_name = mem.toSliceConst(u8, @ptrCast([*:0]const u8, di.strings.ptr + symbol.nlist.n_strx)); |
| ... | @@ -676,13 +692,13 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt | ... | @@ -676,13 +692,13 @@ fn printSourceAtAddressMacOs(di: *DebugInfo, out_stream: var, address: usize, tt |
| 676 | address, | 692 | address, |
| 677 | symbol_name, | 693 | symbol_name, |
| 678 | compile_unit_name, | 694 | compile_unit_name, |
| 679 | tty_color, | 695 | tty_config, |
| 680 | printLineFromFileAnyOs, | 696 | printLineFromFileAnyOs, |
| 681 | ); | 697 | ); |
| 682 | } | 698 | } |
| 683 | | 699 | |
| 684 | pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void { | 700 | pub fn printSourceAtAddressPosix(debug_info: *DebugInfo, out_stream: var, address: usize, tty_config: TTY.Config) !void { |
| 685 | return debug_info.printSourceAtAddress(out_stream, address, tty_color, printLineFromFileAnyOs); | 701 | return debug_info.printSourceAtAddress(out_stream, address, tty_config, printLineFromFileAnyOs); |
| 686 | } | 702 | } |
| 687 | | 703 | |
| 688 | fn printLineInfo( | 704 | fn printLineInfo( |
| ... | @@ -691,10 +707,10 @@ fn printLineInfo( | ... | @@ -691,10 +707,10 @@ fn printLineInfo( |
| 691 | address: usize, | 707 | address: usize, |
| 692 | symbol_name: []const u8, | 708 | symbol_name: []const u8, |
| 693 | compile_unit_name: []const u8, | 709 | compile_unit_name: []const u8, |
| 694 | tty_color: bool, | 710 | tty_config: TTY.Config, |
| 695 | comptime printLineFromFile: var, | 711 | comptime printLineFromFile: var, |
| 696 | ) !void { | 712 | ) !void { |
| 697 | if (tty_color) setTtyColor(.White); | 713 | tty_config.setColor(out_stream, .White); |
| 698 | | 714 | |
| 699 | if (line_info) |*li| { | 715 | if (line_info) |*li| { |
| 700 | try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column }); | 716 | try out_stream.print("{}:{}:{}", .{ li.file_name, li.line, li.column }); |
| ... | @@ -702,11 +718,11 @@ fn printLineInfo( | ... | @@ -702,11 +718,11 @@ fn printLineInfo( |
| 702 | try out_stream.print("???:?:?", .{}); | 718 | try out_stream.print("???:?:?", .{}); |
| 703 | } | 719 | } |
| 704 | | 720 | |
| 705 | if (tty_color) setTtyColor(.Reset); | 721 | tty_config.setColor(out_stream, .Reset); |
| 706 | try out_stream.write(": "); | 722 | try out_stream.write(": "); |
| 707 | if (tty_color) setTtyColor(.Dim); | 723 | tty_config.setColor(out_stream, .Dim); |
| 708 | try out_stream.print("0x{x} in {} ({})", .{ address, symbol_name, compile_unit_name }); | 724 | try out_stream.print("0x{x} in {} ({})", .{ address, symbol_name, compile_unit_name }); |
| 709 | if (tty_color) setTtyColor(.Reset); | 725 | tty_config.setColor(out_stream, .Reset); |
| 710 | try out_stream.write("\n"); | 726 | try out_stream.write("\n"); |
| 711 | | 727 | |
| 712 | // Show the matching source code line if possible | 728 | // Show the matching source code line if possible |
| ... | @@ -717,9 +733,9 @@ fn printLineInfo( | ... | @@ -717,9 +733,9 @@ fn printLineInfo( |
| 717 | const space_needed = @intCast(usize, li.column - 1); | 733 | const space_needed = @intCast(usize, li.column - 1); |
| 718 | | 734 | |
| 719 | try out_stream.writeByteNTimes(' ', space_needed); | 735 | try out_stream.writeByteNTimes(' ', space_needed); |
| 720 | if (tty_color) setTtyColor(.Green); | 736 | tty_config.setColor(out_stream, .Green); |
| 721 | try out_stream.write("^"); | 737 | try out_stream.write("^"); |
| 722 | if (tty_color) setTtyColor(.Reset); | 738 | tty_config.setColor(out_stream, .Reset); |
| 723 | } | 739 | } |
| 724 | try out_stream.write("\n"); | 740 | try out_stream.write("\n"); |
| 725 | } else |err| switch (err) { | 741 | } else |err| switch (err) { |
| ... | @@ -1167,11 +1183,11 @@ pub const DwarfInfo = struct { | ... | @@ -1167,11 +1183,11 @@ pub const DwarfInfo = struct { |
| 1167 | self: *DwarfInfo, | 1183 | self: *DwarfInfo, |
| 1168 | out_stream: var, | 1184 | out_stream: var, |
| 1169 | address: usize, | 1185 | address: usize, |
| 1170 | tty_color: bool, | 1186 | tty_config: TTY.Config, |
| 1171 | comptime printLineFromFile: var, | 1187 | comptime printLineFromFile: var, |
| 1172 | ) !void { | 1188 | ) !void { |
| 1173 | const compile_unit = self.findCompileUnit(address) catch { | 1189 | const compile_unit = self.findCompileUnit(address) catch { |
| 1174 | return printLineInfo(out_stream, null, address, "???", "???", tty_color, printLineFromFile); | 1190 | return printLineInfo(out_stream, null, address, "???", "???", tty_config, printLineFromFile); |
| 1175 | }; | 1191 | }; |
| 1176 | | 1192 | |
| 1177 | const compile_unit_name = try compile_unit.die.getAttrString(self, DW.AT_name); | 1193 | const compile_unit_name = try compile_unit.die.getAttrString(self, DW.AT_name); |
| ... | @@ -1188,7 +1204,7 @@ pub const DwarfInfo = struct { | ... | @@ -1188,7 +1204,7 @@ pub const DwarfInfo = struct { |
| 1188 | address, | 1204 | address, |
| 1189 | symbol_name, | 1205 | symbol_name, |
| 1190 | compile_unit_name, | 1206 | compile_unit_name, |
| 1191 | tty_color, | 1207 | tty_config, |
| 1192 | printLineFromFile, | 1208 | printLineFromFile, |
| 1193 | ); | 1209 | ); |
| 1194 | } | 1210 | } |