Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: multi-process init — ac-native as child, SDL crash auto-recovery

Init (PID 1) now spawns ac-native as a child process via &/wait.
If ac-native crashes from DRI/Mesa (signal > 128), init automatically
restarts it with AC_NO_SDL=1, falling back to DRM dumb buffers.

Flow: init → spawn ac-native (SDL enabled) → if signal crash →
respawn with AC_NO_SDL=1 (DRM only) → stable boot.

SDL/Mesa/DRI libs restored in initramfs. On hardware with working
GPU drivers, SDL3 GPU acceleration works. On broken DRI, auto-fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+62 -27
+21 -8
fedac/native/docker-build.sh
··· 216 216 [ -f "$REAL" ] && cp -L "$REAL" "$IROOT/lib64/$BASENAME" 217 217 done 218 218 219 - # SDL3 + Mesa/GPU libs — NOT included in initramfs. 220 - # Mesa DRI drivers segfault on ThinkPad 11e during dlopen and no signal 221 - # handler can recover (process state is corrupted). SDL3 GPU acceleration 222 - # will be enabled when we move to a multi-process architecture where 223 - # ac-native runs as a child of init (not PID 1), so DRI crashes are 224 - # recoverable via process restart. 225 - # For now: DRM dumb buffers work fine for all target hardware. 226 - log " SDL3/Mesa libs: skipped (DRM dumb buffer mode)" 219 + # SDL3 + Mesa/GPU libs — included for GPU acceleration via dlopen. 220 + # ac-native runs as a child of init (not PID 1), so if Mesa DRI crashes, 221 + # init catches the signal and restarts without SDL (AC_NO_SDL=1). 222 + for lib in libSDL3.so.0 \ 223 + libgbm.so.1 libEGL.so.1 libEGL_mesa.so.0 libGLESv2.so.2 \ 224 + libGL.so.1 libGLX_mesa.so.0 libGLdispatch.so.0 libglapi.so.0 \ 225 + libdrm_intel.so.1 libdrm_amdgpu.so.1; do 226 + REAL=$(readlink -f "/lib64/$lib" 2>/dev/null) 227 + [ -f "$REAL" ] && cp -L "$REAL" "$IROOT/lib64/$lib" 228 + done 229 + 230 + # Mesa DRI drivers 231 + if [ -d /lib64/dri ]; then 232 + mkdir -p "$IROOT/lib64/dri" 233 + for drv in /lib64/dri/i915_dri.so /lib64/dri/iris_dri.so /lib64/dri/kms_swrast_dri.so /lib64/dri/swrast_dri.so; do 234 + [ -f "$drv" ] && cp -L "$drv" "$IROOT/lib64/dri/" 235 + done 236 + fi 237 + # Gallium megadriver 238 + GALLIUM=$(readlink -f /lib64/libgallium-*.so 2>/dev/null || true) 239 + [ -f "$GALLIUM" ] && cp -L "$GALLIUM" "$IROOT/lib64/" 227 240 228 241 # Transitive deps — resolve everything in lib64 229 242 log " Resolving transitive dependencies..."
+33 -18
fedac/native/initramfs/init
··· 144 144 SWANK_PID=$! 145 145 fi 146 146 147 - # Main loop — restart on crash, poweroff on exit 0, reboot on exit 2 147 + # Main loop — ac-native runs as a child process (not PID 1). 148 + # First attempt: with SDL3/GPU env vars. 149 + # If it crashes (signal), retry without SDL (AC_NO_SDL=1). 150 + # If that also crashes, keep retrying without SDL with backoff. 148 151 CRASH_COUNT=0 152 + SDL_ENABLED=1 149 153 while true; do 150 - # Pre-launch: dump lib check to both tty0 and USB 151 - echo "[init] checking libs..." > /dev/tty0 2>/dev/null 152 - LD_LIBRARY_PATH="/lib64" /lib64/ld-linux-x86-64.so.2 --list /ac-native > /tmp/ldd.log 2>&1 || true 153 - # Show missing libs on screen 154 - grep "not found" /tmp/ldd.log > /dev/tty0 2>/dev/null || echo "[init] all libs OK" > /dev/tty0 2>/dev/null 155 - [ "$USB_MOUNTED" = "1" ] && cp /tmp/ldd.log /mnt/ldd.log 2>/dev/null && sync 156 - # Launch ac-native 157 - echo "[init] launching ac-native..." > /dev/tty0 2>/dev/null 158 - LD_LIBRARY_PATH="/lib64" LIBGL_DRIVERS_PATH="/lib64/dri" GBM_DRIVERS_PATH="/lib64/dri" MESA_LOADER_DRIVER_OVERRIDE=iris /ac-native /piece.mjs 2>/tmp/ac-native-stderr.log 159 - # After crash: dump stderr to tty0 so user can see it 160 - echo "[init] ac-native exited ($?)" > /dev/tty0 2>/dev/null 161 - head -10 /tmp/ac-native-stderr.log > /dev/tty0 2>/dev/null 162 - [ "$USB_MOUNTED" = "1" ] && cp /tmp/ac-native-stderr.log /mnt/ac-native-stderr.log 2>/dev/null && sync 163 - # Pause so user can read the error 164 - sleep 5 154 + if [ "$SDL_ENABLED" = "1" ]; then 155 + echo "[init] launching ac-native (SDL3 GPU enabled)..." > /dev/tty0 2>/dev/null 156 + LD_LIBRARY_PATH="/lib64" LIBGL_DRIVERS_PATH="/lib64/dri" GBM_DRIVERS_PATH="/lib64/dri" MESA_LOADER_DRIVER_OVERRIDE=iris \ 157 + /ac-native /piece.mjs 2>/tmp/ac-native-stderr.log & 158 + else 159 + echo "[init] launching ac-native (DRM only)..." > /dev/tty0 2>/dev/null 160 + LD_LIBRARY_PATH="/lib64" AC_NO_SDL=1 \ 161 + /ac-native /piece.mjs 2>/tmp/ac-native-stderr.log & 162 + fi 163 + CHILD_PID=$! 164 + wait $CHILD_PID 165 165 EXIT_CODE=$? 166 - echo "[init] ac-native exited: code=$EXIT_CODE crash=$CRASH_COUNT" > /dev/tty0 2>/dev/null 167 - echo "[init] stderr: $(tail -5 /tmp/ac-native-stderr.log 2>/dev/null)" > /dev/tty0 2>/dev/null 166 + # Save crash info 167 + echo "[init] ac-native (pid $CHILD_PID) exited: code=$EXIT_CODE crash=$CRASH_COUNT sdl=$SDL_ENABLED" > /dev/tty0 2>/dev/null 168 + head -5 /tmp/ac-native-stderr.log > /dev/tty0 2>/dev/null 168 169 # Save crash info to USB if mounted 169 170 if [ "$USB_MOUNTED" = "1" ]; then 170 171 echo "exit=$EXIT_CODE crash=$CRASH_COUNT $(date 2>/dev/null)" >> /mnt/ac-crash.log ··· 193 194 fi 194 195 195 196 CRASH_COUNT=$((CRASH_COUNT + 1)) 197 + 198 + # If crashed with SDL enabled, disable it and retry immediately 199 + if [ "$SDL_ENABLED" = "1" ] && [ "$EXIT_CODE" -gt 128 ]; then 200 + # Exit > 128 = killed by signal (128 + signal number) 201 + SIG=$((EXIT_CODE - 128)) 202 + echo "[init] Signal $SIG with SDL — disabling GPU, retrying with DRM..." > /dev/tty0 2>/dev/null 203 + SDL_ENABLED=0 204 + if [ "$USB_MOUNTED" = "1" ]; then 205 + echo "sdl_crash: signal=$SIG, disabling SDL" >> /mnt/ac-crash.log 206 + sync 207 + fi 208 + sleep 1 209 + continue 210 + fi 196 211 197 212 # Flash screen red via framebuffer 198 213 if [ -c /dev/fb0 ]; then
+8 -1
fedac/native/src/drm-display.c
··· 105 105 } 106 106 107 107 static ACDisplay *sdl_init(void) { 108 + // Check if SDL was disabled by init after a previous crash 109 + const char *no_sdl = getenv("AC_NO_SDL"); 110 + if (no_sdl && no_sdl[0] == '1') { 111 + ac_log("[sdl3] Disabled via AC_NO_SDL (previous crash) — using DRM\n"); 112 + return NULL; 113 + } 114 + 108 115 // Set Mesa env vars before any dlopen 109 116 setenv("LIBGL_DRIVERS_PATH", "/lib64/dri", 0); 110 117 setenv("GBM_DRIVERS_PATH", "/lib64/dri", 0); 111 118 setenv("MESA_LOADER_DRIVER_OVERRIDE", "iris", 0); 112 - if (getpid() == 1) setenv("SDL_VIDEO_DRIVER", "kmsdrm", 0); 119 + setenv("SDL_VIDEO_DRIVER", "kmsdrm", 0); 113 120 114 121 // Install crash handler — catches SIGSEGV/SIGBUS from Mesa DRI loading 115 122 struct sigaction sa = {0}, old_segv = {0}, old_bus = {0}, old_abrt = {0};