From 4d9a5d4b507d009e0f7ce0e40aa90d51256b8700 Mon Sep 17 00:00:00 2001 From: lucannez64 <58551020+lucannez64@users.noreply.github.com> Date: Sun, 18 Oct 2026 15:10:04 +0200 Subject: [PATCH] fix(launcher): disable inherited MangoHud fdinfo scans --- docs/TROUBLESHOOTING.md | 33 ++++++++++++++++++++++++++++ tools/riot-launcher-offline-check.py | 16 +++++++++++--- tools/run-riot-client.sh | 5 +++++ 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 7d8b3f4..14515f8 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -422,3 +422,36 @@ Recovery requires every matching client to be at least 60 seconds old and a complete Hyprland window record (`class`, `title`, `mapped`, `hidden`). A second process scan after window inspection must find the same client identities and no game. Missing information or shutdown failure leaves normal launch in charge. + +## Installer aborts on `/proc//fdinfo` + +[Issue #38](https://github.com/lucannez64/darling-lol/issues/38) reports an +uncaught `ghc::filesystem::filesystem_error` with `Permission denied` on +`/proc//fdinfo`. `ghc::filesystem` is a C++ filesystem library, not evidence +that the Riot installer is written in Haskell. + +An independent guest/native Vulkan probe reproduced this exact exception with +MangoHud 0.8.4 enabled on 2026-10-18. MangoHud's `GPU_fdinfo::find_fd()` builds +`/proc//fdinfo` and uses a throwing directory iterator. Inside Darling, +the native library's PID is in the guest PID namespace while its native `/proc` +view can still refer to host processes: the probe's native PID 35 resolved to an +inaccessible host process. The same probe completed Vulkan instance, device and +swapchain creation with MangoHud disabled. This does not establish the cause of +every installer abort; confirmation from the original reporter remains pending. + +The normal launcher now unsets `MANGOHUD` and exports `DISABLE_MANGOHUD=1` before +runtime helpers start, including first-time installation. This disables inherited +implicit MangoHud activation for the launched session without changing the host +configuration. Do not wrap the launcher in `mangohud` or explicitly force its +Vulkan layer. Updating these launcher scripts needs no Darling rebuild. For an +older checkout, use: + +```sh +env -u MANGOHUD DISABLE_MANGOHUD=1 ./scripts/installer.sh euw +``` + +Do not run the installer as root or change `/proc` permissions. If it still +fails, include the exception and whether a host overlay was enabled; redact +account tokens from logs. + +Upstream source: [MangoHud 0.8.4 fdinfo scan](https://github.com/flightlessmango/MangoHud/blob/v0.8.4/src/gpu_fdinfo.cpp#L9). diff --git a/tools/riot-launcher-offline-check.py b/tools/riot-launcher-offline-check.py index 1254b7a..1d661e7 100644 --- a/tools/riot-launcher-offline-check.py +++ b/tools/riot-launcher-offline-check.py @@ -22,9 +22,9 @@ def check(): stub = f'''#!{sys.executable} import json, os, sys record = {{"command": os.path.basename(sys.argv[0]), "args": sys.argv[1:]}} -if record["command"] == "darling": +if record["command"] in ("darling", "python3"): record["flags"] = {{key: os.environ.get(key) for key in - ("RCLOL_APP_ARG3", "RCLOL_APP_ARG3_SLOT", "RCLOL_UX_ARG2", "RCLOL_UX_ARG2_SLOT", "RCLOL_UX_ARG1", "RCLOL_APP_ARGS", "RCLOL_APP_ARG2", "DYLD_INSERT_LIBRARIES", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH", "DARLING_XSHM_LIBRARY")}} + ("RCLOL_APP_ARG3", "RCLOL_APP_ARG3_SLOT", "RCLOL_UX_ARG2", "RCLOL_UX_ARG2_SLOT", "RCLOL_UX_ARG1", "RCLOL_APP_ARGS", "RCLOL_APP_ARG2", "DYLD_INSERT_LIBRARIES", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH", "DARLING_XSHM_LIBRARY", "MANGOHUD", "DISABLE_MANGOHUD")}} with open({str(log)!r}, "a") as output: output.write(json.dumps(record) + "\\n") ''' @@ -46,6 +46,8 @@ with open({str(log)!r}, "a") as output: env["DYLD_INSERT_LIBRARIES"] = "/Users/offline-check/zzlogdir.dylib:/tmp/inherited.dylib" env["RCLOL_APP_ARGS"] = "--inherited-shim-argument" env["RCLOL_APP_ARG2"] = "--inherited-shim-argument-2" + env["MANGOHUD"] = "1" + env.pop("DISABLE_MANGOHUD", None) env["RCLOL_NATIVE_VPX"] = "1" env["RCLOL_LEAGUE_UX_TUNING"] = "1" # Inherited legacy settings must not re-enable inspection or unlimited frames. @@ -69,6 +71,9 @@ with open({str(log)!r}, "a") as output: ], "unexpected automatic helper" launches = [r for r in records if r["command"] == "darling"] assert len(launches) == 1, "unexpected launch count" + for record in records: + assert record["flags"]["MANGOHUD"] is None, "inherited MangoHud activation survived" + assert record["flags"]["DISABLE_MANGOHUD"] == "1", "MangoHud not disabled before a runtime helper" launch = launches[0] assert all(launch["flags"][key] is None for key in ( "RCLOL_APP_ARG3", "RCLOL_APP_ARG3_SLOT", "RCLOL_UX_ARG2", "RCLOL_UX_ARG2_SLOT" @@ -84,18 +89,23 @@ with open({str(log)!r}, "a") as output: assert "--log-dir=/Users/offline-check/Library/Logs/Riot Games/Riot Client" in launch["args"], "absolute log directory lost" # An inherited injection must also be absent for first-time installation. env["RIOT_LAUNCHER_HOST"] = str(folder / "Install Riot.app/Contents/MacOS/RiotClientServices") + env["DISABLE_MANGOHUD"] = "0" # An inherited value cannot override launcher policy. subprocess.run(["sh", str(launcher)], env=env, check=True, capture_output=True, text=True) install = json.loads(log.read_text().splitlines()[-1]) assert install["args"][0] == env["RIOT_LAUNCHER_HOST"] assert "--skip-to-install" in install["args"] assert not any(arg.startswith("--app-root=") for arg in install["args"]) assert install["flags"]["DYLD_INSERT_LIBRARIES"] is None + assert install["flags"]["MANGOHUD"] is None + assert install["flags"]["DISABLE_MANGOHUD"] == "1" env.pop("RIOT_LAUNCHER_HOST") env.pop("DYLD_INSERT_LIBRARIES") subprocess.run(["sh", str(launcher)], env=env, check=True, capture_output=True, text=True) clean = json.loads(log.read_text().splitlines()[-1]) assert clean["flags"]["DYLD_INSERT_LIBRARIES"] is None - print("LAUNCHER_OFFLINE pass=1 installed=PASS installer=PASS inherited_injection=absent runtime=preserved") + assert clean["flags"]["MANGOHUD"] is None + assert clean["flags"]["DISABLE_MANGOHUD"] == "1" + print("LAUNCHER_OFFLINE pass=1 installed=PASS installer=PASS inherited_injection=absent mangohud=disabled runtime=preserved") if __name__ == "__main__": diff --git a/tools/run-riot-client.sh b/tools/run-riot-client.sh index 75b6ec7..f33a612 100755 --- a/tools/run-riot-client.sh +++ b/tools/run-riot-client.sh @@ -2,6 +2,11 @@ # Launch Riot Client using the Darling runtime, without library injection. # Darling supplies Xlib Display pointers to EGL, so select X11 explicitly. set -eu +# Native MangoHud uses the guest PID against the host /proc view and can abort +# in GPU_fdinfo::find_fd (issue #38). Disable inherited implicit activation +# before any helper can start Darling, including first-time installation. +unset MANGOHUD +export DISABLE_MANGOHUD=1 # Native guest crashes created large system core files and exhausted this disk. # Address-only diagnostics suffice; bound this runner and its new namespace. if [ "${RCLOL_CORE_DUMPS:-0}" != 1 ]; then