Files
darling-lol/tools/run-riot-native-check.py
T
lucannez64 5609d96f16 Fix Darling runtime performance and new-PC compatibility
Preserve floating-point arguments in GL resolvers, retain presentation across differently sized windows, export AppKit click and URL fixes, and guard nullable LaunchServices errors. Include compiler/build and installer corrections for the new PC.

Reuse server receive buffers with descriptor-safe exception cleanup and avoid disabled debug-string allocation. Translate Darwin free/reuse memory hints, add atomic server/library installers with separate user-owned memory backups, and preserve active processes until a manual namespace restart.

Remove automatic inspectors, client helpers and forced unlimited UI frames from normal launches. Retain historical hooks with offline mocks and document their exclusion, unresolved installer handoff, activation requirements and unmeasured FPS/RAM benefits.

Validation: all 29 pinned patches apply; all 461 exported source files match; host receive and memory checks, launcher and JavaScript mocks, syntax and documentation-link checks pass. No live client/game was controlled or restarted.
2026-10-13 15:09:23 +02:00

98 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""Run an owned native probe with bounded capture and scoped timeout cleanup."""
import argparse
import os
from pathlib import Path
import signal
import subprocess
import tempfile
root = Path(__file__).resolve().parent.parent
checks = {
"riot-launchservices-null-error-check": "LAUNCHSERVICES_NULL_ERROR",
"m327-cgl-resolver-check": "GL_RESOLVER",
"riot-mach-exception-state-check": "MACH_EXCEPTION_STATE",
"riot-running-application-check": "RUNNING_APP",
"riot-task-info-check": "TASK_INFO",
"riot-appkit-pump-check": "APPKIT_PUMP",
"riot-event-coalescing-check": "EVENT_COALESCING",
"riot-scroll-event-check": "SCROLL_",
"riot-pthread-integrity-check": "PTHREAD_INTEGRITY",
"riot-malloc-integrity-check": "MALLOC_INTEGRITY",
"riot-rpc-signal-mask-check": "RPC_SIGNAL_MASK",
"riot-workqueue-reuse-check": "WORKQUEUE_REUSE",
"riot-kqueue-lifetime-check": "KQUEUE_",
"riot-vnode-close-check": "VNODE_CLOSE",
"riot-kqueue-timer-check": "KQUEUE_TIMER",
"riot-kqueue-stack-check": "KQUEUE_SMALL_STACK",
"riot-kqueue-dispatch2-check": "DISPATCH2",
"riot-dispatch-fd-check": "DISPATCH_FD",
}
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("check", choices=checks)
parser.add_argument("--library-path", default="@GUEST_HOME@/RuntimeLibraries")
parser.add_argument("--framework-path", default="@GUEST_HOME@/RuntimeFrameworks")
parser.add_argument("--timeout", type=int, default=30)
args = parser.parse_args()
if not 1 <= args.timeout <= 120:
parser.error("timeout must be between 1 and 120 seconds")
binary = (root / "build" / args.check).resolve()
if not binary.is_file():
parser.error("probe has not been built")
def owned_guests():
found = {}
for entry in Path("/proc").iterdir():
if not entry.name.isdigit():
continue
try:
if entry.joinpath("exe").readlink().name != "mldr":
continue
if str(binary) not in entry.joinpath("maps").read_text():
continue
fields = entry.joinpath("stat").read_text().rsplit(")", 1)[1].split()
found[int(entry.name)] = fields[19]
except OSError:
pass
return found
previous = owned_guests()
environment = dict(os.environ, DYLD_LIBRARY_PATH=args.library_path,
DYLD_FRAMEWORK_PATH=args.framework_path)
# A killed shell can leave a guest holding inherited stdout open. File capture
# avoids communicate() waiting forever on that guest's pipe after a timeout.
with tempfile.TemporaryFile() as output:
process = subprocess.Popen(["darling", "shell", "/Volumes/SystemRoot" + str(binary)],
env=environment, stdout=output, stderr=output)
timed_out = False
try:
result = process.wait(timeout=args.timeout)
except subprocess.TimeoutExpired:
timed_out = True
process.kill()
process.wait(timeout=3)
for pid, identity in owned_guests().items():
if pid not in previous and owned_guests().get(pid) == identity:
try:
os.kill(pid, signal.SIGKILL)
except ProcessLookupError:
pass
result = 124
output.seek(0)
observed = False
for line in output.read().decode(errors="replace").splitlines():
if line.startswith(checks[args.check]):
observed = True
print(line)
if (args.check == "riot-running-application-check" and
line != "RUNNING_APP found=1 activated=1 missing=1"):
result = 1
if (args.check == "riot-mach-exception-state-check" and
line != "MACH_EXCEPTION_STATE state=1 identity=1 handled=2 server=1"):
result = 1
if result == 0 and not observed:
print("NATIVE_CHECK missing_probe_output=1")
result = 1
print(f"NATIVE_CHECK name={args.check} timed_out={int(timed_out)} exit={result}")
raise SystemExit(result)