Crashdumps詳解

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FFIIB的頭像FFIIB
上一篇 2025-01-13 13:23
下一篇 2025-01-13 13:23

相關推薦

  • Linux sync詳解

    一、sync概述 sync是Linux中一個非常重要的命令,它可以將文件系統緩存中的內容,強制寫入磁盤中。在執行sync之前,所有的文件系統更新將不會立即寫入磁盤,而是先緩存在內存…

    編程 2025-04-25
  • 神經網絡代碼詳解

    神經網絡作為一種人工智能技術,被廣泛應用於語音識別、圖像識別、自然語言處理等領域。而神經網絡的模型編寫,離不開代碼。本文將從多個方面詳細闡述神經網絡模型編寫的代碼技術。 一、神經網…

    編程 2025-04-25
  • Linux修改文件名命令詳解

    在Linux系統中,修改文件名是一個很常見的操作。Linux提供了多種方式來修改文件名,這篇文章將介紹Linux修改文件名的詳細操作。 一、mv命令 mv命令是Linux下的常用命…

    編程 2025-04-25
  • Python輸入輸出詳解

    一、文件讀寫 Python中文件的讀寫操作是必不可少的基本技能之一。讀寫文件分別使用open()函數中的’r’和’w’參數,讀取文件…

    編程 2025-04-25
  • nginx與apache應用開發詳解

    一、概述 nginx和apache都是常見的web服務器。nginx是一個高性能的反向代理web服務器,將負載均衡和緩存集成在了一起,可以動靜分離。apache是一個可擴展的web…

    編程 2025-04-25
  • MPU6050工作原理詳解

    一、什麼是MPU6050 MPU6050是一種六軸慣性傳感器,能夠同時測量加速度和角速度。它由三個傳感器組成:一個三軸加速度計和一個三軸陀螺儀。這個組合提供了非常精細的姿態解算,其…

    編程 2025-04-25
  • 詳解eclipse設置

    一、安裝與基礎設置 1、下載eclipse並進行安裝。 2、打開eclipse,選擇對應的工作空間路徑。 File -> Switch Workspace -> [選擇…

    編程 2025-04-25
  • C語言貪吃蛇詳解

    一、數據結構和算法 C語言貪吃蛇主要運用了以下數據結構和算法: 1. 鏈表 typedef struct body { int x; int y; struct body *nex…

    編程 2025-04-25
  • Python安裝OS庫詳解

    一、OS簡介 OS庫是Python標準庫的一部分,它提供了跨平台的操作系統功能,使得Python可以進行文件操作、進程管理、環境變量讀取等系統級操作。 OS庫中包含了大量的文件和目…

    編程 2025-04-25
  • Java BigDecimal 精度詳解

    一、基礎概念 Java BigDecimal 是一個用於高精度計算的類。普通的 double 或 float 類型只能精確表示有限的數字,而對於需要高精度計算的場景,BigDeci…

    編程 2025-04-25

發表回復

登錄後才能評論