diff --git a/Makefile.port b/Makefile.port index 85e4bee9c..1c0adafbd 100644 --- a/Makefile.port +++ b/Makefile.port @@ -305,6 +305,9 @@ $(G_DIR)/tiles/%.h: $(A_DIR)/tiles/%.json $(BIN): $(O_FILES) $(LD) $(COMMON_CFLAGS) $(OPT_LVL) -o $(BIN) $^ $(LDFLAGS) +ifneq ($(CV2PDB),) + $(CV2PDB) $(BIN) +endif $(B_DIR)/%.o: %.c @mkdir -p $(dir $@) diff --git a/port/include/system.h b/port/include/system.h index 9c2721bb5..672c27220 100644 --- a/port/include/system.h +++ b/port/include/system.h @@ -29,6 +29,7 @@ f32 sysGetSeconds(void); void sysFatalError(const char *fmt, ...) __attribute__((noreturn)); +s32 sysLogIsOpen(void); void sysLogPrintf(s32 level, const char *fmt, ...); void sysGetExecutablePath(char *outPath, const u32 outLen); diff --git a/port/src/crash.c b/port/src/crash.c index 77a8228ed..dc0536589 100644 --- a/port/src/crash.c +++ b/port/src/crash.c @@ -10,7 +10,8 @@ #include "system.h" #include "platform.h" -#define CRASH_MAX_MSG 4096 +#define CRASH_LOG_FNAME "pd.crash.log" +#define CRASH_MAX_MSG 8192 #define CRASH_MAX_SYM 256 #define CRASH_MAX_FRAMES 32 #define CRASH_MSG(...) \ @@ -79,8 +80,8 @@ static void crashStackTrace(char *msg, PEXCEPTION_POINTERS exinfo) if (SymGetLineFromAddr64(process, (uintptr_t)exinfo->ExceptionRecord->ExceptionAddress, &disp, &line)) { CRASH_MSG(": %s:%lu+%lu", line.FileName, line.LineNumber, disp); } - CRASH_MSG("\nMODULE: %p\n", crashGetModuleBase(exinfo->ExceptionRecord->ExceptionAddress)); - CRASH_MSG("MAIN MODULE: %p\n", crashGetModuleBase(crashInit)); + CRASH_MSG("\nMODULE: [%p]\n", crashGetModuleBase(exinfo->ExceptionRecord->ExceptionAddress)); + CRASH_MSG("MAIN MODULE: [%p]\n", crashGetModuleBase(crashInit)); CRASH_MSG("\nBACKTRACE:\n"); char symbuf[sizeof(SYMBOL_INFO) + CRASH_MAX_SYM * sizeof(TCHAR)]; @@ -99,6 +100,10 @@ static void crashStackTrace(char *msg, PEXCEPTION_POINTERS exinfo) if (SymFromAddr(process, stackframe.AddrPC.Offset, &disp64, sym)) { CRASH_MSG(": %s+%llu", sym->Name, disp64); + } else if (process, stackframe.AddrPC.Offset) { + const uintptr_t modbase = (uintptr_t)crashGetModuleBase((void *)(uintptr_t)stackframe.AddrPC.Offset); + const uintptr_t modofs = (uintptr_t)stackframe.AddrPC.Offset - modbase; + CRASH_MSG(": [%p]+%p", (void *)modbase, (void *)modofs); } if(SymGetLineFromAddr64(process, stackframe.AddrPC.Offset, &disp, &line)) { @@ -135,6 +140,15 @@ static long __stdcall crashHandler(PEXCEPTION_POINTERS exinfo) crashStackTrace(msg, exinfo); + // open log file for the crash dump if one hasn't been opened yet + if (!sysLogIsOpen()) { + FILE *f = fopen(CRASH_LOG_FNAME, "wb"); + if (f) { + fprintf(f, "Crash!\n\n%s", msg); + fclose(f); + } + } + sysFatalError("Crash!\n\n%s", msg); return EXCEPTION_CONTINUE_EXECUTION; diff --git a/port/src/system.c b/port/src/system.c index 432fc0a39..14666bbb9 100644 --- a/port/src/system.c +++ b/port/src/system.c @@ -12,6 +12,7 @@ #include "system.h" #define LOG_FNAME "pd.log" +#define CRASHLOG_FNAME "pd.crash.log" #define USEC_IN_SEC 1000000ULL static u64 startTick = 0; @@ -20,6 +21,24 @@ static char logPath[2048]; static s32 sysArgc; static const char **sysArgv; +static inline void sysLogSetPath(const char *fname) +{ + // figure out where the log is and clear it + // try working dir first + snprintf(logPath, sizeof(logPath), "./%s", fname); + FILE *f = fopen(logPath, "wb"); + if (!f) { + // try home dir + sysGetHomePath(logPath, sizeof(logPath) - 1); + strncat(logPath, "/", sizeof(logPath) - 1); + strncat(logPath, fname, sizeof(logPath) - 1); + f = fopen(logPath, "wb"); + } + if (f) { + fclose(f); + } +} + void sysInitArgs(s32 argc, const char **argv) { sysArgc = argc; @@ -31,19 +50,7 @@ void sysInit(void) startTick = sysGetMicroseconds(); if (sysArgCheck("--log")) { - // figure out where the log is and clear it - // try working dir first - snprintf(logPath, sizeof(logPath), "./%s", LOG_FNAME); - FILE *f = fopen(logPath, "wb"); - if (!f) { - // try home dir - sysGetHomePath(logPath, sizeof(logPath) - 1); - strncat(logPath, "/" LOG_FNAME, sizeof(logPath) - 1); - f = fopen(logPath, "wb"); - } - if (f) { - fclose(f); - } + sysLogSetPath(LOG_FNAME); } #ifdef VERSION_HASH @@ -103,6 +110,11 @@ float sysGetSeconds(void) return (f32)t / 1000000.f; } +s32 sysLogIsOpen(void) +{ + return (logPath[0] != '\0'); +} + void sysLogPrintf(s32 level, const char *fmt, ...) { static const char *prefix[3] = {