Open WeijieH opened 3 months ago
Could not reproduce with -target aarch64-linux
via qemu-user:
$ zig version
0.14.0-dev.367+a57479afc
$ zig run -target aarch64-linux repro.zig
crash
The following lines from the original report seem to indicate a syscall gave the OS an unexpected value.
/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.
Linux's manpage for munmap
indicates pointer must be aligned to the page size whereas length does not.
@WeijieH, could you please do the following:
$ zig build-exe repro.zig
$ strace --trace=munmap,mmap ./repro
$ getconf PAGE_SIZE
Very strongly suspect this is a duplicate of #16331, or closely related.
Could not reproduce with
-target aarch64-linux
via qemu-user:details The following lines from the original report seem to indicate a syscall gave the OS an unexpected value.
/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.
Linux's manpage for
munmap
indicates pointer must be aligned to the page size whereas length does not.@WeijieH, could you please do the following:
- Clarify what OS you're using.
- Run and report the output of (EDIT: added PAGE_SIZE print):
$ zig build-exe repro.zig $ strace --trace=munmap,mmap ./repro $ getconf PAGE_SIZE
Here is the result of strace:
[opc@instance-20221208-2328 test]$ strace --trace=munmap,mmap ./t
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef910000
mmap(0xfffeef911000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef900000
munmap(0xfffeef901000, 4096) = -1 EINVAL (Invalid argument)
thread 3648566 panic: reached unreachable code
mmap(0xfffeef902000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef8f0000
mmap(NULL, 2554264, PROT_READ, MAP_SHARED, 4, 0) = 0xfffeef680000
mmap(0xfffeef8f1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef670000
mmap(0xfffeef672000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef660000
mmap(0xfffeef664000, 45056, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef650000
mmap(0xfffeef65b000, 147456, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef620000
mmap(0xfffeef644000, 495616, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xfffeef5a0000
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/posix.zig:4731:19: 0x104e6f7 in munmap (t)
.INVAL => unreachable, // Invalid parameters.
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/heap/PageAllocator.zig:94:21: 0x104e61b in resize (t)
posix.munmap(@alignCast(ptr[0 .. buf_aligned_len - new_size_aligned]));
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/mem/Allocator.zig:92:30: 0x1078f4f in resizeLarge (t)
return self.vtable.resize(self.ptr, buf, log2_buf_align, new_len, ret_addr);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/heap/general_purpose_allocator.zig:722:40: 0x104eb27 in resize (t)
return self.resizeLarge(old_mem, log2_old_align, new_size, ret_addr);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/mem/Allocator.zig:92:30: 0x107bbcf in resize__anon_7814 (t)
return self.vtable.resize(self.ptr, buf, log2_buf_align, new_len, ret_addr);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/array_list.zig:1010:33: 0x109546b in shrinkAndFree (t)
if (allocator.resize(old_memory, new_len)) {
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/array_list.zig:398:36: 0x1089cc7 in shrinkAndFree (t)
unmanaged.shrinkAndFree(self.allocator, new_len);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/io/Reader.zig:76:37: 0x107b92f in readAllArrayListAligned__anon_7813 (t)
array_list.shrinkAndFree(start_index);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/io/Reader.zig:52:40: 0x1050fbb in readAllArrayList (t)
return self.readAllArrayListAligned(null, array_list, max_append_size);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/io/Reader.zig:92:30: 0x104c067 in readAllAlloc (t)
try self.readAllArrayList(&array_list, max_size);
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/io.zig:135:54: 0x104b9d7 in main (t)
return @errorCast(self.any().readAllAlloc(allocator, max_size));
^
/home/opc/zig/0.14.0-dev.764+eb1a199df/files/lib/std/start.zig:570:37: 0x104b777 in posixCallMainAndExit (t)
const result = root.main() catch |err| {
^
???:?:?: 0x0 in ??? (???)
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=3648566, si_uid=1000} ---
+++ killed by SIGABRT (core dumped) +++
Aborted (core dumped)
PAGE_SIZE is 65536
system OS is oracle linux 8 Linux instance-20221208-2328 5.4.17-2136.333.5.el8uek.aarch64 #3 SMP Thu Jun 20 01:09:36 PDT 2024 aarch64 aarch64 aarch64 GNU/Linux
@WeijieH , I think that confirms what @alexrp said. Misaligned munmap
due to an unexpected page size for your platform.
Zig Version
0.14.0-dev.367+a57479afc
Steps to Reproduce and Observed Behavior
Example zig code:
And crash.txt with only 5 letters:
And run
$ zig run example.zig
will result in a crash:To avoid crash, I can either change
const buffer = try reader.readAllAlloc(allocator, 10240);
toconst 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