Almost all the test failures on Windows I am experiencing look to be the same issue. Something like the following.
thread 'main' panicked at 'extern function roc_mmap is not defined by the builtins', crates\compiler\gen_llvm\src\llvm\externs.rs:176:17
So, I thought I might try and investigate further. It looks liks roc_mmap is provided in the bitcode. When I run the tests for zig builtins in crates\compiler\builtins\bitcode
I get the following lld-link errors.
PS C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode> zig build test
lld-link: error: undefined symbol: getppid
>>> referenced by C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\src\utils.zig:28
>>> C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache\o\956e3fa7e43377a9e7882b44adf58cc5\test.obj:(roc_getppid)
lld-link: error: undefined symbol: mmap
>>> referenced by C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\src\utils.zig:39
>>> C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache\o\956e3fa7e43377a9e7882b44adf58cc5\test.obj:(roc_mmap)
lld-link: error: undefined symbol: shm_open
>>> referenced by C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\src\utils.zig:36
>>> C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache\o\956e3fa7e43377a9e7882b44adf58cc5\test.obj:(roc_shm_open)
error: LLDReportedFailure
The following command exited with error code 1:
C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.9.1\zig.exe test C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\src\main.zig -lc --cache-dir C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache --global-cache-dir C:\Users\bosyl\AppData\Local\zig --name test
error: the following build command failed with exit code 1:
C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache\o\52b924dff34895983671b1f52442ea3d\build.exe C:\ProgramData\chocolatey\lib\zig\tools\zig-windows-x86_64-0.9.1\zig.exe C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode C:\Users\bosyl\Documents\GitHub\roc\crates\compiler\builtins\bitcode\zig-cache C:\Users\bosyl\AppData\Local\zig test
ChatGPT tells me the following
It looks like you're getting linker errors when trying to compile your Zig program, which is probably because the functions getppid, mmap, and shm_open are not found.
The reason you're encountering this issue is likely because these functions are not available on Windows. These are POSIX (Portable Operating System Interface) system calls:
getppid: This function returns the parent process id. On Windows, you can use GetCurrentProcessId and GetParentProcessId instead.
mmap: This function is used to map a file or other object into memory. On Windows, you can use CreateFileMapping and MapViewOfFile.
shm_open: This function creates or opens a named shared memory object. On Windows, you can use CreateFileMapping with a unique name to achieve similar functionality.
In c hosts we do:
void* roc_mmap(void* addr, int length, int prot, int flags, int fd, int offset) {
#ifdef _WIN32
return addr;
#else
return mmap(addr, length, prot, flags, fd, offset);
#endif
I don't really know zig, but in compiler/builtins/bitcode/src/utils.zig we don't have an if:
extern fn mmap(addr: ?*anyopaque, length: c_uint, prot: c_int, flags: c_int, fd: c_int, offset: c_uint) *anyopaque;
So that may be a problem.
I don't think I've seen extern function roc_mmap is not defined by the builtins
when fixing windows issues a couple of months ago, so that may also be a recently introduced issue.
I think it's specific to some platforms. In any case, we should not be using mmap on windows, so providing a dummy implementation is fine
Sounds good. Do you have any pointers where the dummy implementation should go? Also, should zig tests run on windows?
they kind of should
re the error, I think here
unreachable_function(env, "roc_getppid");
unreachable_function(env, "roc_mmap");
unreachable_function(env, "roc_shm_open");
add_sjlj_roc_panic(env)
}
}
fn unreachable_function(env: &Env, name: &str) {
// The type of this function (but not the implementation) should have
// already been defined by the builtins, which rely on it.
let fn_val = match env.module.get_function(name) {
Some(f) => f,
None => panic!("extern function {name} is not defined by the builtins"),
};
(you'll find this by searching for string in the panic here)
we should just not call unreachable_function(env, ...
on windows for roc_mmap, ppid, and shm_open I think
so just add some #[cfg(not(windows))]
would be my guess
#[cfg(not(windows))]
{
unreachable_function(env, "roc_getppid");
unreachable_function(env, "roc_mmap");
unreachable_function(env, "roc_shm_open");
}
```
Seems to have done it. Ran one test and it passed. I'll try running all of test_gen next
Ok so running cargo test --release --locked --package test_gen --test test_gen
gave me this.
Screenshot-2023-07-24-210147.png
I'm not sure why that crashes the test runner. If I disable the decode_derive_decoder_for_opaque
which overflowed its stack I get the same issue where something is causing exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
. I've also tried running in debug mode and get the same issue.
what might be helpful here is cargo nextest-gen-llvm --no-fail-fast
(may need cargo install nextest
or similar)
that should run all the tests and not stop when one of them crashes
so we can get an overview of what fails, maybe there are patterns
I'll give that a go.
Just ran mono tests also
failures:
---- branch_store_variable stdout ----
`git diff "generated/branch_store_variable.txt"` failed
thread 'branch_store_variable' panicked at 'internal error: entered unreachable code', crates\compiler\test_mono\src/tests.rs:232:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
branch_store_variable
test result: FAILED. 156 passed; 1 failed; 7 ignored; 0 measured; 0 filtered out; finished in 9.80s
that error means that git diff failed?!
maybe the file doesn't exist?
Here are the results for test-gen in case this helps.
hmm, there is this chunk
FAIL [ 3.124s] test_gen::test_gen gen_num::to_i64_checked_larger_width_signed_fits_neg
FAIL [ 3.978s] test_gen::test_gen gen_num::to_i64_checked_larger_width_signed_fits_pos
FAIL [ 2.370s] test_gen::test_gen gen_num::to_i64_checked_larger_width_signed_oob_neg
FAIL [ 2.326s] test_gen::test_gen gen_num::to_i64_checked_larger_width_signed_oob_pos
FAIL [ 2.134s] test_gen::test_gen gen_num::to_i64_checked_larger_width_unsigned_fits_pos
FAIL [ 2.151s] test_gen::test_gen gen_num::to_i64_checked_larger_width_unsigned_oob_pos
they fail "normally". can you find an error message for them?
(others abort because they do the equivalent of a segfault)
Something like thread 'gen_num::to_i64_checked_larger_width_signed_fits_neg' panicked at 'LLVM error: Did not get return value from bitcode function "roc_builtins.num.int_to_i64_checking_max_and_min.i128"'
and then for the other issues, I suspect return_tuple_3
is the easiest to debug. that'll be an adventure in assembly though
hmm, ok, strange. I think it would help to see the LLVM IR for that failing i128 test. I think when a test fails we try to save that IR
but maybe that is skipped on windows
right, so on windows this function does not return, apparently
and you pass in effectively a &mut result
for it to write the value into
so that will have to be special-cased
in particular, I suspect that this logic is not entirely correct
if target_int_width.stack_size() as usize > env.target_info.ptr_size() {
let bitcode_return_type =
zig_to_int_checked_result_type(env, target_int_width.type_name());
call_bitcode_fn_fixing_for_convention(
env,
layout_interner,
bitcode_return_type,
&[arg.into()],
return_layout,
intrinsic,
)
} else {
call_bitcode_fn(env, &[arg.into()], intrinsic)
}
They run through the else
branch when I add dbg's
yeah, I think that is incorrect
So does this mean the builtin function when it is called by env.builder.build_call() isn't returning a BasicValueEnum type?
yes
it's a void function
pub fn exportToIntCheckingMaxAndMin(comptime From: type, comptime To: type, comptime name: []const u8) void
eh yes but that function is the generator
it makes available a function with some different type
it's like a macro
let xxx = call_bitcode_fn_help(env, args, fn_name);
dbg!(&xxx);
xxx.try_as_basic_value()
.left()
.unwrap_or_else(|| {
panic!("LLVM error: Did not get return value from bitcode function {fn_name:?}")
})
Gives
[crates\compiler\gen_llvm\src\llvm\bitcode.rs:35] &xxx = CallSiteValue(
Value {
name: "",
address: 0x000001b9326ddd10,
is_const: false,
is_null: false,
is_undef: false,
llvm_value: " call void @roc_builtins.num.int_to_i64_checking_max_and_min.i128(i128 noalias nocapture nonnull sret(%\"num.ToIntCheckedResult(i64)\") %\"#arg1\"), !dbg !9",
llvm_type: "void",
},
)
yes, exactly
it returns void, and the first argument is a pointer to write the result into
Last updated: Jul 06 2025 at 12:14 UTC