Skip to content

reached unreachable code compiling zig #22485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
raquentin opened this issue Jan 13, 2025 · 5 comments
Closed

reached unreachable code compiling zig #22485

raquentin opened this issue Jan 13, 2025 · 5 comments
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@raquentin
Copy link

raquentin commented Jan 13, 2025

Zig Version

0.14.0

Steps to Reproduce and Observed Behavior

  1. Be on aarch64 linux. sudo dnf install clang-devel llvm-devel lld-devel zlib zlib-devel.
  2. clone zig, cd
  3. clear cache: rm -rf build; mkdir build; rm -rf ~/.cache/zig; rm -rf zig-cache; git pull
  4. build cd build; cmake .. -DCMAKE_PREFIX_PATH=$(where llvm); make install

Output:

thread 6774 panic: reached unreachable code
/home/<...>/zig/lib/std/posix.zig:4686:23: 0x150b1db in mprotect (build)
            .INVAL => unreachable,
                      ^
/home/<...>/zig/lib/std/Thread.zig:1424:23: 0x153651f in spawn__anon_56775 (build)
        posix.mprotect(
                      ^
/home/<...>/zig/lib/std/Thread.zig:419:32: 0x14eb1f7 in spawn__anon_8489 (build)
    const impl = try Impl.spawn(config, function, args);
                               ^
/home/<...>/zig/lib/std/Progress.zig:423:55: 0x14d7c53 in start (build)
                .ansi_escape_codes => std.Thread.spawn(.{}, updateThreadRun, .{}),
                                                      ^
/home/<...>/zig/lib/compiler/build_runner.zig:329:50: 0x14d27f3 in main (build)
    const main_progress_node = std.Progress.start(.{
                                                 ^
/home/<...>/zig/lib/std/start.zig:656:37: 0x14beab7 in posixCallMainAndExit (build)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x0 in ??? (???)
error: the following build command crashed:
/home/<...>/zig/.zig-cache/o/edacf39d414fa60bf436caccbad656c9/build /home/<...>/zig/build/zig2 /home/<...>/zig/lib /home/<...>/zig /home/<...>/zig/.zig-cache /home/<user>/.cache/zig --seed 0x64a0fe9c -Z94e65736300eab91 --prefix /home/<...>/zig/build/stage3 -Dversion-string=0.14.0-dev.2643+fb43e91b2 -Dtarget=native -Dcpu=native -Denable-llvm -Dconfig_h=/home/<...>/zig/build/config.h -Dno-langref -Doptimize=Debug
make[2]: *** [CMakeFiles/stage3.dir/build.make:73: stage3/bin/zig] Error 1
make[1]: *** [CMakeFiles/Makefile2:196: CMakeFiles/stage3.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Expected Behavior

Zig builds

@raquentin raquentin added the bug Observed behavior contradicts documented or intended behavior label Jan 13, 2025
@raquentin
Copy link
Author

Here's the function panicking for convenience. In `lib/std/posix.zig:4666':

pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void {
    if (native_os == .windows) {
        const win_prot: windows.DWORD = switch (@as(u3, @truncate(protection))) {
            0b000 => windows.PAGE_NOACCESS,
            0b001 => windows.PAGE_READONLY,
            0b010 => unreachable, // +w -r not allowed
            0b011 => windows.PAGE_READWRITE,
            0b100 => windows.PAGE_EXECUTE,
            0b101 => windows.PAGE_EXECUTE_READ,
            0b110 => unreachable, // +w -r not allowed
            0b111 => windows.PAGE_EXECUTE_READWRITE,
        };
        var old: windows.DWORD = undefined;
        windows.VirtualProtect(memory.ptr, memory.len, win_prot, &old) catch |err| switch (err) {
            error.InvalidAddress => return error.AccessDenied,
            error.Unexpected => return error.Unexpected,
        };
    } else {
        switch (errno(system.mprotect(memory.ptr, memory.len, protection))) {
            .SUCCESS => return,
            .INVAL => unreachable, // panic here
            .ACCES => return error.AccessDenied,
            .NOMEM => return error.OutOfMemory,
            else => |err| return unexpectedErrno(err),
        }
    }
}

@raquentin
Copy link
Author

Thanks to anyone checking this out been stumping me for a bit now

@rootbeer
Copy link
Contributor

The compile is failing because mprotect is returning EINVAL and the standard library assumes EINVAL cannot happen. The mprotect man page says EINVAL might be returned if the pointer is invalid or not a multiple of the system page size (see https://linux.die.net/man/2/mprotect). Since this mprotect is being invoked from Zig's thread setup, I'm going to guess the address isn't aligned to the system page size. I believe there is ongoing work to make Zig work with non-4k page systems (e.g., I think #16331) might be related. What does getconfig PAGE_SIZE say on your system?

@raquentin
Copy link
Author

raquentin commented Jan 14, 2025

Thanks a lot. getconf PAGE_SIZE prints 16384. Looking more into it, my kernel assumes 16k page size despite the hardware technically supporting both at times.

@alexrp
Copy link
Member

alexrp commented Jan 14, 2025

In that case, I'll close this as a duplicate of #16331. There's a workaround in that issue that you can use until #20511 is merged.

@alexrp alexrp closed this as not planned Won't fix, can't repro, duplicate, stale Jan 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

3 participants