zig
zig copied to clipboard
reader.readAllAlloc crash on Ampere a1 CPU when given a much larger max_size parameter than the actual file size
Zig Version
0.14.0-dev.367+a57479afc
Steps to Reproduce and Observed Behavior
Example zig code:
const std = @import("std");
const fs = std.fs;
const print = std.debug.print;
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const file = try fs.cwd().openFile("crash.txt", .{});
defer file.close();
var buf_reader = std.io.bufferedReader(file.reader());
const reader = buf_reader.reader();
const buffer = try reader.readAllAlloc(allocator, 10240);
defer allocator.free(buffer);
print("{s}\n", .{buffer});
}
And crash.txt with only 5 letters:
crash
And run $ zig run example.zig
will result in a crash:
thread 2442597 panic: reached unreachable code
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/posix.zig:4699:19: 0x104fa9f in munmap (t)
.INVAL => unreachable, // Invalid parameters.
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/heap/PageAllocator.zig:94:21: 0x104f9c3 in resize (t)
posix.munmap(@alignCast(ptr[0 .. buf_aligned_len - new_size_aligned]));
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/mem/Allocator.zig:92:30: 0x107a923 in resizeLarge (t)
return self.vtable.resize(self.ptr, buf, log2_buf_align, new_len, ret_addr);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/heap/general_purpose_allocator.zig:722:40: 0x104fecf in resize (t)
return self.resizeLarge(old_mem, log2_old_align, new_size, ret_addr);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/mem/Allocator.zig:92:30: 0x107d6e3 in resize__anon_7795 (t)
return self.vtable.resize(self.ptr, buf, log2_buf_align, new_len, ret_addr);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/array_list.zig:1010:33: 0x1096e6f in shrinkAndFree (t)
if (allocator.resize(old_memory, new_len)) {
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/array_list.zig:398:36: 0x108b5bb in shrinkAndFree (t)
unmanaged.shrinkAndFree(self.allocator, new_len);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/io/Reader.zig:76:37: 0x107d443 in readAllArrayListAligned__anon_7794 (t)
array_list.shrinkAndFree(start_index);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/io/Reader.zig:52:40: 0x1052363 in readAllArrayList (t)
return self.readAllArrayListAligned(null, array_list, max_append_size);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/io/Reader.zig:92:30: 0x104c60f in readAllAlloc (t)
try self.readAllArrayList(&array_list, max_size);
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/io.zig:135:54: 0x104bf7f in main (t)
return @errorCast(self.any().readAllAlloc(allocator, max_size));
^
/home/opc/zig-linux-aarch64-0.14.0-dev.367+a57479afc/lib/std/start.zig:532:37: 0x104bd1f in posixCallMainAndExit (t)
const result = root.main() catch |err| {
^
???:?:?: 0x0 in ??? (???)
Aborted (core dumped)
To avoid crash, I can either change const buffer = try reader.readAllAlloc(allocator, 10240);
to const buffer = try reader.readAllAlloc(allocator, 1024);
or read a different file with more text in it. For example, the same text file but with with 999 lines of 'crash'
I only observed this behavior on my Oracle Cloud Ampere A1 CPU machines. I don't have other aarch64 machines to test so I'm not sure if this is Ampere A1 CPU only. Same code will run on x64 windows and x64 linux without any problems.
Expected Behavior
readAllAlloc should read the file without crash