mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 18:25:35 -04:00
cf87fd8fc6
New runtime/src/crash_trace.c writes psx_last_run_report.json with: reason / timestamp / frame / last_func_addr / last_store_pc full CPU register state (all 32 GPRs + hi/lo/sr/cause/epc) dispatch_ring tail (last 256 dispatched func entries) unknown_dispatch tail (last 50 entries with addr/phys/ra/a0/a1) dirty_block_log tail (last 100 entries) Windows SEH info (when triggered from SEH filter) Triggered from: - SIGSEGV / SIGABRT signal handlers - Windows SetUnhandledExceptionFilter (catches access violations) - atexit - psx_unknown_dispatch fail-fast path (set PSX_FAIL_FAST_UNKNOWN_DISPATCH=1) - trap_crash (existing fatal trap path) File overwrites per dump (last-write-wins). Per CLAUDE.md §3 this is not a log — it's a one-shot final state snapshot for crashes the running TCP server cannot intercept. Pattern mirrors F:/Projects/SuperMarioWorldRecomp/src/post_mortem.c. Used the new infrastructure to capture a controlled crash with 0xBFC0989C re-seeded. Crash dump revealed the chain: - JAL at 0xBFC09788 is jalr $s3, NOT jalr $a0 - $s3 was set in func_1FC09598 prologue: $s3 = $a2 (callee saves arg) - Caller at 0xBFC093C4 in func_1FC092EC: $a2 = $s3 - 128 (delay slot) - func_1FC092EC at 0xBFC09314: $s3 = $a3 (callee saves arg) So real bug is upstream-of-upstream caller passing $a3 = 131 (0x83) to func_1FC092EC, propagating down to a misaligned function pointer. The 0xA000E1E8 we suspected as a function-pointer table was a red herring — $a0 in the loop body is loaded from $fp+s1*4 (the ARG to pass to the called fn), not the call target. 0xBFC0989C reverted out of seed list (was diagnostic-only). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
24 lines
655 B
C
24 lines
655 B
C
#ifndef PSXRECOMP_V4_CRASH_TRACE_H
|
|
#define PSXRECOMP_V4_CRASH_TRACE_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Install signal/SEH/atexit handlers. Call once early in main(). */
|
|
void psx_crash_trace_install_handlers(void);
|
|
|
|
/* Manually trigger a crash dump. `reason` is a short string identifying
|
|
* the trigger (e.g. "fail_fast_unknown_dispatch", "trap_crash"). On
|
|
* Windows, `seh_info` is the EXCEPTION_POINTERS* from the SEH filter or
|
|
* NULL. Writes to psx_last_run_report.json (overwrite). */
|
|
void psx_crash_trace_dump(const char *reason, void *seh_info);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PSXRECOMP_V4_CRASH_TRACE_H */
|