Windows下利用Windbg 分析dump


概述:

  1. 注冊生成dump文件的函數。
  2. 當程序收到沒有捕獲的異常時,調用上述函數,生成dump文件。
  3. 利用Windbg結合編譯程序時生成的pdb和代碼來分析dump文件,定位問題。

 

如下代碼生成dump文件(轉):

#include <Windows.h>
#include <stdio.h>
#include <DbgHelp.h>  
#pragma comment(lib, "dbghelp.lib") 

inline BOOL IsDataSectionNeeded(const WCHAR* pModuleName)  
{  
    if(pModuleName == NULL)  
    {  
        return FALSE;  
    }  
  
    WCHAR szFileName[_MAX_FNAME] = L"";  
    _wsplitpath(pModuleName, NULL, NULL, szFileName, NULL);  
  
    if(wcsicmp(szFileName, L"ntdll") == 0)  
        return TRUE;  
  
    return FALSE;  
}  
  
inline BOOL CALLBACK MiniDumpCallback(PVOID                            pParam,  
                                      const PMINIDUMP_CALLBACK_INPUT   pInput,  
                                      PMINIDUMP_CALLBACK_OUTPUT        pOutput)  
{  
    if(pInput == 0 || pOutput == 0)  
        return FALSE;  
  
    switch(pInput->CallbackType)  
    {  
    case ModuleCallback:  
        if(pOutput->ModuleWriteFlags & ModuleWriteDataSeg)  
            if(!IsDataSectionNeeded(pInput->Module.FullPath))  
                pOutput->ModuleWriteFlags &= (~ModuleWriteDataSeg);  
    case IncludeModuleCallback:  
    case IncludeThreadCallback:  
    case ThreadCallback:  
    case ThreadExCallback:  
        return TRUE;  
    default:;  
    }  
  
    return FALSE;  
}  

inline void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName)  
{  
    HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE,  
        FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);  
  
    if(hFile != INVALID_HANDLE_VALUE)
    {  
      MINIDUMP_EXCEPTION_INFORMATION mdei;
      mdei.ThreadId           = GetCurrentThreadId();  
      mdei.ExceptionPointers  = pep;  
      mdei.ClientPointers     = FALSE;  
  
      MINIDUMP_CALLBACK_INFORMATION mci;  
      mci.CallbackRoutine     = (MINIDUMP_CALLBACK_ROUTINE)MiniDumpCallback;  
      mci.CallbackParam       = NULL;  
  
      ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), hFile, MiniDumpNormal, (pep != NULL) ? &mdei : NULL, NULL, &mci);  
  
      CloseHandle(hFile);  
    }  
}  


LONG __stdcall MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)  
{
  CreateMiniDump(pExceptionInfo, "core.dmp");  
  
  return EXCEPTION_EXECUTE_HANDLER;  
}  

 

確保程序開始執行如下代碼,然后程序崩潰時會調用上面代碼創建dump文件:

SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

 

分析生成的dump文件需要如下:

  • 編譯程序時生成的PDB,如果是release版本:
    •   需要禁用優化 - VS - Project Property - C/C++ Optimization - Release - Optimization - Disabled
    •   啟用生成調試信息 - VS - Project Property - Linker - Debugging - Generate Debug Info - Yes.
  • 代碼

 

分析dump文件步驟如下:

  1. 運行Windbg。
  2. 指定PDB文件路徑: File - Symbol File Path。多個路徑用分號分隔。
  3. 指定代碼路徑:File - Source File Path
  4. 載入dump文件。
  5. Windbg命令行輸入:  !analyze -v
  6. 等待結果 - 函數調用堆棧,程序崩潰代碼。busy狀態表示正在生成結果。

 

注釋:

  • 沒有代碼,只有PDB,也可以顯示函數調用堆棧,但是不會定位到具體代碼。
  • Windbg中,配置 Symbol File Path: srv*c:\symbols*http://msdl.microsoft.com/download/symbols,可以解決本地找不到symbol問題。定位一般問題,不是必須。c:\symbols為本地緩存PDB目錄。只會同步用到的symbol。
  • Windbg的附帶工具symchk可以用來下載指定dll的pdb文件:
    • 下載特定dll的pdb文件:symchk /r c:\windows\system32\secur32.dll /s SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols
    • 下載特定目錄下的dll的pdb文件:symchk /r c:\windows\system32 /s SRV*c:\symbols\*http://msdl.microsoft.com/download/symbols
  • 如果dump文件被拷貝到編譯程序的機器上,無需指定代碼路徑,只需指定pdb文件,可自動定位代碼。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM