Skip to content

Commit 65270cd

Browse files
authored
Merge pull request #12298 from r00ster91/debugerror
std.debug: handle some possible errors and resolve low-hanging TODOs
2 parents 9be5323 + 7561f63 commit 65270cd

4 files changed

Lines changed: 73 additions & 94 deletions

File tree

lib/std/Progress.zig

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,11 @@ fn refreshWithHeldLock(self: *Progress) void {
210210
std.debug.assert(self.is_windows_terminal);
211211

212212
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
213-
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE)
214-
unreachable;
213+
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) {
214+
// stop trying to write to this file
215+
self.terminal = null;
216+
break :winapi;
217+
}
215218

216219
var cursor_pos = windows.COORD{
217220
.X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written),
@@ -231,7 +234,7 @@ fn refreshWithHeldLock(self: *Progress) void {
231234
cursor_pos,
232235
&written,
233236
) != windows.TRUE) {
234-
// Stop trying to write to this file.
237+
// stop trying to write to this file
235238
self.terminal = null;
236239
break :winapi;
237240
}
@@ -241,10 +244,16 @@ fn refreshWithHeldLock(self: *Progress) void {
241244
fill_chars,
242245
cursor_pos,
243246
&written,
244-
) != windows.TRUE) unreachable;
245-
246-
if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)
247-
unreachable;
247+
) != windows.TRUE) {
248+
// stop trying to write to this file
249+
self.terminal = null;
250+
break :winapi;
251+
}
252+
if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) {
253+
// stop trying to write to this file
254+
self.terminal = null;
255+
break :winapi;
256+
}
248257
} else {
249258
// we are in a "dumb" terminal like in acme or writing to a file
250259
self.output_buffer[end] = '\n';
@@ -288,7 +297,7 @@ fn refreshWithHeldLock(self: *Progress) void {
288297
}
289298

290299
_ = file.write(self.output_buffer[0..end]) catch {
291-
// Stop trying to write to this file once it errors.
300+
// stop trying to write to this file
292301
self.terminal = null;
293302
};
294303
if (self.timer) |*timer| {

lib/std/debug.zig

Lines changed: 37 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ pub fn detectTTYConfig() TTY.Config {
119119
if (stderr_file.supportsAnsiEscapeCodes()) {
120120
return .escape_codes;
121121
} else if (native_os == .windows and stderr_file.isTty()) {
122-
return .windows_api;
122+
return .{ .windows_api = stderr_file };
123123
} else {
124124
return .no_color;
125125
}
@@ -384,14 +384,6 @@ pub fn panicImpl(trace: ?*const std.builtin.StackTrace, first_trace_addr: ?usize
384384
os.abort();
385385
}
386386

387-
const RED = "\x1b[31;1m";
388-
const GREEN = "\x1b[32;1m";
389-
const CYAN = "\x1b[36;1m";
390-
const WHITE = "\x1b[37;1m";
391-
const BOLD = "\x1b[1m";
392-
const DIM = "\x1b[2m";
393-
const RESET = "\x1b[0m";
394-
395387
pub fn writeStackTrace(
396388
stack_trace: std.builtin.StackTrace,
397389
out_stream: anytype,
@@ -415,9 +407,9 @@ pub fn writeStackTrace(
415407
if (stack_trace.index > stack_trace.instruction_addresses.len) {
416408
const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len;
417409

418-
tty_config.setColor(out_stream, .Bold);
410+
tty_config.setColor(out_stream, .Bold) catch {};
419411
try out_stream.print("({d} additional stack frames skipped...)\n", .{dropped_frames});
420-
tty_config.setColor(out_stream, .Reset);
412+
tty_config.setColor(out_stream, .Reset) catch {};
421413
}
422414
}
423415

@@ -605,59 +597,39 @@ pub const TTY = struct {
605597
Reset,
606598
};
607599

608-
pub const Config = enum {
600+
pub const Config = union(enum) {
609601
no_color,
610602
escape_codes,
611-
// TODO give this a payload of file handle
612-
windows_api,
603+
windows_api: File,
613604

614-
pub fn setColor(conf: Config, out_stream: anytype, color: Color) void {
605+
pub fn setColor(conf: Config, out_stream: anytype, color: Color) !void {
615606
nosuspend switch (conf) {
616607
.no_color => return,
617-
.escape_codes => switch (color) {
618-
.Red => out_stream.writeAll(RED) catch return,
619-
.Green => out_stream.writeAll(GREEN) catch return,
620-
.Cyan => out_stream.writeAll(CYAN) catch return,
621-
.White => out_stream.writeAll(WHITE) catch return,
622-
.Dim => out_stream.writeAll(DIM) catch return,
623-
.Bold => out_stream.writeAll(BOLD) catch return,
624-
.Reset => out_stream.writeAll(RESET) catch return,
608+
.escape_codes => {
609+
const color_string = switch (color) {
610+
.Red => "\x1b[31;1m",
611+
.Green => "\x1b[32;1m",
612+
.Cyan => "\x1b[36;1m",
613+
.White => "\x1b[37;1m",
614+
.Bold => "\x1b[1m",
615+
.Dim => "\x1b[2m",
616+
.Reset => "\x1b[0m",
617+
};
618+
try out_stream.writeAll(color_string);
625619
},
626-
.windows_api => if (native_os == .windows) {
627-
const stderr_file = io.getStdErr();
628-
const S = struct {
629-
var attrs: windows.WORD = undefined;
630-
var init_attrs = false;
620+
.windows_api => |file| if (native_os == .windows) {
621+
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
622+
if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE)
623+
return error.FailedRetrievingTerminalInfo;
624+
const attributes = switch (color) {
625+
.Red => windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY,
626+
.Green => windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY,
627+
.Cyan => windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY,
628+
.White, .Bold => windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY,
629+
.Dim => windows.FOREGROUND_INTENSITY,
630+
.Reset => info.wAttributes,
631631
};
632-
if (!S.init_attrs) {
633-
S.init_attrs = true;
634-
var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
635-
// TODO handle error
636-
_ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info);
637-
S.attrs = info.wAttributes;
638-
}
639-
640-
// TODO handle errors
641-
switch (color) {
642-
.Red => {
643-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {};
644-
},
645-
.Green => {
646-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {};
647-
},
648-
.Cyan => {
649-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
650-
},
651-
.White, .Bold => {
652-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {};
653-
},
654-
.Dim => {
655-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {};
656-
},
657-
.Reset => {
658-
_ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {};
659-
},
660-
}
632+
try windows.SetConsoleTextAttribute(file.handle, attributes);
661633
} else {
662634
unreachable;
663635
},
@@ -751,19 +723,19 @@ fn printLineInfo(
751723
comptime printLineFromFile: anytype,
752724
) !void {
753725
nosuspend {
754-
tty_config.setColor(out_stream, .Bold);
726+
try tty_config.setColor(out_stream, .Bold);
755727

756728
if (line_info) |*li| {
757729
try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column });
758730
} else {
759731
try out_stream.writeAll("???:?:?");
760732
}
761733

762-
tty_config.setColor(out_stream, .Reset);
734+
try tty_config.setColor(out_stream, .Reset);
763735
try out_stream.writeAll(": ");
764-
tty_config.setColor(out_stream, .Dim);
736+
try tty_config.setColor(out_stream, .Dim);
765737
try out_stream.print("0x{x} in {s} ({s})", .{ address, symbol_name, compile_unit_name });
766-
tty_config.setColor(out_stream, .Reset);
738+
try tty_config.setColor(out_stream, .Reset);
767739
try out_stream.writeAll("\n");
768740

769741
// Show the matching source code line if possible
@@ -774,9 +746,9 @@ fn printLineInfo(
774746
const space_needed = @intCast(usize, li.column - 1);
775747

776748
try out_stream.writeByteNTimes(' ', space_needed);
777-
tty_config.setColor(out_stream, .Green);
749+
try tty_config.setColor(out_stream, .Green);
778750
try out_stream.writeAll("^");
779-
tty_config.setColor(out_stream, .Reset);
751+
try tty_config.setColor(out_stream, .Reset);
780752
}
781753
try out_stream.writeAll("\n");
782754
} else |err| switch (err) {
@@ -789,14 +761,12 @@ fn printLineInfo(
789761
}
790762
}
791763

792-
// TODO use this
793764
pub const OpenSelfDebugInfoError = error{
794765
MissingDebugInfo,
795-
OutOfMemory,
796766
UnsupportedOperatingSystem,
797767
};
798768

799-
pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo {
769+
pub fn openSelfDebugInfo(allocator: mem.Allocator) OpenSelfDebugInfoError!DebugInfo {
800770
nosuspend {
801771
if (builtin.strip_debug_info)
802772
return error.MissingDebugInfo;
@@ -813,7 +783,7 @@ pub fn openSelfDebugInfo(allocator: mem.Allocator) anyerror!DebugInfo {
813783
.windows,
814784
.solaris,
815785
=> return DebugInfo.init(allocator),
816-
else => return error.UnsupportedDebugInfo,
786+
else => return error.UnsupportedOperatingSystem,
817787
}
818788
}
819789
}

lib/std/testing.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,9 @@ fn SliceDiffer(comptime T: type) type {
387387
for (self.expected) |value, i| {
388388
var full_index = self.start_index + i;
389389
const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true;
390-
if (diff) self.ttyconf.setColor(writer, .Red);
390+
if (diff) try self.ttyconf.setColor(writer, .Red);
391391
try writer.print("[{}]: {any}\n", .{ full_index, value });
392-
if (diff) self.ttyconf.setColor(writer, .Reset);
392+
if (diff) try self.ttyconf.setColor(writer, .Reset);
393393
}
394394
}
395395
};
@@ -427,9 +427,9 @@ const BytesDiffer = struct {
427427
}
428428

429429
fn writeByteDiff(self: BytesDiffer, writer: anytype, comptime fmt: []const u8, byte: u8, diff: bool) !void {
430-
if (diff) self.ttyconf.setColor(writer, .Red);
430+
if (diff) try self.ttyconf.setColor(writer, .Red);
431431
try writer.print(fmt, .{byte});
432-
if (diff) self.ttyconf.setColor(writer, .Reset);
432+
if (diff) try self.ttyconf.setColor(writer, .Reset);
433433
}
434434

435435
const ChunkIterator = struct {

src/Compilation.zig

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -428,29 +428,29 @@ pub const AllErrors = struct {
428428
switch (msg) {
429429
.src => |src| {
430430
try counting_stderr.writeByteNTimes(' ', indent);
431-
ttyconf.setColor(stderr, .Bold);
431+
try ttyconf.setColor(stderr, .Bold);
432432
try counting_stderr.print("{s}:{d}:{d}: ", .{
433433
src.src_path,
434434
src.line + 1,
435435
src.column + 1,
436436
});
437-
ttyconf.setColor(stderr, color);
437+
try ttyconf.setColor(stderr, color);
438438
try counting_stderr.writeAll(kind);
439439
try counting_stderr.writeAll(": ");
440440
// This is the length of the part before the error message:
441441
// e.g. "file.zig:4:5: error: "
442442
const prefix_len = @intCast(usize, counting_stderr.context.bytes_written);
443-
ttyconf.setColor(stderr, .Reset);
444-
ttyconf.setColor(stderr, .Bold);
443+
try ttyconf.setColor(stderr, .Reset);
444+
try ttyconf.setColor(stderr, .Bold);
445445
if (src.count == 1) {
446446
try src.writeMsg(stderr, prefix_len);
447447
try stderr.writeByte('\n');
448448
} else {
449449
try src.writeMsg(stderr, prefix_len);
450-
ttyconf.setColor(stderr, .Dim);
450+
try ttyconf.setColor(stderr, .Dim);
451451
try stderr.print(" ({d} times)\n", .{src.count});
452452
}
453-
ttyconf.setColor(stderr, .Reset);
453+
try ttyconf.setColor(stderr, .Reset);
454454
if (src.source_line) |line| {
455455
for (line) |b| switch (b) {
456456
'\t' => try stderr.writeByte(' '),
@@ -462,19 +462,19 @@ pub const AllErrors = struct {
462462
// -1 since span.main includes the caret
463463
const after_caret = src.span.end - src.span.main -| 1;
464464
try stderr.writeByteNTimes(' ', src.column - before_caret);
465-
ttyconf.setColor(stderr, .Green);
465+
try ttyconf.setColor(stderr, .Green);
466466
try stderr.writeByteNTimes('~', before_caret);
467467
try stderr.writeByte('^');
468468
try stderr.writeByteNTimes('~', after_caret);
469469
try stderr.writeByte('\n');
470-
ttyconf.setColor(stderr, .Reset);
470+
try ttyconf.setColor(stderr, .Reset);
471471
}
472472
for (src.notes) |note| {
473473
try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent);
474474
}
475475
if (src.reference_trace.len != 0) {
476-
ttyconf.setColor(stderr, .Reset);
477-
ttyconf.setColor(stderr, .Dim);
476+
try ttyconf.setColor(stderr, .Reset);
477+
try ttyconf.setColor(stderr, .Dim);
478478
try stderr.print("referenced by:\n", .{});
479479
for (src.reference_trace) |reference| {
480480
switch (reference) {
@@ -498,23 +498,23 @@ pub const AllErrors = struct {
498498
}
499499
}
500500
try stderr.writeByte('\n');
501-
ttyconf.setColor(stderr, .Reset);
501+
try ttyconf.setColor(stderr, .Reset);
502502
}
503503
},
504504
.plain => |plain| {
505-
ttyconf.setColor(stderr, color);
505+
try ttyconf.setColor(stderr, color);
506506
try stderr.writeByteNTimes(' ', indent);
507507
try stderr.writeAll(kind);
508508
try stderr.writeAll(": ");
509-
ttyconf.setColor(stderr, .Reset);
509+
try ttyconf.setColor(stderr, .Reset);
510510
if (plain.count == 1) {
511511
try stderr.print("{s}\n", .{plain.msg});
512512
} else {
513513
try stderr.print("{s}", .{plain.msg});
514-
ttyconf.setColor(stderr, .Dim);
514+
try ttyconf.setColor(stderr, .Dim);
515515
try stderr.print(" ({d} times)\n", .{plain.count});
516516
}
517-
ttyconf.setColor(stderr, .Reset);
517+
try ttyconf.setColor(stderr, .Reset);
518518
for (plain.notes) |note| {
519519
try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent + 4);
520520
}

0 commit comments

Comments
 (0)