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