#include #ifdef _WIN32 #include #include /// Ddghelp.h 必须在 Windows.h 后定义 #include static LONG WINAPI CreateMiniDump(EXCEPTION_POINTERS *pExceptionPointers) { HANDLE hFile = CreateFileA("crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { scc_fprintf(scc_stderr, "Failed to create crash.dmp\n"); return EXCEPTION_EXECUTE_HANDLER; } MINIDUMP_EXCEPTION_INFORMATION mei = {0}; BOOL bDumpWithException = FALSE; if (pExceptionPointers != NULL) { // 有异常上下文(来自 UnhandledExceptionFilter) mei.ThreadId = GetCurrentThreadId(); mei.ExceptionPointers = pExceptionPointers; mei.ClientPointers = FALSE; bDumpWithException = TRUE; } else { // 没有异常上下文(例如来自 abort 信号),捕获当前线程上下文 CONTEXT ctx = {0}; ctx.ContextFlags = CONTEXT_FULL; RtlCaptureContext(&ctx); // 获取当前执行点寄存器状态 static EXCEPTION_POINTERS fakeEP = {0}; static EXCEPTION_RECORD fakeER = {0}; fakeER.ExceptionCode = 0xE0000001; // 自定义异常码 fakeER.ExceptionFlags = 0; fakeER.ExceptionRecord = NULL; fakeER.ExceptionAddress = (PVOID)ctx.Rip; // 当前指令指针 fakeER.NumberParameters = 0; fakeEP.ExceptionRecord = &fakeER; fakeEP.ContextRecord = &ctx; mei.ThreadId = GetCurrentThreadId(); mei.ExceptionPointers = &fakeEP; mei.ClientPointers = FALSE; bDumpWithException = TRUE; } MINIDUMP_TYPE dumpType = (MINIDUMP_TYPE)(MiniDumpWithFullMemory); BOOL bOK = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, dumpType, bDumpWithException ? &mei : NULL, NULL, NULL); CloseHandle(hFile); if (bOK) scc_fprintf(scc_stderr, "Minidump written: crash.dmp\n"); else scc_fprintf(scc_stderr, "MiniDumpWriteDump failed: %lu\n", GetLastError()); return EXCEPTION_EXECUTE_HANDLER; } void SignalHandler(int sig) { if (sig == SIGABRT) { #ifdef DEV_MODE CreateMiniDump(NULL); #else scc_fprintf(scc_stderr, "Press Enter to continue..."); getchar(); #endif _exit(1); } } #endif void init_platform(void) { #ifdef _WIN32 signal(SIGABRT, SignalHandler); #ifdef DEV_MODE SetUnhandledExceptionFilter(CreateMiniDump); #endif SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); #endif }