随着计算机应用的不断发展,软件崩溃问题难免会发生,而软件崩溃后留下的信息也是非常有价值的,这便是crashdumps。
一、什么是crashdumps
crashdumps是软件崩溃时产生的一种数据文件,记录了软件崩溃时的状态信息和执行堆栈信息。通过分析crashdumps能够找出崩溃原因,加速故障排查。
crashdumps是一种操作系统级别的特性,在Windows系统中,它通常使用“.dmp”后缀命名。crashdumps文件名包括了产生该文件的进程ID、线程ID和时间戳等信息。
// C++代码示例 // 生成Crash Dumps文件 BOOL GenerateDump(DWORD dwProcessId, DWORD dwThreadId, HANDLE hDumpFile) { BOOL bSuccess = FALSE; HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE, dwProcessId); if(hProcess != NULL) { CONTEXT Context; ZeroMemory(&Context, sizeof(Context)); Context.ContextFlags = CONTEXT_FULL; if(::SuspendThread(hThread) != (DWORD)-1) { CONTEXT Context; ZeroMemory(&Context, sizeof(Context)); Context.ContextFlags = CONTEXT_FULL; if(::GetThreadContext(hThread, &Context)) { DWORD64 dwImageBase = GetModuleBase(hProcess, GetIp(Context)); if(dwImageBase) { MINIDUMP_EXCEPTION_INFORMATION ExceptionInformation; ZeroMemory(&ExceptionInformation, sizeof(ExceptionInformation)); ExceptionInformation.ThreadId = dwThreadId; ExceptionInformation.ExceptionPointers = (EXCEPTION_POINTERS*)malloc(sizeof(EXCEPTION_POINTERS)); ExceptionInformation.ExceptionPointers->ContextRecord = ContextRecord; ExceptionInformation.ExceptionPointers->ExceptionRecord = ExceptionRecord; bSuccess = MiniDumpWriteDump(hProcess, dwProcessId, hDumpFile, MiniDumpWithDataSegs, &ExceptionInformation, NULL, NULL); } } ::ResumeThread(hThread); } ::CloseHandle(hProcess); } return bSuccess; }
二、如何使用crashdumps
crashdumps文件通常用于故障排查,可以分析文件中记录的信息找到软件崩溃的原因。当软件工作出现问题时,可以手动或者通过一些工具自动生成crashdumps。
Windows操作系统中提供了一些辅助程序可以生成crashdumps,例如procdump、ADPlus等工具。procdump 是一个轻量级的工具,它会在到达自定义的 CPU 利用率阈值或者发生异常时触发指定程序的崩溃记录( .dmp ),不影响目标应用程序的性能。
// 使用procdump生成Crash Dumps procdump.exe -ma -e 1 myapp.exe myapp.dmp // 解析Crash Dumps windbg.exe -z myapp.dmp -y SymbolPath -c "!analyze -v; !clrstack;"
根据crashdumps信息可以定位到软件崩溃的位置和原因,进而修复问题。
三、crashdumps实践
在软件开发中,为了提高软件的鲁棒性和故障排查能力,可以自行编写代码来捕获生成crashdumps。以下是一个C++实现生成crashdumps的示例代码:
// C++代码示例 int main() { SetUnhandledExceptionFilter(CustomDumpFilter); int* p = nullptr; // 故意造成异常,方便测试 *p = 1; return 0; } LONG WINAPI CustomDumpFilter(_In_ struct _EXCEPTION_POINTERS* ExceptionInfo) { WCHAR szDumpPath[MAX_PATH] = { 0 }; if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_DESKTOPDIRECTORY, NULL, 0, szDumpPath))) { WCHAR szFileName[MAX_PATH] = { 0 }; SYSTEMTIME st = { 0 }; GetLocalTime(&st); wsprintf(szFileName, L"crash-%04d%02d%02d-%02d%02d%02d.dmp", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); PathAppend(szDumpPath, szFileName); HANDLE hFile = CreateFile(szDumpPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { MINIDUMP_EXCEPTION_INFORMATION exceptionInfo; exceptionInfo.ThreadId = GetCurrentThreadId(); exceptionInfo.ExceptionPointers = ExceptionInfo; exceptionInfo.ClientPointers = FALSE; MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpWithDataSegs, &exceptionInfo, NULL, NULL); CloseHandle(hFile); } } return EXCEPTION_EXECUTE_HANDLER; }
在程序运行时,只需调用 SetUnhandledExceptionFilter 函数即可指定自定义的异常处理函数。当程序发生异常崩溃时,CustomDumpFilter 函数会被调用,该函数负责生成一个crashdumps文件并保存到指定位置。
四、总结
crashdumps是一种有效的故障排查工具,可以帮助程序员解决软件崩溃问题。本文详细介绍了crashdumps的概念、使用方法和代码实践,希望对大家有所帮助。
原创文章,作者:FFIIB,如若转载,请注明出处:https://www.506064.com/n/325139.html