隨着計算機應用的不斷發展,軟件崩潰問題難免會發生,而軟件崩潰後留下的信息也是非常有價值的,這便是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/zh-hant/n/325139.html