Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

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

fix: crash-safe SDL3 init — probe in child process to catch segfaults

SDL3 KMSDRM init can segfault on bare metal if Mesa/EGL libs are
missing or misconfigured. Now probes in a forked child process first;
if the child crashes, SDL3 is skipped and DRM dumb buffers are used.
Also checks dlopen("libSDL3.so.0") before attempting init.

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

+47 -1
+1 -1
fedac/native/Makefile
··· 13 13 QUIRCDIR := lib/quirc/lib 14 14 QRGENDIR := lib/qrcodegen 15 15 CFLAGS := -O2 -Wall -Wextra -std=gnu11 -I$(QJSDIR) -I$(QUIRCDIR) -I$(QRGENDIR) -DAC_GIT_HASH=\"$(GIT_HASH)\" -DAC_BUILD_TS=\"$(BUILD_TS)\" -DAC_BUILD_NAME=\"$(BUILD_NAME)\" 16 - LDFLAGS := -Wl,--as-needed -lm -lpthread -lasound -lutil 16 + LDFLAGS := -Wl,--as-needed -lm -lpthread -lasound -lutil -ldl 17 17 18 18 # Static build: only when musl-gcc is available (musl has bundled static libc) 19 19 # On Fedora/standard gcc, dynamic linking is used and .so files are bundled in initramfs
+46
fedac/native/src/drm-display.c
··· 15 15 // SDL3 GPU-accelerated display (uses KMSDRM backend on bare metal) 16 16 // ============================================================ 17 17 18 + #include <dlfcn.h> 19 + #include <signal.h> 20 + #include <sys/wait.h> 21 + 22 + // Probe whether SDL3 can init without crashing (runs in a child process) 23 + static int sdl_probe_safe(void) { 24 + pid_t pid = fork(); 25 + if (pid < 0) return 0; // fork failed, skip SDL 26 + if (pid == 0) { 27 + // Child: try SDL_Init, exit 0 on success, 1 on failure, crash = signal 28 + if (getpid() != 1) // never true in child, but set env anyway 29 + setenv("SDL_VIDEO_DRIVER", "kmsdrm", 0); 30 + int ok = SDL_Init(SDL_INIT_VIDEO) ? 0 : 1; 31 + if (!ok) SDL_Quit(); 32 + _exit(ok); 33 + } 34 + // Parent: wait for child 35 + int status = 0; 36 + waitpid(pid, &status, 0); 37 + if (WIFSIGNALED(status)) { 38 + fprintf(stderr, "[sdl3] Probe crashed (signal %d) — skipping SDL3\n", 39 + WTERMSIG(status)); 40 + return 0; 41 + } 42 + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 43 + return 1; 44 + } 45 + fprintf(stderr, "[sdl3] Probe failed (exit %d) — skipping SDL3\n", 46 + WIFEXITED(status) ? WEXITSTATUS(status) : -1); 47 + return 0; 48 + } 49 + 18 50 static ACDisplay *sdl_init(void) { 51 + // Check if libSDL3 is even loadable 52 + void *sdl_lib = dlopen("libSDL3.so.0", RTLD_LAZY | RTLD_NOLOAD); 53 + if (!sdl_lib) { 54 + sdl_lib = dlopen("libSDL3.so.0", RTLD_LAZY); 55 + if (!sdl_lib) { 56 + fprintf(stderr, "[sdl3] libSDL3.so.0 not found — skipping\n"); 57 + return NULL; 58 + } 59 + } 60 + dlclose(sdl_lib); 61 + 62 + // Probe in a child process to catch segfaults 63 + if (!sdl_probe_safe()) return NULL; 64 + 19 65 // Set KMSDRM hints for bare metal (no X11/Wayland) 20 66 if (getpid() == 1) { 21 67 setenv("SDL_VIDEO_DRIVER", "kmsdrm", 0);