mirror of
https://github.com/lucannez64/darling-lol.git
synced 2026-10-26 19:47:42 +00:00
fix(iokitd): run without an X display instead of crashing in a loop
With DISPLAY set but XAUTHORITY missing or stale, the X server rejects the connection, XOpenDisplay() returns NULL, and iokitd passed that NULL display to eglGetPlatformDisplay(). Mesa's X11 platform expects a real Display there, so iokitd faulted and launchd restarted it every 10 seconds while /tmp/lolsig.log filled with frames (issue #140). IOSurfaceRoot now checks the display first, stays at EGL_NO_DISPLAY and prints one line when it is missing. createSurface() already returns KERN_FAILURE for !hasDisplay(), so surfaces fail closed instead of the process crashing. The destructor also skips eglTerminate() when no display was initialized. Documents that DISPLAY alone is not enough on servers and SSH sessions, and adds a display probe to tools/env-check.sh: it reports DISPLAY/XAUTHORITY and warns when xdpyinfo cannot open the display that Darling will inherit. Signed-off-by: zero <zero@localhost>
This commit is contained in:
1 parent
24276b91c6
commit
9a1a38b568
3 files changed
+61
-3
No files matched your search
@@ -434,6 +434,20 @@ The installer adds a CarbonCore framework override and the matching absolute Cor
|
||||
|
||||
`iokitd` crashed in host glibc's `pthread_mutex_lock` and launchd restarted it every 10 seconds. It called `eglGetDisplay()` with an Xlib display, so Mesa picked the platform from `EGL_PLATFORM`. Wayland sessions often set that to `wayland`, and the first `darling` command passes its environment to every guest service, including `iokitd`. `scripts/run.sh` sets `EGL_PLATFORM=x11` and was unaffected, but `darling shell` from a Wayland terminal (including the one in `scripts/install-runtime.sh`) started the loop. `iokitd` now requests the X11 platform explicitly. The fix is part of the base install (`sudo cmake --install`); until then, start Darling with `EGL_PLATFORM=x11`.
|
||||
|
||||
## `iokitd` restarts when the X display is not accessible
|
||||
|
||||
`DISPLAY` can name an X server that rejects the connection, which is what an unset or stale `XAUTHORITY` does on a server, over SSH, or in a `sudo` session that dropped the cookie. `iokitd` then has no Xlib display and previously still called into EGL with a null display, so the process faulted and launchd restarted it in a loop while `/tmp/lolsig.log` filled with frames ([#140](https://github.com/lucannez64/darling-lol/issues/140)).
|
||||
|
||||
`iokitd` now checks the display before EGL. Without a usable display it prints one line (`iokitd: cannot open X display …; X11 surface acceleration disabled`) and keeps running, so `darling shell` starts instead of crash-looping. Surfaces then fail with `KERN_FAILURE`, which means the guest has no GPU rendering: export a cookie the user running Darling can read and start again, for example:
|
||||
|
||||
```sh
|
||||
export XAUTHORITY=/run/user/$(id -u)/xauth
|
||||
# or, from a server install that keeps its cookie elsewhere:
|
||||
XAUTHORITY=$(ls /var/run/sddm/* | head -1) DISPLAY=:0 EGL_PLATFORM=x11 darling shell echo hola
|
||||
```
|
||||
|
||||
`bash tools/env-check.sh` now probes the display with `xdpyinfo` in the environment Darling inherits and warns when it cannot open it. That check is advisory: without X11/EGL the runtime still boots, but the game cannot render.
|
||||
|
||||
## Blocky video or flickering startup logo
|
||||
|
||||
The first dynamically resolved GL call could lose floating-point arguments during ELF symbol lookup. Chromium's linear sampler request then failed and left nearest sampling. The generated resolver now preserves those registers. Install both the rebuilt native `libGL.dylib` in `RuntimeLibraries` and the OpenGL framework's library copy using the paired runtime installer; the framework alone is insufficient.
|
||||
|
||||
+29
-3
@@ -437,10 +437,10 @@ index 50c10fe..7026e1c 100644
|
||||
+ return kIOReturnSuccess;
|
||||
+}
|
||||
diff --git a/src/IOSurfaceRoot.mm b/src/IOSurfaceRoot.mm
|
||||
index d7e6fab..d860582 100644
|
||||
index d7e6fab..f47889f 100644
|
||||
--- a/src/IOSurfaceRoot.mm
|
||||
+++ b/src/IOSurfaceRoot.mm
|
||||
@@ -21,13 +21,17 @@
|
||||
@@ -21,13 +21,33 @@
|
||||
#include "iokitd.h"
|
||||
#include "IOSurface.h"
|
||||
#include "IODisplayConnectX11.h"
|
||||
@@ -448,6 +448,7 @@ index d7e6fab..d860582 100644
|
||||
#include <IOKit/IOCFUnserialize.h>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
+#include <cstdlib>
|
||||
|
||||
IOSurfaceRoot::IOSurfaceRoot()
|
||||
{
|
||||
@@ -455,10 +456,35 @@ index d7e6fab..d860582 100644
|
||||
+ // The native display is an Xlib Display. eglGetDisplay() would let Mesa
|
||||
+ // guess the platform from EGL_PLATFORM, which Wayland sessions often set
|
||||
+ // to "wayland"; Mesa then treats the Display as a wl_display and crashes.
|
||||
+ m_display = eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, IODisplayConnectX11::getDisplay(), NULL);
|
||||
+ Display* display = IODisplayConnectX11::getDisplay();
|
||||
+ // Mesa's X11 platform dereferences the native display, so a NULL display
|
||||
+ // faults. XOpenDisplay() returns NULL when the X server rejects the
|
||||
+ // connection, which is what an unset or stale XAUTHORITY does. iokitd then
|
||||
+ // crashed and launchd restarted it in a loop. Run without EGL instead;
|
||||
+ // createSurface() already reports KERN_FAILURE when hasDisplay() is false.
|
||||
+ if (!display)
|
||||
+ {
|
||||
+ m_display = EGL_NO_DISPLAY;
|
||||
+ std::cerr << "iokitd: cannot open X display "
|
||||
+ << (std::getenv("DISPLAY") ? std::getenv("DISPLAY") : "(DISPLAY unset)")
|
||||
+ << "; X11 surface acceleration disabled, set XAUTHORITY to a readable cookie"
|
||||
+ << std::endl;
|
||||
+ return;
|
||||
+ }
|
||||
+ m_display = eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, display, NULL);
|
||||
|
||||
if (m_display == EGL_NO_DISPLAY)
|
||||
return;
|
||||
@@ -50,7 +70,8 @@ IOSurfaceRoot::IOSurfaceRoot()
|
||||
|
||||
IOSurfaceRoot::~IOSurfaceRoot()
|
||||
{
|
||||
- eglTerminate(m_display);
|
||||
+ if (m_display != EGL_NO_DISPLAY)
|
||||
+ eglTerminate(m_display);
|
||||
}
|
||||
|
||||
IOSurfaceRoot* IOSurfaceRoot::instance()
|
||||
diff --git a/src/PowerSources.mm b/src/PowerSources.mm
|
||||
new file mode 100644
|
||||
index 0000000..70ca9bd
|
||||
|
||||
@@ -20,4 +20,22 @@ command -v darling >/dev/null && darling --version 2>&1 || echo "darling not ins
|
||||
echo "== gpu =="
|
||||
ls /dev/dri 2>/dev/null || echo "no /dev/dri (Vulkan render needs GPU or lavapipe)"
|
||||
command -v vulkaninfo >/dev/null && vulkaninfo --summary 2>&1 | head -20 || echo "vulkaninfo absent"
|
||||
echo "== display =="
|
||||
# DISPLAY is not enough: the X server can reject the connection when the cookie
|
||||
# is missing or stale, and Darling's iokitd then has no X11/EGL path. Ask the
|
||||
# server with the environment Darling will inherit.
|
||||
if [ -n "${DISPLAY:-}" ]; then
|
||||
echo "DISPLAY=$DISPLAY XAUTHORITY=${XAUTHORITY:-unset}"
|
||||
if command -v xdpyinfo >/dev/null 2>&1; then
|
||||
if xdpyinfo >/dev/null 2>&1; then
|
||||
echo "X display reachable"
|
||||
else
|
||||
echo "WARN: cannot open $DISPLAY; export XAUTHORITY with a readable cookie (typical for servers and SSH), otherwise iokitd runs without X11/EGL"
|
||||
fi
|
||||
else
|
||||
echo "xdpyinfo not installed; skipping the display probe (install x11-utils)"
|
||||
fi
|
||||
else
|
||||
echo "DISPLAY unset; iokitd runs without X11/EGL (expected on a headless host)"
|
||||
fi
|
||||
[ "$ok" -eq 1 ] && echo "OK" || { echo "FAIL: install missing tools"; exit 1; }
|
||||
Reference in new issue
Block a user