From b1b17e21c18f4e748598d961adeded28348b9b3c Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jan 2024 15:40:30 +0100 Subject: [PATCH 1/5] port: write crash info to log file even without --log --- port/include/system.h | 1 + port/src/crash.c | 3 +++ port/src/system.c | 40 +++++++++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/port/include/system.h b/port/include/system.h index 005dbaf48..e6b75ac3d 100644 --- a/port/include/system.h +++ b/port/include/system.h @@ -24,6 +24,7 @@ u64 sysGetMicroseconds(void); void sysFatalError(const char *fmt, ...) __attribute__((noreturn)); +void sysLogStartCrash(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..1ea2ea557 100644 --- a/port/src/crash.c +++ b/port/src/crash.c @@ -128,6 +128,9 @@ static long __stdcall crashHandler(PEXCEPTION_POINTERS exinfo) return EXCEPTION_CONTINUE_EXECUTION; } + // start writing to a crash log file + sysLogStartCrash(); + sysLogPrintf(LOG_ERROR, "FATAL: Crashed: PC=%p CODE=0x%08lx", exinfo->ExceptionRecord->ExceptionAddress, exinfo->ExceptionRecord->ExceptionCode); fflush(stderr); diff --git a/port/src/system.c b/port/src/system.c index 5261f05cd..fb24addd0 100644 --- a/port/src/system.c +++ b/port/src/system.c @@ -11,6 +11,7 @@ #include "system.h" #define LOG_FNAME "pd.log" +#define CRASHLOG_FNAME "pd.crash.log" #define USEC_IN_SEC 1000000ULL static u64 startTick = 0; @@ -19,6 +20,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; @@ -30,19 +49,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 @@ -96,6 +103,13 @@ u64 sysGetMicroseconds(void) return ((u64)tv.tv_sec * USEC_IN_SEC + (u64)tv.tv_usec) - startTick; } +void sysLogStartCrash(void) +{ + if (!logPath[0]) { + sysLogSetPath(CRASHLOG_FNAME); + } +} + void sysLogPrintf(s32 level, const char *fmt, ...) { static const char *prefix[3] = { From 06f22831804128bf33b16851eb5b9f8aa049748f Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jan 2024 16:09:04 +0100 Subject: [PATCH 2/5] port: use cv2pdb on windows executables if present --- Makefile.port | 10 ++++++++++ port/src/crash.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile.port b/Makefile.port index 0a53f3d33..e7a266855 100644 --- a/Makefile.port +++ b/Makefile.port @@ -154,6 +154,13 @@ ifneq (,$(findstring windows,$(TARGET_PLATFORM))) TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lz -lopengl32 -static-libstdc++ -ldbghelp # on windows/mingw we need this to be built with a 32-bit compiler so it finds the correct libs TOOLCHAIN ?= i686-w64-mingw32- + # check if cv2pdb is present + ifeq ($(CV2PDB),) + CV2PDB := cv2pdb + ifeq (,$(shell which cv2pdb 2>/dev/null)) + CV2PDB := + endif + endif else # assume *nix TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lGL -lz -ldl @@ -305,6 +312,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/src/crash.c b/port/src/crash.c index 1ea2ea557..47c24101b 100644 --- a/port/src/crash.c +++ b/port/src/crash.c @@ -10,7 +10,7 @@ #include "system.h" #include "platform.h" -#define CRASH_MAX_MSG 4096 +#define CRASH_MAX_MSG 8192 #define CRASH_MAX_SYM 256 #define CRASH_MAX_FRAMES 32 #define CRASH_MSG(...) \ From d1d288b96a92ea5e359e23cc73fa14be82eb38ae Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jan 2024 16:43:02 +0100 Subject: [PATCH 3/5] port: don't use cv2pdb by default if it exists --- Makefile.port | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Makefile.port b/Makefile.port index e7a266855..b8ebadb12 100644 --- a/Makefile.port +++ b/Makefile.port @@ -154,13 +154,6 @@ ifneq (,$(findstring windows,$(TARGET_PLATFORM))) TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lz -lopengl32 -static-libstdc++ -ldbghelp # on windows/mingw we need this to be built with a 32-bit compiler so it finds the correct libs TOOLCHAIN ?= i686-w64-mingw32- - # check if cv2pdb is present - ifeq ($(CV2PDB),) - CV2PDB := cv2pdb - ifeq (,$(shell which cv2pdb 2>/dev/null)) - CV2PDB := - endif - endif else # assume *nix TARGET_CFLAGS := $(shell pkg-config sdl2 --cflags-only-I) TARGET_LDFLAGS := $(shell pkg-config sdl2 --libs) -lGL -lz -ldl From ba52580e0c70b9f2b35ce76831fa3d59e64dd75a Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jan 2024 16:43:20 +0100 Subject: [PATCH 4/5] port: display module offsets in the windows crashlog --- port/src/crash.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/port/src/crash.c b/port/src/crash.c index 47c24101b..e2b6be079 100644 --- a/port/src/crash.c +++ b/port/src/crash.c @@ -79,8 +79,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 +99,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)) { From 8645d0a82a5c89650e834b898b7b4deb3108c4fb Mon Sep 17 00:00:00 2001 From: fgsfds Date: Sun, 7 Jan 2024 17:07:12 +0100 Subject: [PATCH 5/5] port: don't use the existing log system in crashlog in case it crashes --- port/include/system.h | 2 +- port/src/crash.c | 13 ++++++++++--- port/src/system.c | 6 ++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/port/include/system.h b/port/include/system.h index e6b75ac3d..94158802a 100644 --- a/port/include/system.h +++ b/port/include/system.h @@ -24,7 +24,7 @@ u64 sysGetMicroseconds(void); void sysFatalError(const char *fmt, ...) __attribute__((noreturn)); -void sysLogStartCrash(void); +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 e2b6be079..dc0536589 100644 --- a/port/src/crash.c +++ b/port/src/crash.c @@ -10,6 +10,7 @@ #include "system.h" #include "platform.h" +#define CRASH_LOG_FNAME "pd.crash.log" #define CRASH_MAX_MSG 8192 #define CRASH_MAX_SYM 256 #define CRASH_MAX_FRAMES 32 @@ -132,9 +133,6 @@ static long __stdcall crashHandler(PEXCEPTION_POINTERS exinfo) return EXCEPTION_CONTINUE_EXECUTION; } - // start writing to a crash log file - sysLogStartCrash(); - sysLogPrintf(LOG_ERROR, "FATAL: Crashed: PC=%p CODE=0x%08lx", exinfo->ExceptionRecord->ExceptionAddress, exinfo->ExceptionRecord->ExceptionCode); fflush(stderr); @@ -142,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 fb24addd0..538dd1e87 100644 --- a/port/src/system.c +++ b/port/src/system.c @@ -103,11 +103,9 @@ u64 sysGetMicroseconds(void) return ((u64)tv.tv_sec * USEC_IN_SEC + (u64)tv.tv_usec) - startTick; } -void sysLogStartCrash(void) +s32 sysLogIsOpen(void) { - if (!logPath[0]) { - sysLogSetPath(CRASHLOG_FNAME); - } + return (logPath[0] != '\0'); } void sysLogPrintf(s32 level, const char *fmt, ...)