diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index f4a5488..d7b0e68 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -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. diff --git a/patches/iokitd.patch b/patches/iokitd.patch index 5607ad6..d7f9069 100644 --- a/patches/iokitd.patch +++ b/patches/iokitd.patch @@ -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 #include #include ++#include 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 diff --git a/tools/env-check.sh b/tools/env-check.sh index 116b206..f0e5415 100755 --- a/tools/env-check.sh +++ b/tools/env-check.sh @@ -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; }