Skip to content

Example Project Crashes on Keyboard Input on Linux #342

Description

@coal-rock

I'm currently running Arch Linux:
Linux 7.0.10-arch1-1 x86_64 GNU/Linux

Zig Version: 0.16.0
Raylib-zig: 97be2c7ae646a2f09856604b138c427c0af1b952

When attempting to run the example with Debug mode enabled (default behavior with zig build run), any keyboard input causes the application to crash with the following trace:

INFO: Initializing raylib 6.0
INFO: Platform backend: DESKTOP (GLFW)
INFO: Supported raylib modules:
INFO:     > rcore:..... loaded (mandatory)
INFO:     > rlgl:...... loaded (mandatory)
INFO:     > rshapes:... loaded (optional)
INFO:     > rtextures:. loaded (optional)
INFO:     > rtext:..... loaded (optional)
INFO:     > rmodels:... loaded (optional)
INFO:     > raudio:.... loaded (optional)
INFO: DISPLAY: Device initialized successfully
INFO:     > Display size: 2560 x 1600
INFO:     > Screen size:  800 x 450
INFO:     > Render size:  800 x 450
INFO:     > Viewport offsets: 0, 0
INFO: GLAD: OpenGL extensions loaded successfully
INFO: GL: Supported extensions count: 235
INFO: GL: OpenGL device information:
INFO:     > Vendor:   Intel
INFO:     > Renderer: Mesa Intel(R) Iris(R) Xe Graphics (RPL-P)
INFO:     > Version:  4.6 (Core Profile) Mesa 26.1.1-arch1.2
INFO:     > GLSL:     4.60
INFO: GL: VAO extension detected, VAO functions loaded successfully
INFO: GL: NPOT textures extension detected, full NPOT textures supported
INFO: GL: DXT compressed textures supported
INFO: GL: ETC2/EAC compressed textures supported
INFO: PLATFORM: DESKTOP (GLFW - X11): Initialized successfully
INFO: TEXTURE: [ID 1] Texture loaded successfully (1x1 | R8G8B8A8 | 1 mipmaps)
INFO: TEXTURE: [ID 1] Default texture loaded successfully
INFO: SHADER: [ID 1] Vertex shader compiled successfully
INFO: SHADER: [ID 2] Fragment shader compiled successfully
INFO: SHADER: [ID 3] Program shader loaded successfully
INFO: SHADER: [ID 3] Default shader loaded successfully
INFO: RLGL: Render batch vertex buffers loaded successfully in RAM (CPU)
INFO: RLGL: Render batch vertex buffers loaded successfully in VRAM (GPU)
INFO: RLGL: Default OpenGL state initialized successfully
INFO: TEXTURE: [ID 2] Texture loaded successfully (128x128 | GRAY_ALPHA | 1 mipmaps)
INFO: FONT: Default font loaded successfully (224 glyphs)
INFO: SYSTEM: Working Directory: /home/coal/Coding/Zig/mini
INFO: TIMER: Target time per frame: 16.667 milliseconds
thread 133975 panic: index -131 out of bounds for type 'int[512]'
zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/external/glfw/src/linux_joystick.c:53:30: 0x15f76bd in handleKeyEvent (/home/coal/Coding/Zig/mini/zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rglfw.c)
                             js->linjs.keyMap[code - BTN_MISC],
                             ^
zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/external/glfw/src/linux_joystick.c:418:13: 0x15f6f12 in _glfwPollJoystickLinux (/home/coal/Coding/Zig/mini/zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rglfw.c)
            handleKeyEvent(js, e.code, e.value);
            ^
zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/external/glfw/src/input.c:1052:12: 0x15eaf77 in glfwJoystickPresent (/home/coal/Coding/Zig/mini/zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rglfw.c)
    return _glfw.platform.pollJoystick(js, _GLFW_POLL_PRESENCE);
           ^
zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/platforms/rcore_desktop_glfw.c:1310:13: 0x12cef2c in PollInputEvents (/home/coal/Coding/Zig/mini/zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rcore.c)
        if (glfwJoystickPresent(i)) CORE.Input.Gamepad.ready[i] = true;
            ^
zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rcore.c:927:5: 0x12dbd9b in EndDrawing (/home/coal/Coding/Zig/mini/zig-pkg/raylib-6.0.0-whq8uCSwLgWWeF3ec3dbG6Rr36SLFL-s2WJ1Q_2E22Bb/src/rcore.c)
    PollInputEvents();      // Poll user events (before next frame update)
    ^
/home/coal/Coding/Zig/mini/zig-pkg/raylib_zig-6.0.0-KE8REDJ4BQBu7lKwYNt6R4j5ywPeS37zqW6zrtjCcRwH/lib/raylib.zig:2986:20: 0x123bbb2 in endDrawing (raylib.zig)
    cdef.EndDrawing();
                   ^
/home/coal/Coding/Zig/mini/src/main.zig:39:28: 0x123b959 in main (main.zig)
        defer rl.endDrawing();
                           ^
/usr/lib/zig/std/start.zig:698:59: 0x1239d15 in callMain (std.zig)
    if (fn_info.params.len == 0) return wrapMain(root.main());
                                                          ^
???:?:?: 0x7f599dc27740 in ??? (/usr/lib/libc.so.6)
???:?:?: 0x7f599dc27878 in ??? (/usr/lib/libc.so.6)
???:?:?: 0x1252374 in ??? (???)
run
└─ run exe mini failure
error: process terminated with signal ABRT
failed command: /home/coal/Coding/Zig/mini/zig-out/bin/mini

Build Summary: 6/8 steps succeeded (1 failed)
run transitive failure
└─ run exe mini failure

error: the following build command failed with exit code 1:
.zig-cache/o/7bad0cb848a5eb674f1afdccfd8a5c55/build /usr/bin/zig /usr/lib/zig /home/coal/Coding/Zig/mini .zig-cache /home/coal/.cache/zig --seed 0x2546d235 -Zff71d0bc9af05bff run

This looks like it could be an upstream issue with GLFW returning an integer outside of the valid range, caused by pushing keyboard input events through the joystick pipeline, which leads to an OOB read. Compiling without debug/safety checks enabled seems to resolve any visible issues, though there still may be behavioral issues that I haven't noticed.

Other users of this library have had this issue: see here.

In zig-pkg/raylib-6.0.0-[]/src/external/glfw/src/linux_joystick.c you can manually patch out the offending function by explicitly adding bounds checks:

diff -u zig-pkg/raylib-6.0.0-[]/src/external/glfw/src/linux_joystick.c.old zig-pkg/raylib-6.0.0-[]/src/external/glfw/src/linux_joystick.c
--- zig-pkg/raylib-6.0.0-[]/src/external/glfw/src/linux_joystick.c.old	2026-05-25 19:13:17.327141054 -0400
+++ zig-pkg/raylib-6.0.0-[]/src/external/glfw/src/linux_joystick.c	2026-05-25 19:12:41.473672855 -0400
@@ -49,6 +49,11 @@
 //
 static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
 {
+    if (code < BTN_MISC || (code - BTN_MISC) >= 512) {
+        return;
+    }
+
+
     _glfwInputJoystickButton(js,
                              js->linjs.keyMap[code - BTN_MISC],
                              value ? GLFW_PRESS : GLFW_RELEASE);

I'm sure something like this could be added to build.zig, though that doesn't really feel like a real solution.

Additionally, you might be able to use @setRuntimeSafety(false); or perform some unchecked cast at the FFI barrier, though I'm really not sure.

Apologies if this isn't the correct place to open an issue about this!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    raylib issueRaylib bug affecting the binding

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions