libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.96k stars 1.84k forks source link

Crash with Missing XInput2 Shared Library #8378

Closed SirNate0 closed 1 year ago

SirNate0 commented 1 year ago

I came across what I think is a bug in a 32 bit CI build for another library: If SDL is built with support for XInput2, but the shared library is not available on the run-time system, then you get a crash, for example, here, because the function pointer is null. I only came across this as we had missed the 32 bit version of the libxi-dev package, but since the 64 bit version was installed the build system (modified some from the base SDL build system) detected that XInput2 was available (since it found the 64 bit version) but when running the 32 bit executable, it could not load the library (as there was no 32 bit version installed).

I don't know if it is actually a sane setup to be missing libxi or not, but since it seems SDL can be built for X11 without it, I suppose it might be. The Github Actions runner running with xvfb-run for the "display" is hardly a representative use case, so I don't really know what would be expected on a normal system. I just know that I encountered this crash when upgrading SDL versions, and it seems like it's still present in master (the older version of SDL didn't have the XInput2 specific code).

For more details on the crash, you can refer to my comment here https://github.com/u3d-community/U3D/issues/4#issuecomment-1746993297


If it is reasonable for users to not have libxi installed, I think there need to be runtime checks for the functions availability, or they need to be replaced with functions that fall back to the non-XInput2 functions. E.g. for this

#ifdef SDL_VIDEO_DRIVER_X11_XINPUT2
    int deviceid = 0;
    /* It seems XIWarpPointer() doesn't work correctly on multi-head setups:
     * https://developer.blender.org/rB165caafb99c6846e53d11c4e966990aaffc06cea
     */
    if (ScreenCount(display) == 1) {
        X11_XIGetClientPointer(display, None, &deviceid);
    }
    if (deviceid != 0) {
        X11_XIWarpPointer(display, deviceid, None, xwindow, 0.0, 0.0, 0, 0, x, y);
    } else
#endif
    {
        X11_XWarpPointer(display, None, xwindow, 0, 0, 0, 0, (int)x, (int)y);
    }

we would have fallen back to something like

icculus commented 1 year ago

This is fixed in SDL3, SDL2, and the release-2.28.x branch.