From 2bbd177d5a68e1dff83cc81afaae706c58f81a12 Mon Sep 17 00:00:00 2001 From: PioLing <964472638@qq.com> Date: Sat, 31 May 2025 11:26:00 +0800 Subject: [PATCH] Add win32 core dump (#4291) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 单元测试代码 int main() { System::systemSetup(); int *p = nullptr; *p = 1; // 强制崩溃 return 0; } 崩溃后直接用 vs2019(2022) 打开 dmp 文件。 菜单选择 File → Open → File...,选择你的 .dmp 文件。 提示你“选择符号和源码”,若有源码和 pdb/symbol 文件能看到更详细的堆栈。 --- server/System.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++++ server/main.cpp | 5 ++--- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/server/System.cpp b/server/System.cpp index c37e4958..c76af03e 100644 --- a/server/System.cpp +++ b/server/System.cpp @@ -15,6 +15,12 @@ #if !defined(ANDROID) #include #endif//!defined(ANDROID) +#else +#include +#include +#include +#include +#pragma comment(lib, "DbgHelp.lib") #endif//!defined(_WIN32) #include @@ -213,6 +219,48 @@ void System::systemSetup(){ // Ignore the hang up signal signal(SIGHUP, SIG_IGN); #endif// ANDROID +#else + // 避免系统弹窗导致程序阻塞,适合无界面或后台服务场景。 + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); + +#if !defined(__MINGW32__) + // 将assert和error时错误输出 + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); +#endif + + _setmode(0, _O_BINARY); + _setmode(1, _O_BINARY); + _setmode(2, _O_BINARY); + + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + std::ios_base::sync_with_stdio(false); + + // 注册crash自动生成dump(等价core dump) + SetUnhandledExceptionFilter([](EXCEPTION_POINTERS *pException) -> LONG { + // 生成 dump 文件名,带时间戳 + char dumpPath[MAX_PATH]; + std::time_t t = std::time(nullptr); + std::tm tm; +#ifdef _MSC_VER + localtime_s(&tm, &t); +#else + tm = *std::localtime(&t); +#endif + std::strftime(dumpPath, sizeof(dumpPath), "crash_%Y%m%d_%H%M%S.dmp", &tm); + + HANDLE hFile = CreateFileA(dumpPath, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); + if (hFile != INVALID_HANDLE_VALUE) { + MINIDUMP_EXCEPTION_INFORMATION mdei; + mdei.ThreadId = GetCurrentThreadId(); + mdei.ExceptionPointers = pException; + mdei.ClientPointers = FALSE; + MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, nullptr, nullptr); + CloseHandle(hFile); + } + return EXCEPTION_EXECUTE_HANDLER; + }); #endif//!defined(_WIN32) } diff --git a/server/main.cpp b/server/main.cpp index 051f2bfe..014517da 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -41,9 +41,7 @@ #include "ZLMVersion.h" #endif -#if !defined(_WIN32) #include "System.h" -#endif//!defined(_WIN32) using namespace std; using namespace toolkit; @@ -259,10 +257,11 @@ int start_main(int argc,char *argv[]) { // Start daemon process System::startDaemon(kill_parent_if_failed); } +#endif //! defined(_WIN32) + // 开启崩溃捕获等 [AUTO-TRANSLATED:9c7c759c] // Enable crash capture, etc. System::systemSetup(); -#endif//!defined(_WIN32) // 启动异步日志线程 [AUTO-TRANSLATED:c93cc6f4] // Start asynchronous log thread