diff --git a/src/game/crash_screen.c b/src/game/crash_screen.c index 3f47756d..197f32e3 100644 --- a/src/game/crash_screen.c +++ b/src/game/crash_screen.c @@ -15,8 +15,9 @@ #include "printf.h" enum crashPages { - PAGE_STACK, + PAGE_CONTEXT, PAGE_LOG, + PAGE_STACKTRACE, PAGE_COUNT }; @@ -68,6 +69,7 @@ char *gFpcsrDesc[6] = { extern u64 osClockRate; extern far char *parse_map(u32); extern far void map_data_init(void); +extern far char *find_function_in_stack(u32 *); struct { OSThread thread; @@ -187,7 +189,7 @@ void crash_screen_print_fpcsr(u32 fpcsr) { } } -void draw_crash_stack(OSThread *thread, s32 cause) +void draw_crash_context(OSThread *thread, s32 cause) { __OSThreadContext *tc = &thread->context; @@ -200,7 +202,8 @@ void draw_crash_stack(OSThread *thread, s32 cause) crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1); } else { - crash_screen_print(30, 50, "CRASH AT: %s", parse_map(tc->pc)); + char *fname = parse_map(tc->pc); + crash_screen_print(30, 50, "CRASH AT: %s", fname == NULL ? "UNKNOWN" : fname); } // crash_screen_print(30, 50, "AT:%08XH V0:%08XH V1:%08XH", (u32) tc->at, (u32) tc->v0, (u32) tc->v1); crash_screen_print(30, 60, "A0:%08XH A1:%08XH A2:%08XH", (u32) tc->a0, (u32) tc->a1, (u32) tc->a2); @@ -250,6 +253,42 @@ void draw_crash_log(OSThread *thread, s32 cause) } +// prints any function pointers it finds in the stack +// format: +// SP address: function name +void draw_stacktrace(OSThread *thread, s32 cause) { + __OSThreadContext *tc = &thread->context; + u32 temp_sp = tc->sp + 0x14; + + crash_screen_draw_rect(25, 20, 270, 25); + crash_screen_print(30, 25, "STACK TRACE FROM %08X:", temp_sp); + if ((u32) parse_map == 0x80345678) { + crash_screen_print(30, 35, "CURRFUNC: NONE"); + } else { + crash_screen_print(30, 35, "CURRFUNC: %s", parse_map(tc->pc)); + } + + osWritebackDCacheAll(); + + for (int i = 0; i < 16; i++) { + if ((u32) find_function_in_stack == 0x80345678) { + crash_screen_print(30, 45 + (i * 10), "STACK TRACE DISABLED"); + break; + } else { + char *fname = find_function_in_stack(&temp_sp); + if (fname == NULL || (*(u32*)temp_sp & 0x80000000 == 0)) { + crash_screen_print(30, 45 + (i * 10), "%08X: UNKNOWN", temp_sp); + } else { + crash_screen_print(30, 45 + (i * 10), "%08X: %s", temp_sp, fname); + } + } + } + + +} + + + void draw_crash_screen(OSThread *thread) { s32 cause; @@ -291,8 +330,9 @@ void draw_crash_screen(OSThread *thread) crash_screen_print(15, 10, "Page:%d L/Z: Left R: Right", crashPage); switch (crashPage) { - case PAGE_STACK: draw_crash_stack(thread, cause); break; - case PAGE_LOG: draw_crash_log(thread, cause); break; + case PAGE_CONTEXT: draw_crash_context(thread, cause); break; + case PAGE_LOG: draw_crash_log(thread, cause); break; + case PAGE_STACKTRACE: draw_stacktrace(thread, cause); break; } osWritebackDCacheAll();