Hi, I ran into an issue using GLFW with Zig 0.16.0 on Gentoo (Wayland/niri).
I first hit this in a bigger project, where I could open a window and render OpenGL quads fine, so GLFW itself is working. The panic only shows up when an error propagates out of main unhandled. Here’s the smallest repro I could get it down to:
main.zig
const std = @import("std");
const c = @cImport({
@cInclude("GLFW/glfw3.h");
});
pub fn main(init: std.process.Init) !void {
_ = init;
if (c.glfwInit() == 0) return error.GlfwInitFailed;
defer c.glfwTerminate();
return error.DeliberateTestError;
}
build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "game",
.root_module = b.createModule(.{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
}),
});
exe.root_module.linkSystemLibrary("glfw", .{});
b.installArtifact(exe);
const run_step = b.step("run", "Run the application");
const run_cmd = b.addRunArtifact(exe);
run_step.dependOn(&run_cmd.step);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
}
Here is the command I used to run the program:
$ zig build run
thread 19458 panic: attempt to use null value
error return context:
Then it just hangs, has to be killed.
If I remove the return error.DeliberateTestError; line so main exits normally, no problem at all. If I keep the error but don’t call glfwInit(), also no problem and it prints the error trace and exits. So glfwInit() specifically seems to be the thing that triggers it, not window/context creation or anything that comes normally after.
Backtrace from gdb:
$ gdb --args zig-out/bin/game
GNU gdb (Gentoo 17.2 vanilla) 17.2
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.gentoo.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from zig-out/bin/game...
(gdb) run
Starting program: /home/thomas/Projects/Games/balian/zig-out/bin/game
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/usr/lib64/libthread_db.so.1".
[New Thread 0x7ffff5f016c0 (LWP 19707)]
[New Thread 0x7ffff57006c0 (LWP 19708)]
[New Thread 0x7ffff4eff6c0 (LWP 19709)]
[New Thread 0x7fffe7fff6c0 (LWP 19710)]
[New Thread 0x7fffe77fe6c0 (LWP 19711)]
thread 19703 panic: attempt to use null value
error return context:
^C
Thread 1 "game" received signal SIGINT, Interrupt.
0x00000000010db8eb in os.linux.x86_64.syscall4 (number=futex, arg1=19318312, arg2=128, arg3=2, arg4=0)
(gdb) bt
#0 0x00000000010db8eb in os.linux.x86_64.syscall4 ()
#1 0x00000000010db4cf in os.linux.futex_4arg ()
#2 0x00000000010dab54 in Io.Threaded.Thread.futexWaitInner ()
#3 0x00000000010d890f in Io.Threaded.Thread.futexWaitUncancelable ()
#4 0x00000000010d87f7 in Io.Threaded.mutexLock ()
#5 0x00000000010d590d in Io.Threaded.scanEnviron ()
#6 0x00000000010d5a15 in Io.Threaded.environString__anon_13417 ()
#7 0x00000000010d0734 in debug.ElfFile.DebugInfoSearchPaths.native ()
#8 0x00000000010bddee in debug.SelfInfo.Elf.Module.loadElf ()
#9 0x00000000010bd694 in debug.SelfInfo.Elf.Module.getLoadedElf ()
#10 0x000000000103dfa1 in debug.SelfInfo.Elf.getSymbols ()
#11 0x00000000010272cf in debug.printSourceAtAddress ()
#12 0x00000000011241d1 in debug.writeTrace ()
#13 0x0000000001123c89 in debug.writeErrorReturnTrace ()
#14 0x000000000102521f in debug.defaultPanic ()
#15 0x000000000102ffa4 in debug.FullPanic((function 'defaultPanic')).unwrapNull ()
#16 0x00000000010d5ad6 in Io.Threaded.Environ.scan ()
#17 0x00000000010d597f in Io.Threaded.scanEnviron ()
#18 0x0000000001164c30 in Io.Threaded.initLockedStderr ()
#19 0x00000000011653fc in Io.Threaded.lockStderr ()
#20 0x00000000011263ff in Io.lockStderr ()
#21 0x00000000011260c5 in debug.lockStderr ()
#22 0x00000000011d25d5 in log.defaultLog__anon_35555 ()
#23 0x00000000011d24cb in log.log__anon_35548 ()
#24 0x00000000011d246b in log.scoped(.default).err__anon_32808 ()
#25 0x00000000011ccb51 in start.main ()
#26 0x00007ffff7cd21fe in ??? () at /usr/lib64/libc.so.6
#27 0x00007ffff7cd231b in __libc_start_main () at /usr/lib64/libc.so.6
#28 0x00000000012042b5 in _start ()
(gdb)
I also tested with the official zig-x86_64-linux-0.16.0 binary from ziglang.org (not just my Gentoo-built one), same exact panic and backtrace, so it doesn’t look like a packaging issue on my end.
Let me know if there’s anything else I can test. Thanks in advance!