sigaltstack() is per thread. InstallExceptionHandler() runs in CPU_Init()
on the loading thread, which exits after boot, while the faults come from
the CPU thread and UninstallExceptionHandler() runs on the emu thread. So
our stack was never used, and the uninstall "restored" the loading
thread's previous alt stack onto the emu thread. On Android that's the
one bionic gives each thread and frees when the thread exits, so every
later fault on the emu thread ran its handler on freed memory. A Play
crash report shows scudo finding a corrupted chunk header when freeing our
stack in UninstallExceptionHandler().
The alt stack came with the Dolphin code, which needs it to handle its own
stack overflows. Ours only handles guest memory faults, so let the handler
run on the faulting thread's stack, or the alt stack that thread already
has. This also leaves a libretro frontend's alt stack alone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>