| author | |
| committer | |
| log | bee8005fe6817ade9191de0493888b14cdbcac31 |
| tree | 6001bd45ab1118e92a77fe6ebfbf6b332d371a2b |
| parent | 4a53e5b0b4131c6b8e18bb551e8215e425f8ac71 |
instead, allow the user to set it as a field.
this fixes a bug where leak printing and error printing would run tty
config detection for stderr, and then emit a log, which is not necessary
going to print to stderr.
however, the nice defaults are gone; the user must explicitly assign the
tty_config field during initialization or else the logging will not have
color.
related: https://github.com/ziglang/zig/issues/2451025 files changed, 113 insertions(+), 86 deletions(-)
lib/compiler/build_runner.zig+1-1| ... | @@ -435,7 +435,7 @@ pub fn main() !void { | ... | @@ -435,7 +435,7 @@ pub fn main() !void { |
| 435 | if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{}); | 435 | if (builtin.single_threaded) fatal("'--webui' is not yet supported on single-threaded hosts", .{}); |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | const ttyconf = color.detectTtyConf(); | 438 | const ttyconf = color.detectTtyConf(io); |
| 439 | 439 | ||
| 440 | const main_progress_node = std.Progress.start(.{ | 440 | const main_progress_node = std.Progress.start(.{ |
| 441 | .disable_printing = (color == .off), | 441 | .disable_printing = (color == .off), |
lib/std/Build/Fuzz.zig+10-9| ... | @@ -360,12 +360,13 @@ fn coverageRunCancelable(fuzz: *Fuzz) Io.Cancelable!void { | ... | @@ -360,12 +360,13 @@ fn coverageRunCancelable(fuzz: *Fuzz) Io.Cancelable!void { |
| 360 | fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutOfMemory, AlreadyReported, Canceled }!void { | 360 | fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutOfMemory, AlreadyReported, Canceled }!void { |
| 361 | assert(fuzz.mode == .forever); | 361 | assert(fuzz.mode == .forever); |
| 362 | const ws = fuzz.mode.forever.ws; | 362 | const ws = fuzz.mode.forever.ws; |
| 363 | const gpa = fuzz.gpa; | ||
| 363 | const io = fuzz.io; | 364 | const io = fuzz.io; |
| 364 | 365 | ||
| 365 | try fuzz.coverage_mutex.lock(io); | 366 | try fuzz.coverage_mutex.lock(io); |
| 366 | defer fuzz.coverage_mutex.unlock(io); | 367 | defer fuzz.coverage_mutex.unlock(io); |
| 367 | 368 | ||
| 368 | const gop = try fuzz.coverage_files.getOrPut(fuzz.gpa, coverage_id); | 369 | const gop = try fuzz.coverage_files.getOrPut(gpa, coverage_id); |
| 369 | if (gop.found_existing) { | 370 | if (gop.found_existing) { |
| 370 | // We are fuzzing the same executable with multiple threads. | 371 | // We are fuzzing the same executable with multiple threads. |
| 371 | // Perhaps the same unit test; perhaps a different one. In any | 372 | // Perhaps the same unit test; perhaps a different one. In any |
| ... | @@ -383,12 +384,12 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -383,12 +384,12 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 383 | .entry_points = .{}, | 384 | .entry_points = .{}, |
| 384 | .start_timestamp = ws.now(), | 385 | .start_timestamp = ws.now(), |
| 385 | }; | 386 | }; |
| 386 | errdefer gop.value_ptr.coverage.deinit(fuzz.gpa); | 387 | errdefer gop.value_ptr.coverage.deinit(gpa); |
| 387 | 388 | ||
| 388 | const rebuilt_exe_path = run_step.rebuilt_executable.?; | 389 | const rebuilt_exe_path = run_step.rebuilt_executable.?; |
| 389 | const target = run_step.producer.?.rootModuleTarget(); | 390 | const target = run_step.producer.?.rootModuleTarget(); |
| 390 | var debug_info = std.debug.Info.load( | 391 | var debug_info = std.debug.Info.load( |
| 391 | fuzz.gpa, | 392 | gpa, |
| 392 | io, | 393 | io, |
| 393 | rebuilt_exe_path, | 394 | rebuilt_exe_path, |
| 394 | &gop.value_ptr.coverage, | 395 | &gop.value_ptr.coverage, |
| ... | @@ -400,7 +401,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -400,7 +401,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 400 | }); | 401 | }); |
| 401 | return error.AlreadyReported; | 402 | return error.AlreadyReported; |
| 402 | }; | 403 | }; |
| 403 | defer debug_info.deinit(fuzz.gpa); | 404 | defer debug_info.deinit(gpa); |
| 404 | 405 | ||
| 405 | const coverage_file_path: Build.Cache.Path = .{ | 406 | const coverage_file_path: Build.Cache.Path = .{ |
| 406 | .root_dir = run_step.step.owner.cache_root, | 407 | .root_dir = run_step.step.owner.cache_root, |
| ... | @@ -434,14 +435,14 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -434,14 +435,14 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 434 | 435 | ||
| 435 | const header: *const abi.SeenPcsHeader = @ptrCast(mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]); | 436 | const header: *const abi.SeenPcsHeader = @ptrCast(mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]); |
| 436 | const pcs = header.pcAddrs(); | 437 | const pcs = header.pcAddrs(); |
| 437 | const source_locations = try fuzz.gpa.alloc(Coverage.SourceLocation, pcs.len); | 438 | const source_locations = try gpa.alloc(Coverage.SourceLocation, pcs.len); |
| 438 | errdefer fuzz.gpa.free(source_locations); | 439 | errdefer gpa.free(source_locations); |
| 439 | 440 | ||
| 440 | // Unfortunately the PCs array that LLVM gives us from the 8-bit PC | 441 | // Unfortunately the PCs array that LLVM gives us from the 8-bit PC |
| 441 | // counters feature is not sorted. | 442 | // counters feature is not sorted. |
| 442 | var sorted_pcs: std.MultiArrayList(struct { pc: u64, index: u32, sl: Coverage.SourceLocation }) = .{}; | 443 | var sorted_pcs: std.MultiArrayList(struct { pc: u64, index: u32, sl: Coverage.SourceLocation }) = .{}; |
| 443 | defer sorted_pcs.deinit(fuzz.gpa); | 444 | defer sorted_pcs.deinit(gpa); |
| 444 | try sorted_pcs.resize(fuzz.gpa, pcs.len); | 445 | try sorted_pcs.resize(gpa, pcs.len); |
| 445 | @memcpy(sorted_pcs.items(.pc), pcs); | 446 | @memcpy(sorted_pcs.items(.pc), pcs); |
| 446 | for (sorted_pcs.items(.index), 0..) |*v, i| v.* = @intCast(i); | 447 | for (sorted_pcs.items(.index), 0..) |*v, i| v.* = @intCast(i); |
| 447 | sorted_pcs.sortUnstable(struct { | 448 | sorted_pcs.sortUnstable(struct { |
| ... | @@ -452,7 +453,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO | ... | @@ -452,7 +453,7 @@ fn prepareTables(fuzz: *Fuzz, run_step: *Step.Run, coverage_id: u64) error{ OutO |
| 452 | } | 453 | } |
| 453 | }{ .addrs = sorted_pcs.items(.pc) }); | 454 | }{ .addrs = sorted_pcs.items(.pc) }); |
| 454 | 455 | ||
| 455 | debug_info.resolveAddresses(fuzz.gpa, sorted_pcs.items(.pc), sorted_pcs.items(.sl)) catch |err| { | 456 | debug_info.resolveAddresses(gpa, io, sorted_pcs.items(.pc), sorted_pcs.items(.sl)) catch |err| { |
| 456 | log.err("failed to resolve addresses to source locations: {t}", .{err}); | 457 | log.err("failed to resolve addresses to source locations: {t}", .{err}); |
| 457 | return error.AlreadyReported; | 458 | return error.AlreadyReported; |
| 458 | }; | 459 | }; |
lib/std/Build/Step/InstallArtifact.zig+1-1| ... | @@ -172,7 +172,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -172,7 +172,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 172 | defer src_dir.close(io); | 172 | defer src_dir.close(io); |
| 173 | 173 | ||
| 174 | var it = try src_dir.walk(b.allocator); | 174 | var it = try src_dir.walk(b.allocator); |
| 175 | next_entry: while (try it.next()) |entry| { | 175 | next_entry: while (try it.next(io)) |entry| { |
| 176 | for (dir.options.exclude_extensions) |ext| { | 176 | for (dir.options.exclude_extensions) |ext| { |
| 177 | if (std.mem.endsWith(u8, entry.path, ext)) continue :next_entry; | 177 | if (std.mem.endsWith(u8, entry.path, ext)) continue :next_entry; |
| 178 | } | 178 | } |
lib/std/Build/Step/WriteFile.zig+1-1| ... | @@ -309,7 +309,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { | ... | @@ -309,7 +309,7 @@ fn make(step: *Step, options: Step.MakeOptions) !void { |
| 309 | 309 | ||
| 310 | var it = try already_open_dir.walk(gpa); | 310 | var it = try already_open_dir.walk(gpa); |
| 311 | defer it.deinit(); | 311 | defer it.deinit(); |
| 312 | while (try it.next()) |entry| { | 312 | while (try it.next(io)) |entry| { |
| 313 | if (!dir.options.pathIncluded(entry.path)) continue; | 313 | if (!dir.options.pathIncluded(entry.path)) continue; |
| 314 | 314 | ||
| 315 | const src_entry_path = try src_dir_path.join(arena, entry.path); | 315 | const src_entry_path = try src_dir_path.join(arena, entry.path); |
lib/std/Io/Dir.zig+4-4| ... | @@ -574,7 +574,7 @@ pub fn updateFile( | ... | @@ -574,7 +574,7 @@ pub fn updateFile( |
| 574 | error.WriteFailed => return atomic_file.file_writer.err.?, | 574 | error.WriteFailed => return atomic_file.file_writer.err.?, |
| 575 | }; | 575 | }; |
| 576 | try atomic_file.flush(); | 576 | try atomic_file.flush(); |
| 577 | try atomic_file.file_writer.file.updateTimes(src_stat.atime, src_stat.mtime); | 577 | try atomic_file.file_writer.file.setTimestamps(io, src_stat.atime, src_stat.mtime); |
| 578 | try atomic_file.renameIntoPlace(); | 578 | try atomic_file.renameIntoPlace(); |
| 579 | return .stale; | 579 | return .stale; |
| 580 | } | 580 | } |
| ... | @@ -1238,7 +1238,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { | ... | @@ -1238,7 +1238,7 @@ pub fn deleteTree(dir: Dir, io: Io, sub_path: []const u8) DeleteTreeError!void { |
| 1238 | 1238 | ||
| 1239 | process_stack: while (stack.items.len != 0) { | 1239 | process_stack: while (stack.items.len != 0) { |
| 1240 | var top = &stack.items[stack.items.len - 1]; | 1240 | var top = &stack.items[stack.items.len - 1]; |
| 1241 | while (try top.iter.next()) |entry| { | 1241 | while (try top.iter.next(io)) |entry| { |
| 1242 | var treat_as_dir = entry.kind == .directory; | 1242 | var treat_as_dir = entry.kind == .directory; |
| 1243 | handle_entry: while (true) { | 1243 | handle_entry: while (true) { |
| 1244 | if (treat_as_dir) { | 1244 | if (treat_as_dir) { |
| ... | @@ -1695,9 +1695,9 @@ pub fn atomicFile(parent: Dir, io: Io, dest_path: []const u8, options: AtomicFil | ... | @@ -1695,9 +1695,9 @@ pub fn atomicFile(parent: Dir, io: Io, dest_path: []const u8, options: AtomicFil |
| 1695 | else | 1695 | else |
| 1696 | try parent.openDir(io, dirname, .{}); | 1696 | try parent.openDir(io, dirname, .{}); |
| 1697 | 1697 | ||
| 1698 | return .init(path.basename(dest_path), options.permissions, dir, true, options.write_buffer); | 1698 | return .init(io, path.basename(dest_path), options.permissions, dir, true, options.write_buffer); |
| 1699 | } else { | 1699 | } else { |
| 1700 | return .init(dest_path, options.permissions, parent, false, options.write_buffer); | 1700 | return .init(io, dest_path, options.permissions, parent, false, options.write_buffer); |
| 1701 | } | 1701 | } |
| 1702 | } | 1702 | } |
| 1703 | 1703 |
lib/std/Io/File.zig+1-1| ... | @@ -460,7 +460,7 @@ pub fn setTimestamps( | ... | @@ -460,7 +460,7 @@ pub fn setTimestamps( |
| 460 | last_accessed: Io.Timestamp, | 460 | last_accessed: Io.Timestamp, |
| 461 | last_modified: Io.Timestamp, | 461 | last_modified: Io.Timestamp, |
| 462 | ) SetTimestampsError!void { | 462 | ) SetTimestampsError!void { |
| 463 | return io.vtable.fileUpdateTimes(io.userdata, file, last_accessed, last_modified); | 463 | return io.vtable.fileSetTimestamps(io.userdata, file, last_accessed, last_modified); |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | /// Sets the accessed and modification timestamps of `file` to the current wall | 466 | /// Sets the accessed and modification timestamps of `file` to the current wall |
lib/std/Io/File/Atomic.zig+1-1| ... | @@ -66,7 +66,7 @@ pub fn deinit(af: *Atomic) void { | ... | @@ -66,7 +66,7 @@ pub fn deinit(af: *Atomic) void { |
| 66 | af.* = undefined; | 66 | af.* = undefined; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | pub const FlushError = File.WriteError; | 69 | pub const FlushError = File.Writer.Error; |
| 70 | 70 | ||
| 71 | pub fn flush(af: *Atomic) FlushError!void { | 71 | pub fn flush(af: *Atomic) FlushError!void { |
| 72 | af.file_writer.interface.flush() catch |err| switch (err) { | 72 | af.file_writer.interface.flush() catch |err| switch (err) { |
lib/std/Io/File/Writer.zig+5-4| ... | @@ -158,7 +158,7 @@ pub fn sendFile(io_w: *Io.Writer, file_reader: *Io.File.Reader, limit: Io.Limit) | ... | @@ -158,7 +158,7 @@ pub fn sendFile(io_w: *Io.Writer, file_reader: *Io.File.Reader, limit: Io.Limit) |
| 158 | fn sendFilePositional(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) Io.Writer.FileError!usize { | 158 | fn sendFilePositional(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) Io.Writer.FileError!usize { |
| 159 | const io = w.io; | 159 | const io = w.io; |
| 160 | const header = w.interface.buffered(); | 160 | const header = w.interface.buffered(); |
| 161 | const n = io.vtable.fileSendFilePositional(io.userdata, w.file, header, file_reader, limit, w.pos) catch |err| switch (err) { | 161 | const n = io.vtable.fileWriteFilePositional(io.userdata, w.file, header, file_reader, limit, w.pos) catch |err| switch (err) { |
| 162 | error.Unseekable => { | 162 | error.Unseekable => { |
| 163 | w.mode = w.mode.toStreaming(); | 163 | w.mode = w.mode.toStreaming(); |
| 164 | const pos = w.pos; | 164 | const pos = w.pos; |
| ... | @@ -187,7 +187,7 @@ fn sendFilePositional(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) | ... | @@ -187,7 +187,7 @@ fn sendFilePositional(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) |
| 187 | fn sendFileStreaming(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) Io.Writer.FileError!usize { | 187 | fn sendFileStreaming(w: *Writer, file_reader: *Io.File.Reader, limit: Io.Limit) Io.Writer.FileError!usize { |
| 188 | const io = w.io; | 188 | const io = w.io; |
| 189 | const header = w.interface.buffered(); | 189 | const header = w.interface.buffered(); |
| 190 | const n = io.vtable.fileSendFileStreaming(io.userdata, w.file, header, file_reader, limit) catch |err| switch (err) { | 190 | const n = io.vtable.fileWriteFileStreaming(io.userdata, w.file, header, file_reader, limit) catch |err| switch (err) { |
| 191 | error.Canceled => { | 191 | error.Canceled => { |
| 192 | w.err = error.Canceled; | 192 | w.err = error.Canceled; |
| 193 | return error.WriteFailed; | 193 | return error.WriteFailed; |
| ... | @@ -226,7 +226,7 @@ pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { | ... | @@ -226,7 +226,7 @@ pub fn seekToUnbuffered(w: *Writer, offset: u64) SeekError!void { |
| 226 | } | 226 | } |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | pub const EndError = File.SetEndPosError || Io.Writer.Error; | 229 | pub const EndError = File.SetLengthError || Io.Writer.Error; |
| 230 | 230 | ||
| 231 | /// Flushes any buffered data and sets the end position of the file. | 231 | /// Flushes any buffered data and sets the end position of the file. |
| 232 | /// | 232 | /// |
| ... | @@ -236,11 +236,12 @@ pub const EndError = File.SetEndPosError || Io.Writer.Error; | ... | @@ -236,11 +236,12 @@ pub const EndError = File.SetEndPosError || Io.Writer.Error; |
| 236 | /// Flush failure is handled by setting `err` so that it can be handled | 236 | /// Flush failure is handled by setting `err` so that it can be handled |
| 237 | /// along with other write failures. | 237 | /// along with other write failures. |
| 238 | pub fn end(w: *Writer) EndError!void { | 238 | pub fn end(w: *Writer) EndError!void { |
| 239 | const io = w.io; | ||
| 239 | try w.interface.flush(); | 240 | try w.interface.flush(); |
| 240 | switch (w.mode) { | 241 | switch (w.mode) { |
| 241 | .positional, | 242 | .positional, |
| 242 | .positional_reading, | 243 | .positional_reading, |
| 243 | => w.file.setLength(w.pos) catch |err| switch (err) { | 244 | => w.file.setLength(io, w.pos) catch |err| switch (err) { |
| 244 | error.NonResizable => return, | 245 | error.NonResizable => return, |
| 245 | else => |e| return e, | 246 | else => |e| return e, |
| 246 | }, | 247 | }, |
lib/std/Io/Threaded.zig+16-16| ... | @@ -4,8 +4,6 @@ const builtin = @import("builtin"); | ... | @@ -4,8 +4,6 @@ const builtin = @import("builtin"); |
| 4 | const native_os = builtin.os.tag; | 4 | const native_os = builtin.os.tag; |
| 5 | const is_windows = native_os == .windows; | 5 | const is_windows = native_os == .windows; |
| 6 | const is_darwin = native_os.isDarwin(); | 6 | const is_darwin = native_os.isDarwin(); |
| 7 | const windows = std.os.windows; | ||
| 8 | const ws2_32 = std.os.windows.ws2_32; | ||
| 9 | const is_debug = builtin.mode == .Debug; | 7 | const is_debug = builtin.mode == .Debug; |
| 10 | 8 | ||
| 11 | const std = @import("../std.zig"); | 9 | const std = @import("../std.zig"); |
| ... | @@ -19,6 +17,8 @@ const Allocator = std.mem.Allocator; | ... | @@ -19,6 +17,8 @@ const Allocator = std.mem.Allocator; |
| 19 | const Alignment = std.mem.Alignment; | 17 | const Alignment = std.mem.Alignment; |
| 20 | const assert = std.debug.assert; | 18 | const assert = std.debug.assert; |
| 21 | const posix = std.posix; | 19 | const posix = std.posix; |
| 20 | const windows = std.os.windows; | ||
| 21 | const ws2_32 = std.os.windows.ws2_32; | ||
| 22 | 22 | ||
| 23 | /// Thread-safe. | 23 | /// Thread-safe. |
| 24 | allocator: Allocator, | 24 | allocator: Allocator, |
| ... | @@ -1452,7 +1452,7 @@ const dirMake = switch (native_os) { | ... | @@ -1452,7 +1452,7 @@ const dirMake = switch (native_os) { |
| 1452 | else => dirMakePosix, | 1452 | else => dirMakePosix, |
| 1453 | }; | 1453 | }; |
| 1454 | 1454 | ||
| 1455 | fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.MakeError!void { | 1455 | fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { |
| 1456 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1456 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1457 | const current_thread = Thread.getCurrent(t); | 1457 | const current_thread = Thread.getCurrent(t); |
| 1458 | 1458 | ||
| ... | @@ -1461,7 +1461,7 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir | ... | @@ -1461,7 +1461,7 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir |
| 1461 | 1461 | ||
| 1462 | try current_thread.beginSyscall(); | 1462 | try current_thread.beginSyscall(); |
| 1463 | while (true) { | 1463 | while (true) { |
| 1464 | switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, mode))) { | 1464 | switch (posix.errno(posix.system.mkdirat(dir.handle, sub_path_posix, permissions.toMode()))) { |
| 1465 | .SUCCESS => { | 1465 | .SUCCESS => { |
| 1466 | current_thread.endSyscall(); | 1466 | current_thread.endSyscall(); |
| 1467 | return; | 1467 | return; |
| ... | @@ -1498,8 +1498,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir | ... | @@ -1498,8 +1498,8 @@ fn dirMakePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir |
| 1498 | } | 1498 | } |
| 1499 | } | 1499 | } |
| 1500 | 1500 | ||
| 1501 | fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.MakeError!void { | 1501 | fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { |
| 1502 | if (builtin.link_libc) return dirMakePosix(userdata, dir, sub_path, mode); | 1502 | if (builtin.link_libc) return dirMakePosix(userdata, dir, sub_path, permissions); |
| 1503 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1503 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1504 | const current_thread = Thread.getCurrent(t); | 1504 | const current_thread = Thread.getCurrent(t); |
| 1505 | try current_thread.beginSyscall(); | 1505 | try current_thread.beginSyscall(); |
| ... | @@ -1540,13 +1540,13 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir. | ... | @@ -1540,13 +1540,13 @@ fn dirMakeWasi(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir. |
| 1540 | } | 1540 | } |
| 1541 | } | 1541 | } |
| 1542 | 1542 | ||
| 1543 | fn dirMakeWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, mode: Dir.Mode) Dir.MakeError!void { | 1543 | fn dirMakeWindows(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, permissions: Dir.Permissions) Dir.MakeError!void { |
| 1544 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1544 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1545 | const current_thread = Thread.getCurrent(t); | 1545 | const current_thread = Thread.getCurrent(t); |
| 1546 | try current_thread.checkCancel(); | 1546 | try current_thread.checkCancel(); |
| 1547 | 1547 | ||
| 1548 | const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path); | 1548 | const sub_path_w = try windows.sliceToPrefixedFileW(dir.handle, sub_path); |
| 1549 | _ = mode; | 1549 | _ = permissions; // TODO use this value |
| 1550 | const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{ | 1550 | const sub_dir_handle = windows.OpenFile(sub_path_w.span(), .{ |
| 1551 | .dir = dir.handle, | 1551 | .dir = dir.handle, |
| 1552 | .access_mask = .{ | 1552 | .access_mask = .{ |
| ... | @@ -1570,7 +1570,7 @@ fn dirMakePath( | ... | @@ -1570,7 +1570,7 @@ fn dirMakePath( |
| 1570 | userdata: ?*anyopaque, | 1570 | userdata: ?*anyopaque, |
| 1571 | dir: Dir, | 1571 | dir: Dir, |
| 1572 | sub_path: []const u8, | 1572 | sub_path: []const u8, |
| 1573 | mode: Dir.Mode, | 1573 | permissions: Dir.Permissions, |
| 1574 | ) Dir.MakePathError!Dir.MakePathStatus { | 1574 | ) Dir.MakePathError!Dir.MakePathStatus { |
| 1575 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 1575 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 1576 | 1576 | ||
| ... | @@ -1578,7 +1578,7 @@ fn dirMakePath( | ... | @@ -1578,7 +1578,7 @@ fn dirMakePath( |
| 1578 | var status: Dir.MakePathStatus = .existed; | 1578 | var status: Dir.MakePathStatus = .existed; |
| 1579 | var component = it.last() orelse return error.BadPathName; | 1579 | var component = it.last() orelse return error.BadPathName; |
| 1580 | while (true) { | 1580 | while (true) { |
| 1581 | if (dirMake(t, dir, component.path, mode)) |_| { | 1581 | if (dirMake(t, dir, component.path, permissions)) |_| { |
| 1582 | status = .created; | 1582 | status = .created; |
| 1583 | } else |err| switch (err) { | 1583 | } else |err| switch (err) { |
| 1584 | error.PathAlreadyExists => { | 1584 | error.PathAlreadyExists => { |
| ... | @@ -4945,7 +4945,7 @@ fn dirSetTimestamps( | ... | @@ -4945,7 +4945,7 @@ fn dirSetTimestamps( |
| 4945 | sub_path: []const u8, | 4945 | sub_path: []const u8, |
| 4946 | last_accessed: Io.Timestamp, | 4946 | last_accessed: Io.Timestamp, |
| 4947 | last_modified: Io.Timestamp, | 4947 | last_modified: Io.Timestamp, |
| 4948 | options: File.SetTimestampsOptions, | 4948 | options: Dir.SetTimestampsOptions, |
| 4949 | ) File.SetTimestampsError!void { | 4949 | ) File.SetTimestampsError!void { |
| 4950 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 4950 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 4951 | const current_thread = Thread.getCurrent(t); | 4951 | const current_thread = Thread.getCurrent(t); |
| ... | @@ -4997,7 +4997,7 @@ fn dirSetTimestampsNow( | ... | @@ -4997,7 +4997,7 @@ fn dirSetTimestampsNow( |
| 4997 | userdata: ?*anyopaque, | 4997 | userdata: ?*anyopaque, |
| 4998 | dir: Dir, | 4998 | dir: Dir, |
| 4999 | sub_path: []const u8, | 4999 | sub_path: []const u8, |
| 5000 | options: File.SetTimestampsOptions, | 5000 | options: Dir.SetTimestampsOptions, |
| 5001 | ) File.SetTimestampsError!void { | 5001 | ) File.SetTimestampsError!void { |
| 5002 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 5002 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 5003 | const current_thread = Thread.getCurrent(t); | 5003 | const current_thread = Thread.getCurrent(t); |
| ... | @@ -6271,7 +6271,7 @@ fn fileWriteStreaming( | ... | @@ -6271,7 +6271,7 @@ fn fileWriteStreaming( |
| 6271 | header: []const u8, | 6271 | header: []const u8, |
| 6272 | data: []const []const u8, | 6272 | data: []const []const u8, |
| 6273 | splat: usize, | 6273 | splat: usize, |
| 6274 | ) File.WriteStreamingError!usize { | 6274 | ) File.Writer.Error!usize { |
| 6275 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 6275 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 6276 | const current_thread = Thread.getCurrent(t); | 6276 | const current_thread = Thread.getCurrent(t); |
| 6277 | 6277 | ||
| ... | @@ -9690,7 +9690,7 @@ fn statFromLinux(stx: *const std.os.linux.Statx) File.Stat { | ... | @@ -9690,7 +9690,7 @@ fn statFromLinux(stx: *const std.os.linux.Statx) File.Stat { |
| 9690 | return .{ | 9690 | return .{ |
| 9691 | .inode = stx.ino, | 9691 | .inode = stx.ino, |
| 9692 | .size = stx.size, | 9692 | .size = stx.size, |
| 9693 | .mode = stx.mode, | 9693 | .permissions = .fromMode(stx.mode), |
| 9694 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { | 9694 | .kind = switch (stx.mode & std.os.linux.S.IFMT) { |
| 9695 | std.os.linux.S.IFDIR => .directory, | 9695 | std.os.linux.S.IFDIR => .directory, |
| 9696 | std.os.linux.S.IFCHR => .character_device, | 9696 | std.os.linux.S.IFCHR => .character_device, |
| ... | @@ -9714,7 +9714,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { | ... | @@ -9714,7 +9714,7 @@ fn statFromPosix(st: *const posix.Stat) File.Stat { |
| 9714 | return .{ | 9714 | return .{ |
| 9715 | .inode = st.ino, | 9715 | .inode = st.ino, |
| 9716 | .size = @bitCast(st.size), | 9716 | .size = @bitCast(st.size), |
| 9717 | .mode = st.mode, | 9717 | .permissions = .fromMode(st.mode), |
| 9718 | .kind = k: { | 9718 | .kind = k: { |
| 9719 | const m = st.mode & posix.S.IFMT; | 9719 | const m = st.mode & posix.S.IFMT; |
| 9720 | switch (m) { | 9720 | switch (m) { |
| ... | @@ -10019,7 +10019,7 @@ fn lookupHosts( | ... | @@ -10019,7 +10019,7 @@ fn lookupHosts( |
| 10019 | options: HostName.LookupOptions, | 10019 | options: HostName.LookupOptions, |
| 10020 | ) !void { | 10020 | ) !void { |
| 10021 | const t_io = io(t); | 10021 | const t_io = io(t); |
| 10022 | const file = File.openAbsolute(t_io, "/etc/hosts", .{}) catch |err| switch (err) { | 10022 | const file = Dir.openFileAbsolute(t_io, "/etc/hosts", .{}) catch |err| switch (err) { |
| 10023 | error.FileNotFound, | 10023 | error.FileNotFound, |
| 10024 | error.NotDir, | 10024 | error.NotDir, |
| 10025 | error.AccessDenied, | 10025 | error.AccessDenied, |
lib/std/Io/net/HostName.zig+1-1| ... | @@ -343,7 +343,7 @@ pub const ResolvConf = struct { | ... | @@ -343,7 +343,7 @@ pub const ResolvConf = struct { |
| 343 | .attempts = 2, | 343 | .attempts = 2, |
| 344 | }; | 344 | }; |
| 345 | 345 | ||
| 346 | const file = Io.File.openAbsolute(io, "/etc/resolv.conf", .{}) catch |err| switch (err) { | 346 | const file = Io.Dir.openFileAbsolute(io, "/etc/resolv.conf", .{}) catch |err| switch (err) { |
| 347 | error.FileNotFound, | 347 | error.FileNotFound, |
| 348 | error.NotDir, | 348 | error.NotDir, |
| 349 | error.AccessDenied, | 349 | error.AccessDenied, |
lib/std/Io/test.zig+3-2| ... | @@ -114,7 +114,7 @@ test "setEndPos" { | ... | @@ -114,7 +114,7 @@ test "setEndPos" { |
| 114 | try expect((try file.getPos()) == 100); | 114 | try expect((try file.getPos()) == 100); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | test "updateTimes" { | 117 | test "setTimestamps" { |
| 118 | const io = testing.io; | 118 | const io = testing.io; |
| 119 | 119 | ||
| 120 | var tmp = tmpDir(.{}); | 120 | var tmp = tmpDir(.{}); |
| ... | @@ -126,7 +126,8 @@ test "updateTimes" { | ... | @@ -126,7 +126,8 @@ test "updateTimes" { |
| 126 | 126 | ||
| 127 | const stat_old = try file.stat(io); | 127 | const stat_old = try file.stat(io); |
| 128 | // Set atime and mtime to 5s before | 128 | // Set atime and mtime to 5s before |
| 129 | try file.updateTimes( | 129 | try file.setTimestamps( |
| 130 | io, | ||
| 130 | stat_old.atime.subDuration(.fromSeconds(5)), | 131 | stat_old.atime.subDuration(.fromSeconds(5)), |
| 131 | stat_old.mtime.subDuration(.fromSeconds(5)), | 132 | stat_old.mtime.subDuration(.fromSeconds(5)), |
| 132 | ); | 133 | ); |
lib/std/Io/tty.zig+5-4| ... | @@ -2,6 +2,7 @@ const builtin = @import("builtin"); | ... | @@ -2,6 +2,7 @@ const builtin = @import("builtin"); |
| 2 | const native_os = builtin.os.tag; | 2 | const native_os = builtin.os.tag; |
| 3 | 3 | ||
| 4 | const std = @import("std"); | 4 | const std = @import("std"); |
| 5 | const Io = std.Io; | ||
| 5 | const File = std.Io.File; | 6 | const File = std.Io.File; |
| 6 | const process = std.process; | 7 | const process = std.process; |
| 7 | const windows = std.os.windows; | 8 | const windows = std.os.windows; |
| ... | @@ -39,7 +40,7 @@ pub const Config = union(enum) { | ... | @@ -39,7 +40,7 @@ pub const Config = union(enum) { |
| 39 | /// This includes feature checks for ANSI escape codes and the Windows console API, as well as | 40 | /// This includes feature checks for ANSI escape codes and the Windows console API, as well as |
| 40 | /// respecting the `NO_COLOR` and `CLICOLOR_FORCE` environment variables to override the default. | 41 | /// respecting the `NO_COLOR` and `CLICOLOR_FORCE` environment variables to override the default. |
| 41 | /// Will attempt to enable ANSI escape code support if necessary/possible. | 42 | /// Will attempt to enable ANSI escape code support if necessary/possible. |
| 42 | pub fn detect(file: File) Config { | 43 | pub fn detect(io: Io, file: File) Config { |
| 43 | const force_color: ?bool = if (builtin.os.tag == .wasi) | 44 | const force_color: ?bool = if (builtin.os.tag == .wasi) |
| 44 | null // wasi does not support environment variables | 45 | null // wasi does not support environment variables |
| 45 | else if (process.hasNonEmptyEnvVarConstant("NO_COLOR")) | 46 | else if (process.hasNonEmptyEnvVarConstant("NO_COLOR")) |
| ... | @@ -51,7 +52,7 @@ pub const Config = union(enum) { | ... | @@ -51,7 +52,7 @@ pub const Config = union(enum) { |
| 51 | 52 | ||
| 52 | if (force_color == false) return .no_color; | 53 | if (force_color == false) return .no_color; |
| 53 | 54 | ||
| 54 | if (file.enableAnsiEscapeCodes()) |_| { | 55 | if (file.enableAnsiEscapeCodes(io)) |_| { |
| 55 | return .escape_codes; | 56 | return .escape_codes; |
| 56 | } else |_| {} | 57 | } else |_| {} |
| 57 | 58 | ||
| ... | @@ -74,9 +75,9 @@ pub const Config = union(enum) { | ... | @@ -74,9 +75,9 @@ pub const Config = union(enum) { |
| 74 | reset_attributes: u16, | 75 | reset_attributes: u16, |
| 75 | }; | 76 | }; |
| 76 | 77 | ||
| 77 | pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || std.Io.Writer.Error; | 78 | pub const SetColorError = std.os.windows.SetConsoleTextAttributeError || Io.Writer.Error; |
| 78 | 79 | ||
| 79 | pub fn setColor(conf: Config, w: *std.Io.Writer, color: Color) SetColorError!void { | 80 | pub fn setColor(conf: Config, w: *Io.Writer, color: Color) SetColorError!void { |
| 80 | nosuspend switch (conf) { | 81 | nosuspend switch (conf) { |
| 81 | .no_color => return, | 82 | .no_color => return, |
| 82 | .escape_codes => { | 83 | .escape_codes => { |
lib/std/debug.zig+3-1| ... | @@ -286,11 +286,13 @@ pub fn unlockStdErr() void { | ... | @@ -286,11 +286,13 @@ pub fn unlockStdErr() void { |
| 286 | pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } { | 286 | pub fn lockStderrWriter(buffer: []u8) struct { *Writer, tty.Config } { |
| 287 | const global = struct { | 287 | const global = struct { |
| 288 | var conf: ?tty.Config = null; | 288 | var conf: ?tty.Config = null; |
| 289 | var single_threaded_io: Io.Threaded = .init_single_threaded; | ||
| 289 | }; | 290 | }; |
| 291 | const io = global.single_threaded_io.io(); | ||
| 290 | const w = std.Progress.lockStderrWriter(buffer); | 292 | const w = std.Progress.lockStderrWriter(buffer); |
| 291 | // The stderr lock also locks access to `global.conf`. | 293 | // The stderr lock also locks access to `global.conf`. |
| 292 | if (global.conf == null) { | 294 | if (global.conf == null) { |
| 293 | global.conf = .detect(.stderr()); | 295 | global.conf = .detect(io, .stderr()); |
| 294 | } | 296 | } |
| 295 | return .{ w, global.conf.? }; | 297 | return .{ w, global.conf.? }; |
| 296 | } | 298 | } |
lib/std/debug/Info.zig+4-3| ... | @@ -42,7 +42,7 @@ pub fn load( | ... | @@ -42,7 +42,7 @@ pub fn load( |
| 42 | var file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); | 42 | var file = try path.root_dir.handle.openFile(io, path.sub_path, .{}); |
| 43 | defer file.close(io); | 43 | defer file.close(io); |
| 44 | 44 | ||
| 45 | var elf_file: ElfFile = try .load(gpa, file, null, &.none); | 45 | var elf_file: ElfFile = try .load(gpa, io, file, null, &.none); |
| 46 | errdefer elf_file.deinit(gpa); | 46 | errdefer elf_file.deinit(gpa); |
| 47 | 47 | ||
| 48 | if (elf_file.dwarf == null) return error.MissingDebugInfo; | 48 | if (elf_file.dwarf == null) return error.MissingDebugInfo; |
| ... | @@ -58,7 +58,7 @@ pub fn load( | ... | @@ -58,7 +58,7 @@ pub fn load( |
| 58 | const path_str = try path.toString(gpa); | 58 | const path_str = try path.toString(gpa); |
| 59 | defer gpa.free(path_str); | 59 | defer gpa.free(path_str); |
| 60 | 60 | ||
| 61 | var macho_file: MachOFile = try .load(gpa, path_str, arch); | 61 | var macho_file: MachOFile = try .load(gpa, io, path_str, arch); |
| 62 | errdefer macho_file.deinit(gpa); | 62 | errdefer macho_file.deinit(gpa); |
| 63 | 63 | ||
| 64 | return .{ | 64 | return .{ |
| ... | @@ -85,6 +85,7 @@ pub const ResolveAddressesError = Coverage.ResolveAddressesDwarfError || error{U | ... | @@ -85,6 +85,7 @@ pub const ResolveAddressesError = Coverage.ResolveAddressesDwarfError || error{U |
| 85 | pub fn resolveAddresses( | 85 | pub fn resolveAddresses( |
| 86 | info: *Info, | 86 | info: *Info, |
| 87 | gpa: Allocator, | 87 | gpa: Allocator, |
| 88 | io: Io, | ||
| 88 | /// Asserts the addresses are in ascending order. | 89 | /// Asserts the addresses are in ascending order. |
| 89 | sorted_pc_addrs: []const u64, | 90 | sorted_pc_addrs: []const u64, |
| 90 | /// Asserts its length equals length of `sorted_pc_addrs`. | 91 | /// Asserts its length equals length of `sorted_pc_addrs`. |
| ... | @@ -97,7 +98,7 @@ pub fn resolveAddresses( | ... | @@ -97,7 +98,7 @@ pub fn resolveAddresses( |
| 97 | // Resolving all of the addresses at once unfortunately isn't so easy in Mach-O binaries | 98 | // Resolving all of the addresses at once unfortunately isn't so easy in Mach-O binaries |
| 98 | // due to split debug information. For now, we'll just resolve the addreses one by one. | 99 | // due to split debug information. For now, we'll just resolve the addreses one by one. |
| 99 | for (sorted_pc_addrs, output) |pc_addr, *src_loc| { | 100 | for (sorted_pc_addrs, output) |pc_addr, *src_loc| { |
| 100 | const dwarf, const dwarf_pc_addr = mf.getDwarfForAddress(gpa, pc_addr) catch |err| switch (err) { | 101 | const dwarf, const dwarf_pc_addr = mf.getDwarfForAddress(gpa, io, pc_addr) catch |err| switch (err) { |
| 101 | error.InvalidMachO, error.InvalidDwarf => return error.InvalidDebugInfo, | 102 | error.InvalidMachO, error.InvalidDwarf => return error.InvalidDebugInfo, |
| 102 | else => |e| return e, | 103 | else => |e| return e, |
| 103 | }; | 104 | }; |
lib/std/heap/debug_allocator.zig+27-12| ... | @@ -179,6 +179,8 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -179,6 +179,8 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 179 | total_requested_bytes: @TypeOf(total_requested_bytes_init) = total_requested_bytes_init, | 179 | total_requested_bytes: @TypeOf(total_requested_bytes_init) = total_requested_bytes_init, |
| 180 | requested_memory_limit: @TypeOf(requested_memory_limit_init) = requested_memory_limit_init, | 180 | requested_memory_limit: @TypeOf(requested_memory_limit_init) = requested_memory_limit_init, |
| 181 | mutex: @TypeOf(mutex_init) = mutex_init, | 181 | mutex: @TypeOf(mutex_init) = mutex_init, |
| 182 | /// Set this value differently to affect how errors and leaks are logged. | ||
| 183 | tty_config: std.Io.tty.Config = .no_color, | ||
| 182 | 184 | ||
| 183 | const Self = @This(); | 185 | const Self = @This(); |
| 184 | 186 | ||
| ... | @@ -458,9 +460,9 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -458,9 +460,9 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 458 | 460 | ||
| 459 | /// Emits log messages for leaks and then returns the number of detected leaks (0 if no leaks were detected). | 461 | /// Emits log messages for leaks and then returns the number of detected leaks (0 if no leaks were detected). |
| 460 | pub fn detectLeaks(self: *Self) usize { | 462 | pub fn detectLeaks(self: *Self) usize { |
| 461 | var leaks: usize = 0; | 463 | const tty_config = self.tty_config; |
| 462 | 464 | ||
| 463 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 465 | var leaks: usize = 0; |
| 464 | 466 | ||
| 465 | for (self.buckets, 0..) |init_optional_bucket, size_class_index| { | 467 | for (self.buckets, 0..) |init_optional_bucket, size_class_index| { |
| 466 | var optional_bucket = init_optional_bucket; | 468 | var optional_bucket = init_optional_bucket; |
| ... | @@ -533,10 +535,15 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -533,10 +535,15 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 533 | @memset(addr_buf[@min(st.index, addr_buf.len)..], 0); | 535 | @memset(addr_buf[@min(st.index, addr_buf.len)..], 0); |
| 534 | } | 536 | } |
| 535 | 537 | ||
| 536 | fn reportDoubleFree(ret_addr: usize, alloc_stack_trace: StackTrace, free_stack_trace: StackTrace) void { | 538 | fn reportDoubleFree( |
| 539 | tty_config: std.Io.tty.Config, | ||
| 540 | ret_addr: usize, | ||
| 541 | alloc_stack_trace: StackTrace, | ||
| 542 | free_stack_trace: StackTrace, | ||
| 543 | ) void { | ||
| 544 | @branchHint(.cold); | ||
| 537 | var addr_buf: [stack_n]usize = undefined; | 545 | var addr_buf: [stack_n]usize = undefined; |
| 538 | const second_free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); | 546 | const second_free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); |
| 539 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | ||
| 540 | log.err("Double free detected. Allocation: {f} First free: {f} Second free: {f}", .{ | 547 | log.err("Double free detected. Allocation: {f} First free: {f} Second free: {f}", .{ |
| 541 | std.debug.FormatStackTrace{ | 548 | std.debug.FormatStackTrace{ |
| 542 | .stack_trace = alloc_stack_trace, | 549 | .stack_trace = alloc_stack_trace, |
| ... | @@ -580,7 +587,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -580,7 +587,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 580 | 587 | ||
| 581 | if (config.retain_metadata and entry.value_ptr.freed) { | 588 | if (config.retain_metadata and entry.value_ptr.freed) { |
| 582 | if (config.safety) { | 589 | if (config.safety) { |
| 583 | reportDoubleFree(ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free)); | 590 | reportDoubleFree(self.tty_config, ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free)); |
| 584 | @panic("Unrecoverable double free"); | 591 | @panic("Unrecoverable double free"); |
| 585 | } else { | 592 | } else { |
| 586 | unreachable; | 593 | unreachable; |
| ... | @@ -588,9 +595,10 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -588,9 +595,10 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 588 | } | 595 | } |
| 589 | 596 | ||
| 590 | if (config.safety and old_mem.len != entry.value_ptr.bytes.len) { | 597 | if (config.safety and old_mem.len != entry.value_ptr.bytes.len) { |
| 598 | @branchHint(.cold); | ||
| 591 | var addr_buf: [stack_n]usize = undefined; | 599 | var addr_buf: [stack_n]usize = undefined; |
| 592 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); | 600 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); |
| 593 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 601 | const tty_config = self.tty_config; |
| 594 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ | 602 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 595 | entry.value_ptr.bytes.len, | 603 | entry.value_ptr.bytes.len, |
| 596 | old_mem.len, | 604 | old_mem.len, |
| ... | @@ -693,7 +701,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -693,7 +701,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 693 | 701 | ||
| 694 | if (config.retain_metadata and entry.value_ptr.freed) { | 702 | if (config.retain_metadata and entry.value_ptr.freed) { |
| 695 | if (config.safety) { | 703 | if (config.safety) { |
| 696 | reportDoubleFree(ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free)); | 704 | reportDoubleFree(self.tty_config, ret_addr, entry.value_ptr.getStackTrace(.alloc), entry.value_ptr.getStackTrace(.free)); |
| 697 | return; | 705 | return; |
| 698 | } else { | 706 | } else { |
| 699 | unreachable; | 707 | unreachable; |
| ... | @@ -701,9 +709,10 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -701,9 +709,10 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 701 | } | 709 | } |
| 702 | 710 | ||
| 703 | if (config.safety and old_mem.len != entry.value_ptr.bytes.len) { | 711 | if (config.safety and old_mem.len != entry.value_ptr.bytes.len) { |
| 712 | @branchHint(.cold); | ||
| 704 | var addr_buf: [stack_n]usize = undefined; | 713 | var addr_buf: [stack_n]usize = undefined; |
| 705 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); | 714 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = ret_addr }, &addr_buf); |
| 706 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 715 | const tty_config = self.tty_config; |
| 707 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ | 716 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 708 | entry.value_ptr.bytes.len, | 717 | entry.value_ptr.bytes.len, |
| 709 | old_mem.len, | 718 | old_mem.len, |
| ... | @@ -915,6 +924,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -915,6 +924,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 915 | if (!is_used) { | 924 | if (!is_used) { |
| 916 | if (config.safety) { | 925 | if (config.safety) { |
| 917 | reportDoubleFree( | 926 | reportDoubleFree( |
| 927 | self.tty_config, | ||
| 918 | return_address, | 928 | return_address, |
| 919 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 929 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
| 920 | bucketStackTrace(bucket, slot_count, slot_index, .free), | 930 | bucketStackTrace(bucket, slot_count, slot_index, .free), |
| ... | @@ -935,7 +945,8 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -935,7 +945,8 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 935 | var addr_buf: [stack_n]usize = undefined; | 945 | var addr_buf: [stack_n]usize = undefined; |
| 936 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = return_address }, &addr_buf); | 946 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = return_address }, &addr_buf); |
| 937 | if (old_memory.len != requested_size) { | 947 | if (old_memory.len != requested_size) { |
| 938 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 948 | @branchHint(.cold); |
| 949 | const tty_config = self.tty_config; | ||
| 939 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ | 950 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 940 | requested_size, | 951 | requested_size, |
| 941 | old_memory.len, | 952 | old_memory.len, |
| ... | @@ -950,7 +961,8 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -950,7 +961,8 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 950 | }); | 961 | }); |
| 951 | } | 962 | } |
| 952 | if (alignment != slot_alignment) { | 963 | if (alignment != slot_alignment) { |
| 953 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 964 | @branchHint(.cold); |
| 965 | const tty_config = self.tty_config; | ||
| 954 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ | 966 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ |
| 955 | slot_alignment.toByteUnits(), | 967 | slot_alignment.toByteUnits(), |
| 956 | alignment.toByteUnits(), | 968 | alignment.toByteUnits(), |
| ... | @@ -1028,6 +1040,7 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -1028,6 +1040,7 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 1028 | const is_used = @as(u1, @truncate(used_byte.* >> used_bit_index)) != 0; | 1040 | const is_used = @as(u1, @truncate(used_byte.* >> used_bit_index)) != 0; |
| 1029 | if (!is_used) { | 1041 | if (!is_used) { |
| 1030 | reportDoubleFree( | 1042 | reportDoubleFree( |
| 1043 | self.tty_config, | ||
| 1031 | return_address, | 1044 | return_address, |
| 1032 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), | 1045 | bucketStackTrace(bucket, slot_count, slot_index, .alloc), |
| 1033 | bucketStackTrace(bucket, slot_count, slot_index, .free), | 1046 | bucketStackTrace(bucket, slot_count, slot_index, .free), |
| ... | @@ -1044,7 +1057,8 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -1044,7 +1057,8 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 1044 | var addr_buf: [stack_n]usize = undefined; | 1057 | var addr_buf: [stack_n]usize = undefined; |
| 1045 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = return_address }, &addr_buf); | 1058 | const free_stack_trace = std.debug.captureCurrentStackTrace(.{ .first_address = return_address }, &addr_buf); |
| 1046 | if (memory.len != requested_size) { | 1059 | if (memory.len != requested_size) { |
| 1047 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 1060 | @branchHint(.cold); |
| 1061 | const tty_config = self.tty_config; | ||
| 1048 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ | 1062 | log.err("Allocation size {d} bytes does not match free size {d}. Allocation: {f} Free: {f}", .{ |
| 1049 | requested_size, | 1063 | requested_size, |
| 1050 | memory.len, | 1064 | memory.len, |
| ... | @@ -1059,7 +1073,8 @@ pub fn DebugAllocator(comptime config: Config) type { | ... | @@ -1059,7 +1073,8 @@ pub fn DebugAllocator(comptime config: Config) type { |
| 1059 | }); | 1073 | }); |
| 1060 | } | 1074 | } |
| 1061 | if (alignment != slot_alignment) { | 1075 | if (alignment != slot_alignment) { |
| 1062 | const tty_config: std.Io.tty.Config = .detect(.stderr()); | 1076 | @branchHint(.cold); |
| 1077 | const tty_config = self.tty_config; | ||
| 1063 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ | 1078 | log.err("Allocation alignment {d} does not match free alignment {d}. Allocation: {f} Free: {f}", .{ |
| 1064 | slot_alignment.toByteUnits(), | 1079 | slot_alignment.toByteUnits(), |
| 1065 | alignment.toByteUnits(), | 1080 | alignment.toByteUnits(), |
lib/std/process/Child.zig+1-1| ... | @@ -470,7 +470,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { | ... | @@ -470,7 +470,7 @@ pub fn run(allocator: Allocator, io: Io, args: struct { |
| 470 | return .{ | 470 | return .{ |
| 471 | .stdout = try stdout.toOwnedSlice(allocator), | 471 | .stdout = try stdout.toOwnedSlice(allocator), |
| 472 | .stderr = try stderr.toOwnedSlice(allocator), | 472 | .stderr = try stderr.toOwnedSlice(allocator), |
| 473 | .term = try child.wait(), | 473 | .term = try child.wait(io), |
| 474 | }; | 474 | }; |
| 475 | } | 475 | } |
| 476 | 476 |
lib/std/zig.zig+2-2| ... | @@ -60,9 +60,9 @@ pub const Color = enum { | ... | @@ -60,9 +60,9 @@ pub const Color = enum { |
| 60 | .off => .no_color, | 60 | .off => .no_color, |
| 61 | }; | 61 | }; |
| 62 | } | 62 | } |
| 63 | pub fn detectTtyConf(color: Color) Io.tty.Config { | 63 | pub fn detectTtyConf(color: Color, io: Io) Io.tty.Config { |
| 64 | return switch (color) { | 64 | return switch (color) { |
| 65 | .auto => .detect(.stderr()), | 65 | .auto => .detect(io, .stderr()), |
| 66 | .on => .escape_codes, | 66 | .on => .escape_codes, |
| 67 | .off => .no_color, | 67 | .off => .no_color, |
| 68 | }; | 68 | }; |
src/link/Dwarf.zig+3-3| ... | @@ -51,10 +51,10 @@ pub const UpdateError = error{ | ... | @@ -51,10 +51,10 @@ pub const UpdateError = error{ |
| 51 | } || | 51 | } || |
| 52 | codegen.GenerateSymbolError || | 52 | codegen.GenerateSymbolError || |
| 53 | Io.File.OpenError || | 53 | Io.File.OpenError || |
| 54 | Io.File.SetEndPosError || | 54 | Io.File.LengthError || |
| 55 | Io.File.CopyRangeError || | 55 | Io.File.CopyRangeError || |
| 56 | Io.File.PReadError || | 56 | Io.File.ReadPositionalError || |
| 57 | Io.File.PWriteError; | 57 | Io.File.WritePositionalError; |
| 58 | 58 | ||
| 59 | pub const FlushError = UpdateError; | 59 | pub const FlushError = UpdateError; |
| 60 | 60 |
src/link/MappedFile.zig+1-1| ... | @@ -28,7 +28,7 @@ writers: std.SinglyLinkedList, | ... | @@ -28,7 +28,7 @@ writers: std.SinglyLinkedList, |
| 28 | 28 | ||
| 29 | pub const growth_factor = 4; | 29 | pub const growth_factor = 4; |
| 30 | 30 | ||
| 31 | pub const Error = std.posix.MMapError || std.posix.MRemapError || Io.File.SetEndPosError || error{ | 31 | pub const Error = std.posix.MMapError || std.posix.MRemapError || Io.File.LengthError || error{ |
| 32 | NotFile, | 32 | NotFile, |
| 33 | SystemResources, | 33 | SystemResources, |
| 34 | IsDir, | 34 | IsDir, |
src/main.zig+14-9| ... | @@ -162,17 +162,20 @@ var debug_allocator: std.heap.DebugAllocator(.{ | ... | @@ -162,17 +162,20 @@ var debug_allocator: std.heap.DebugAllocator(.{ |
| 162 | .stack_trace_frames = build_options.mem_leak_frames, | 162 | .stack_trace_frames = build_options.mem_leak_frames, |
| 163 | }) = .init; | 163 | }) = .init; |
| 164 | 164 | ||
| 165 | const use_debug_allocator = build_options.debug_gpa or | ||
| 166 | (native_os != .wasi and !builtin.link_libc and switch (builtin.mode) { | ||
| 167 | .Debug, .ReleaseSafe => true, | ||
| 168 | .ReleaseFast, .ReleaseSmall => false, | ||
| 169 | }); | ||
| 170 | |||
| 165 | pub fn main() anyerror!void { | 171 | pub fn main() anyerror!void { |
| 166 | const gpa, const is_debug = gpa: { | 172 | const gpa = gpa: { |
| 167 | if (build_options.debug_gpa) break :gpa .{ debug_allocator.allocator(), true }; | 173 | if (use_debug_allocator) break :gpa debug_allocator.allocator(); |
| 168 | if (native_os == .wasi) break :gpa .{ std.heap.wasm_allocator, false }; | 174 | if (native_os == .wasi) break :gpa std.heap.wasm_allocator; |
| 169 | if (builtin.link_libc) break :gpa .{ std.heap.c_allocator, false }; | 175 | if (builtin.link_libc) break :gpa std.heap.c_allocator; |
| 170 | break :gpa switch (builtin.mode) { | 176 | break :gpa std.heap.smp_allocator; |
| 171 | .Debug, .ReleaseSafe => .{ debug_allocator.allocator(), true }, | ||
| 172 | .ReleaseFast, .ReleaseSmall => .{ std.heap.smp_allocator, false }, | ||
| 173 | }; | ||
| 174 | }; | 177 | }; |
| 175 | defer if (is_debug) { | 178 | defer if (use_debug_allocator) { |
| 176 | _ = debug_allocator.deinit(); | 179 | _ = debug_allocator.deinit(); |
| 177 | }; | 180 | }; |
| 178 | var arena_instance = std.heap.ArenaAllocator.init(gpa); | 181 | var arena_instance = std.heap.ArenaAllocator.init(gpa); |
| ... | @@ -244,6 +247,8 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { | ... | @@ -244,6 +247,8 @@ fn mainArgs(gpa: Allocator, arena: Allocator, args: []const []const u8) !void { |
| 244 | threaded.stack_size = thread_stack_size; | 247 | threaded.stack_size = thread_stack_size; |
| 245 | const io = threaded.io(); | 248 | const io = threaded.io(); |
| 246 | 249 | ||
| 250 | debug_allocator.tty_config = .detect(io, .stderr()); | ||
| 251 | |||
| 247 | const cmd = args[1]; | 252 | const cmd = args[1]; |
| 248 | const cmd_args = args[2..]; | 253 | const cmd_args = args[2..]; |
| 249 | if (mem.eql(u8, cmd, "build-exe")) { | 254 | if (mem.eql(u8, cmd, "build-exe")) { |
test/link/macho.zig+2-1| ... | @@ -868,9 +868,10 @@ fn testLayout(b: *Build, opts: Options) *Step { | ... | @@ -868,9 +868,10 @@ fn testLayout(b: *Build, opts: Options) *Step { |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | fn testLinkDirectlyCppTbd(b: *Build, opts: Options) *Step { | 870 | fn testLinkDirectlyCppTbd(b: *Build, opts: Options) *Step { |
| 871 | const io = b.graph.io; | ||
| 871 | const test_step = addTestStep(b, "link-directly-cpp-tbd", opts); | 872 | const test_step = addTestStep(b, "link-directly-cpp-tbd", opts); |
| 872 | 873 | ||
| 873 | const sdk = std.zig.system.darwin.getSdk(b.allocator, &opts.target.result) orelse | 874 | const sdk = std.zig.system.darwin.getSdk(b.allocator, io, &opts.target.result) orelse |
| 874 | @panic("macOS SDK is required to run the test"); | 875 | @panic("macOS SDK is required to run the test"); |
| 875 | 876 | ||
| 876 | const exe = addExecutable(b, opts, .{ | 877 | const exe = addExecutable(b, opts, .{ |
test/src/Cases.zig+3-2| ... | @@ -339,7 +339,7 @@ fn addFromDirInner( | ... | @@ -339,7 +339,7 @@ fn addFromDirInner( |
| 339 | var it = try iterable_dir.walk(ctx.arena); | 339 | var it = try iterable_dir.walk(ctx.arena); |
| 340 | var filenames: ArrayList([]const u8) = .empty; | 340 | var filenames: ArrayList([]const u8) = .empty; |
| 341 | 341 | ||
| 342 | while (try it.next()) |entry| { | 342 | while (try it.next(io)) |entry| { |
| 343 | if (entry.kind != .file) continue; | 343 | if (entry.kind != .file) continue; |
| 344 | 344 | ||
| 345 | // Ignore stuff such as .swp files | 345 | // Ignore stuff such as .swp files |
| ... | @@ -431,9 +431,10 @@ fn addFromDirInner( | ... | @@ -431,9 +431,10 @@ fn addFromDirInner( |
| 431 | } | 431 | } |
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | pub fn init(gpa: Allocator, arena: Allocator) Cases { | 434 | pub fn init(gpa: Allocator, arena: Allocator, io: Io) Cases { |
| 435 | return .{ | 435 | return .{ |
| 436 | .gpa = gpa, | 436 | .gpa = gpa, |
| 437 | .io = io, | ||
| 437 | .cases = .init(gpa), | 438 | .cases = .init(gpa), |
| 438 | .arena = arena, | 439 | .arena = arena, |
| 439 | }; | 440 | }; |
test/standalone/ios/build.zig+3-1| ... | @@ -23,7 +23,9 @@ pub fn build(b: *std.Build) void { | ... | @@ -23,7 +23,9 @@ pub fn build(b: *std.Build) void { |
| 23 | }), | 23 | }), |
| 24 | }); | 24 | }); |
| 25 | 25 | ||
| 26 | if (std.zig.system.darwin.getSdk(b.allocator, &target.result)) |sdk| { | 26 | const io = b.graph.io; |
| 27 | |||
| 28 | if (std.zig.system.darwin.getSdk(b.allocator, io, &target.result)) |sdk| { | ||
| 27 | b.sysroot = sdk; | 29 | b.sysroot = sdk; |
| 28 | exe.root_module.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/include" }) }); | 30 | exe.root_module.addSystemIncludePath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/usr/include" }) }); |
| 29 | exe.root_module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/Frameworks" }) }); | 31 | exe.root_module.addSystemFrameworkPath(.{ .cwd_relative = b.pathJoin(&.{ sdk, "/System/Library/Frameworks" }) }); |
test/standalone/self_exe_symlink/build.zig-4| ... | @@ -9,10 +9,6 @@ pub fn build(b: *std.Build) void { | ... | @@ -9,10 +9,6 @@ pub fn build(b: *std.Build) void { |
| 9 | const optimize: std.builtin.OptimizeMode = .Debug; | 9 | const optimize: std.builtin.OptimizeMode = .Debug; |
| 10 | const target = b.graph.host; | 10 | const target = b.graph.host; |
| 11 | 11 | ||
| 12 | // The test requires getFdPath in order to to get the path of the | ||
| 13 | // File returned by openSelfExe | ||
| 14 | if (!std.os.isGetFdPathSupportedOnTarget(target.result.os)) return; | ||
| 15 | |||
| 16 | const main = b.addExecutable(.{ | 12 | const main = b.addExecutable(.{ |
| 17 | .name = "main", | 13 | .name = "main", |
| 18 | .root_module = b.createModule(.{ | 14 | .root_module = b.createModule(.{ |
test/tests.zig+1-1| ... | @@ -2632,7 +2632,7 @@ pub fn addCases( | ... | @@ -2632,7 +2632,7 @@ pub fn addCases( |
| 2632 | const gpa = b.allocator; | 2632 | const gpa = b.allocator; |
| 2633 | const io = b.graph.io; | 2633 | const io = b.graph.io; |
| 2634 | 2634 | ||
| 2635 | var cases = @import("src/Cases.zig").init(gpa, arena); | 2635 | var cases = @import("src/Cases.zig").init(gpa, arena, io); |
| 2636 | 2636 | ||
| 2637 | var dir = try b.build_root.handle.openDir(io, "test/cases", .{ .iterate = true }); | 2637 | var dir = try b.build_root.handle.openDir(io, "test/cases", .{ .iterate = true }); |
| 2638 | defer dir.close(io); | 2638 | defer dir.close(io); |