Include older distributions to mitigate glibc incompatibility with GLIBC
NB: Debugging done with Google Ai Studio beacause I'm not a developper.
Hello,
I'm writing to report a persistent Segmentation fault issue encountered while packaging an older native 32-bit Linux game ("Knights of the Old Republic II") using GameImage. After an exhaustive debugging process, the evidence strongly suggests a fundamental incompatibility between the host system's libraries (Debian/Mint-based) and the Arch Linux-based glibc provided by the FlatImage environment.
Here is a summary of our investigation.
- System and Game Information
Host System: Linux Mint (Debian/Ubuntu-based), providing a stable set of older 32-bit libraries (i386-linux-gnu).
Game: "Knights of the Old Republic II", a native 32-bit Linux executable.
GameImage Environment: Reports itself as FlatImage distribution: ARCH, indicating a modern Arch Linux base with a recent version of glibc.
- The Initial Problem
When the game is launched inside the default FlatImage container, it immediately crashes with a Segmentation fault. This occurs despite the Arch environment providing all necessary libraries according to ldd. The initial hypothesis was an ABI incompatibility between the old game and the modern system libraries (e.g., libstdc++, libGL).
- Exhaustive Debugging Steps
To resolve this, we attempted to bundle the host system's (Linux Mint) 32-bit libraries within the image.
Attempt A: Full Library Override
We copied the entire set of 32-bit libraries required by the game from the Mint host system into a local ./lib directory inside the image.
We then used a local 32-bit dynamic loader (./lib/ld-linux.so.2 --library-path ./lib) to force the game to use this self-contained environment.
Result: This failed catastrophically. The dynamic loader itself crashed with a Fatal glibc error: allocatestack.c:333 (allocate_stack): assertion failed: size != 0. This proved that our host's glibc is fundamentally incompatible with the underlying kernel/system services of the Arch Linux environment provided by FlatImage.
Attempt B: Hybrid Library Approach (The Key Finding)
Recognizing the glibc conflict, we shifted to a "hybrid" strategy. We bundled all of the game's dependencies from the host system EXCEPT for libc.so.6 and its core components (libpthread.so.0, etc.).
We used export LD_LIBRARY_PATH to ensure our bundled libraries (like libstdc++.so.6, libGL.so.1, etc.) were preferred, while allowing the program to fall back to the FlatImage's native Arch glibc.
Result: The glibc assertion error disappeared, but the Segmentation fault returned. This confirmed that while the Arch glibc could run, a conflict still existed.
- Final Diagnosis with strace
To pinpoint the source of the crash in the hybrid environment, we ran the game under strace.
The strace log confirmed that our bundled libraries (from ./lib) were being loaded correctly, followed by the Arch glibc (from /usr/lib32).
The log showed a long series of system calls related to Name Service Switch (nsswitch.conf, passwd, userdb). The program was trying to identify the current user.
The very last system call before the crash was rt_sigprocmask, immediately followed by: --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x14} ---.
- Conclusion
The SEGV_MAPERR at a low address like 0x14 is a classic symptom of a NULL pointer dereference. The sequence of events strongly indicates the following failure chain:
A high-level library from our Mint environment (e.g., libX11.so.6) is loaded.
This library needs to query user information and calls a function to do so.
This call is handled by the Arch Linux glibc.
The Arch glibc interacts with the Arch environment's NSS modules (like libnss_systemd.so.2).
The data structure returned by the Arch glibc is either in a format that the older Mint library does not understand, or it is malformed from the perspective of the older library, resulting in a NULL pointer.
When the Mint library tries to access a member of this NULL structure (at an offset like 0x14), the program crashes.
We confirmed this by also bundling the Mint libnss_* libraries, but the Segmentation fault persisted, proving the conflict lies at the core glibc communication level.
In short, the ABI gap between an older Debian-based glibc ecosystem and a modern Arch-based glibc is too significant for older, complex applications like games to bridge, even when only high-level libraries are swapped. The way these libraries interact with the core C library for fundamental operations like user lookups or thread management is subtly but critically different.
A potential solution for GameImage could be to offer the ability to build images on top of different, older bases (e.g., Debian 10, Ubuntu 20.04) for applications that require better legacy compatibility.
Thank you for your work on this tool. I hope this detailed report is useful for future development.
Best regards.
Hi @flelard, thank you a lot for all this information. I plan to add Debian to the Linux distributions to choose from on the runner options, that way issues with GLIBC should be solved for several Linux native games. I'll use this issue to track that.
Best,