| ... | @@ -50,33 +50,17 @@ pub const LineInfo = struct { | ... | @@ -50,33 +50,17 @@ pub const LineInfo = struct { |
| 50 | } | 50 | } |
| 51 | }; | 51 | }; |
| 52 | | 52 | |
| 53 | /// Tries to write to stderr, unbuffered, and ignores any error returned. | | |
| 54 | /// Does not append a newline. | | |
| 55 | var stderr_file: File = undefined; | | |
| 56 | var stderr_file_writer: File.Writer = undefined; | | |
| 57 | | | |
| 58 | var stderr_stream: ?*File.OutStream = null; | | |
| 59 | var stderr_mutex = std.Mutex.init(); | 53 | var stderr_mutex = std.Mutex.init(); |
| 60 | | 54 | |
| | 55 | /// Tries to write to stderr, unbuffered, and ignores any error returned. |
| | 56 | /// Does not append a newline. |
| 61 | pub fn warn(comptime fmt: []const u8, args: var) void { | 57 | pub fn warn(comptime fmt: []const u8, args: var) void { |
| 62 | const held = stderr_mutex.acquire(); | 58 | const held = stderr_mutex.acquire(); |
| 63 | defer held.release(); | 59 | defer held.release(); |
| 64 | const stderr = getStderrStream(); | 60 | const stderr = io.getStdErr().writer(); |
| 65 | nosuspend stderr.print(fmt, args) catch return; | 61 | nosuspend stderr.print(fmt, args) catch return; |
| 66 | } | 62 | } |
| 67 | | 63 | |
| 68 | pub fn getStderrStream() *File.OutStream { | | |
| 69 | if (stderr_stream) |st| { | | |
| 70 | return st; | | |
| 71 | } else { | | |
| 72 | stderr_file = io.getStdErr(); | | |
| 73 | stderr_file_writer = stderr_file.outStream(); | | |
| 74 | const st = &stderr_file_writer; | | |
| 75 | stderr_stream = st; | | |
| 76 | return st; | | |
| 77 | } | | |
| 78 | } | | |
| 79 | | | |
| 80 | pub fn getStderrMutex() *std.Mutex { | 64 | pub fn getStderrMutex() *std.Mutex { |
| 81 | return &stderr_mutex; | 65 | return &stderr_mutex; |
| 82 | } | 66 | } |
| ... | @@ -99,6 +83,7 @@ pub fn detectTTYConfig() TTY.Config { | ... | @@ -99,6 +83,7 @@ pub fn detectTTYConfig() TTY.Config { |
| 99 | if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| { | 83 | if (process.getEnvVarOwned(allocator, "ZIG_DEBUG_COLOR")) |_| { |
| 100 | return .escape_codes; | 84 | return .escape_codes; |
| 101 | } else |_| { | 85 | } else |_| { |
| | 86 | const stderr_file = io.getStdErr(); |
| 102 | if (stderr_file.supportsAnsiEscapeCodes()) { | 87 | if (stderr_file.supportsAnsiEscapeCodes()) { |
| 103 | return .escape_codes; | 88 | return .escape_codes; |
| 104 | } else if (builtin.os.tag == .windows and stderr_file.isTty()) { | 89 | } else if (builtin.os.tag == .windows and stderr_file.isTty()) { |
| ... | @@ -113,7 +98,7 @@ pub fn detectTTYConfig() TTY.Config { | ... | @@ -113,7 +98,7 @@ pub fn detectTTYConfig() TTY.Config { |
| 113 | /// TODO multithreaded awareness | 98 | /// TODO multithreaded awareness |
| 114 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { | 99 | pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 115 | nosuspend { | 100 | nosuspend { |
| 116 | const stderr = getStderrStream(); | 101 | const stderr = io.getStdErr().writer(); |
| 117 | if (builtin.strip_debug_info) { | 102 | if (builtin.strip_debug_info) { |
| 118 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; | 103 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; |
| 119 | return; | 104 | return; |
| ... | @@ -134,7 +119,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { | ... | @@ -134,7 +119,7 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void { |
| 134 | /// TODO multithreaded awareness | 119 | /// TODO multithreaded awareness |
| 135 | pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { | 120 | pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { |
| 136 | nosuspend { | 121 | nosuspend { |
| 137 | const stderr = getStderrStream(); | 122 | const stderr = io.getStdErr().writer(); |
| 138 | if (builtin.strip_debug_info) { | 123 | if (builtin.strip_debug_info) { |
| 139 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; | 124 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; |
| 140 | return; | 125 | return; |
| ... | @@ -204,7 +189,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace | ... | @@ -204,7 +189,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *builtin.StackTrace |
| 204 | /// TODO multithreaded awareness | 189 | /// TODO multithreaded awareness |
| 205 | pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { | 190 | pub fn dumpStackTrace(stack_trace: builtin.StackTrace) void { |
| 206 | nosuspend { | 191 | nosuspend { |
| 207 | const stderr = getStderrStream(); | 192 | const stderr = io.getStdErr().writer(); |
| 208 | if (builtin.strip_debug_info) { | 193 | if (builtin.strip_debug_info) { |
| 209 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; | 194 | stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; |
| 210 | return; | 195 | return; |
| ... | @@ -272,7 +257,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c | ... | @@ -272,7 +257,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c |
| 272 | const held = panic_mutex.acquire(); | 257 | const held = panic_mutex.acquire(); |
| 273 | defer held.release(); | 258 | defer held.release(); |
| 274 | | 259 | |
| 275 | const stderr = getStderrStream(); | 260 | const stderr = io.getStdErr().writer(); |
| 276 | stderr.print(format ++ "\n", args) catch os.abort(); | 261 | stderr.print(format ++ "\n", args) catch os.abort(); |
| 277 | if (trace) |t| { | 262 | if (trace) |t| { |
| 278 | dumpStackTrace(t.*); | 263 | dumpStackTrace(t.*); |
| ... | @@ -297,7 +282,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c | ... | @@ -297,7 +282,7 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c |
| 297 | // A panic happened while trying to print a previous panic message, | 282 | // A panic happened while trying to print a previous panic message, |
| 298 | // we're still holding the mutex but that's fine as we're going to | 283 | // we're still holding the mutex but that's fine as we're going to |
| 299 | // call abort() | 284 | // call abort() |
| 300 | const stderr = getStderrStream(); | 285 | const stderr = io.getStdErr().writer(); |
| 301 | stderr.print("Panicked during a panic. Aborting.\n", .{}) catch os.abort(); | 286 | stderr.print("Panicked during a panic. Aborting.\n", .{}) catch os.abort(); |
| 302 | }, | 287 | }, |
| 303 | else => { | 288 | else => { |
| ... | @@ -458,6 +443,7 @@ pub const TTY = struct { | ... | @@ -458,6 +443,7 @@ pub const TTY = struct { |
| 458 | .Reset => out_stream.writeAll(RESET) catch return, | 443 | .Reset => out_stream.writeAll(RESET) catch return, |
| 459 | }, | 444 | }, |
| 460 | .windows_api => if (builtin.os.tag == .windows) { | 445 | .windows_api => if (builtin.os.tag == .windows) { |
| | 446 | const stderr_file = io.getStdErr(); |
| 461 | const S = struct { | 447 | const S = struct { |
| 462 | var attrs: windows.WORD = undefined; | 448 | var attrs: windows.WORD = undefined; |
| 463 | var init_attrs = false; | 449 | var init_attrs = false; |