日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法

發(fā)布時間:2024/10/14 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
2018-01-15 創(chuàng)建人:Ruo_Xiao 郵箱:xclsoftware@163.com

一、基礎鏈接

http://blog.csdn.net/itworld123/article/details/79041500
http://blog.csdn.net/itworld123/article/details/79047788
http://blog.csdn.net/itworld123/article/details/79061296

二、源碼

1、DLL代碼(工程1)

#pragma once#ifdef __XError_Export__#define __XError_DLL__ _declspec(dllexport) #else#define __XError_DLL__ _declspec(dllimport) #endifclass __XError_DLL__ XError { public:XError(void);~XError(void); public:void ErrorFun(int *p); }; -------------------------------------------------------------- void XError::ErrorFun(int *p) {p[2] = 10; //崩潰位置,源碼中顯示第16行 }

2、測試代碼(工程2)

#include "stdafx.h" #include "source/ErrorDLL/XError.h" #include <windows.h>#include <DbgHelp.h> #pragma comment(lib,"Dbghelp.lib")static long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp);int _tmain(int argc, _TCHAR* argv[]) {::SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)CrashInfocallback);XError X;int *p = NULL;X.ErrorFun(p); //調(diào)用dll中含有崩潰代碼的函數(shù),源碼第19行return 0; }long __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp) {//創(chuàng)建 Dump 文件HANDLE hDumpFile = ::CreateFile(L"MEMORY.DMP",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);if( hDumpFile != INVALID_HANDLE_VALUE){//Dump信息MINIDUMP_EXCEPTION_INFORMATION dumpInfo;dumpInfo.ExceptionPointers = pexcp;dumpInfo.ThreadId = GetCurrentThreadId();dumpInfo.ClientPointers = TRUE;//寫入Dump文件內(nèi)容::MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hDumpFile,MiniDumpNormal,&dumpInfo,NULL,NULL);}return 0; }

三、要點

  • PE文件中包含了對應的pdb文件的校驗碼和路徑,二者必須和pdb文件保持一致,即:PE文件和pdb文件必須同時生成,pdb文件必須在PE文件中記錄的路徑下。
  • pdb文件中記錄了源碼的位置,若該位置下有源碼,則定位時不僅可以定位到行號而且還能顯示對應的源碼,反之只能顯示行號。通常情況下不方便提供源碼,故pdb文件必須在所屬的PE文件下。
  • 四、定位dll文件中崩潰位置行號步驟

    1、修改工程1的pdb文件生成目錄,如下所示。
    項目 -> 工程名 + 屬性,按照下圖修改

    將“生成程序數(shù)據(jù)庫文件”改為上圖所示,意思是dll對應的pdb文件的生成路徑為C盤PDB文件下,名字為工程名.pdb,同時該路徑會被記錄在對應的PE文件中(重要!!!)。
    2、將生成的dll文件copy到exe所在的目錄下,如下所示:

    雙擊exe,因為程序崩潰自動生成了“MEMORY.DMP”文件,如下圖所示:

    3、打開WinDbg軟件,操作步驟如下:
    (1)File -> Image File Path 下圖所示的框:

    選中“Browse…”按鈕,選擇TEST1.exe,如下圖所示:

    (2)File -> Open Crash Dump… 選擇剛才生成的"MEMORY.DMP"文件。
    (3)之后軟件會彈出命令行窗口,如下圖所示:

    在下面命令行那里輸入“!analyze -v”,WinDbg會自動根據(jù)信息分析出崩潰的代碼行數(shù),部分結果如下:

    WRITE_ADDRESS: 00000008 FOLLOWUP_IP: ErrorDLL!XError::ErrorFun+6 [d:\errordll\errordll\xerror.cpp @ 16] 70591036 c740080a000000 mov dword ptr [eax+8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 00001dacBUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 01201054 to 70591036STACK_TEXT: 0038fab8 01201054 00000000 4546f4ea 01203018 ErrorDLL!XError::ErrorFun+0x6 [d:\errordll\errordll\xerror.cpp @ 16] WARNING: Stack unwind information not available. Following frames may be wrong. 0038fae0 01201268 00000001 00601ba8 00604150 TEST1+0x1054 0038fb24 74a2336a 7efde000 0038fb70 77039902 TEST1+0x1268 0038fb30 77039902 7efde000 7733d33e 00000000 kernel32!BaseThreadInitThunk+0x12 0038fb70 770398d5 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x63 0038fb88 00000000 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbFAULTING_SOURCE_CODE: 12: }13: 14: void XError::ErrorFun(int *p)15: { > 16: p[2] = 10;17: }SYMBOL_STACK_INDEX: 0SYMBOL_NAME: errordll!XError::ErrorFun+6FOLLOWUP_NAME: MachineOwnerIMAGE_NAME: ErrorDLL.dllBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_ErrorDLL.dll!XError::ErrorFunWATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/TEST1_exe/0_0_0_0/5a5c1877/ErrorDLL_dll/0_0_0_0/5a5d4b1a/c0000005/00001036.htm?Retriage=1 WRITE_ADDRESS: 00000008 寫入空指針,違規(guī)訪問。 --------------------------------------------------------------- XError::ErrorFun+0x6 [d:\errordll\errordll\xerror.cpp @ 16] dll源碼中第16行異常。 --------------------------------------------------------------- STACK_COMMAND: ~0s; .ecxr ; kb FAULTING_SOURCE_CODE: 12: }13: 14: void XError::ErrorFun(int *p)15: { > 16: p[2] = 10;17: } WinDbg定位到了dll源碼位置。

    任務達成!

    五、注意事項

  • exe、pdb和dmp文件保持版本一致。
  • 在dll工程設置的 pdb生成目錄下存在對應的pdb文件。
  • 源碼存在于原來的位置,路徑?jīng)]有改動。
  • 六、分析

    1、若源碼位置改動,我這里把路徑下的工程名改為“ErrorDLL00”,WinDbg的部分分析結果如下:

    WRITE_ADDRESS: 00000008 FOLLOWUP_IP: ErrorDLL!XError::ErrorFun+6 [d:\errordll\errordll\xerror.cpp @ 16] 70591036 c740080a000000 mov dword ptr [eax+8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 00001dacBUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 01201054 to 70591036STACK_TEXT: 0038fab8 01201054 00000000 4546f4ea 01203018 ErrorDLL!XError::ErrorFun+0x6 [d:\errordll\errordll\xerror.cpp @ 16] WARNING: Stack unwind information not available. Following frames may be wrong. 0038fae0 01201268 00000001 00601ba8 00604150 TEST1+0x1054 0038fb24 74a2336a 7efde000 0038fb70 77039902 TEST1+0x1268 0038fb30 77039902 7efde000 7733d33e 00000000 kernel32!BaseThreadInitThunk+0x12 0038fb70 770398d5 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x63 0038fb88 00000000 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbFAULTING_SOURCE_CODE: No source found for 'd:\errordll\errordll\xerror.cpp'SYMBOL_STACK_INDEX: 0SYMBOL_NAME: errordll!XError::ErrorFun+6FOLLOWUP_NAME: MachineOwnerIMAGE_NAME: ErrorDLL.dllBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_ErrorDLL.dll!XError::ErrorFunWATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/TEST1_exe/0_0_0_0/5a5c1877/ErrorDLL_dll/0_0_0_0/5a5d4b1a/c0000005/00001036.htm?Retriage=1

    大家可以發(fā)現(xiàn),雖然WinDbg仍然可以分析出源碼異常行號,但是不能再顯示出對應的源碼。
    在源碼對應位置顯示的內(nèi)容如下:

    FAULTING_SOURCE_CODE: No source found for 'd:\errordll\errordll\xerror.cpp'

    大家可以發(fā)現(xiàn),WinDbg不能在該路徑下發(fā)現(xiàn)源碼文件,故無法顯示對應的異常源碼。那么這個源碼路徑哪來的呢?之前的文章介紹過,這個源碼路徑就是存儲在ErrorDLL.dll指定的ErrorDLL.pdb中。
    2、若源碼位置沒有改動,我將ErrorDLL工程中pdb文件生成目錄下的pdb文件刪除,部分結果如下:

    WRITE_ADDRESS: 00000008 FOLLOWUP_IP: ErrorDLL!XError::ErrorFun+6 70591036 c740080a000000 mov dword ptr [eax+8],0AhMOD_LIST: <ANALYSIS/>FAULTING_THREAD: 00001dacBUGCHECK_STR: APPLICATION_FAULT_NULL_CLASS_PTR_DEREFERENCE_INVALID_POINTER_WRITE_WRONG_SYMBOLSPRIMARY_PROBLEM_CLASS: NULL_CLASS_PTR_DEREFERENCEDEFAULT_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCELAST_CONTROL_TRANSFER: from 01201054 to 70591036STACK_TEXT: WARNING: Stack unwind information not available. Following frames may be wrong. 0038fab8 01201054 00000000 4546f4ea 01203018 ErrorDLL!XError::ErrorFun+0x6 0038fae0 01201268 00000001 00601ba8 00604150 TEST1+0x1054 0038fb24 74a2336a 7efde000 0038fb70 77039902 TEST1+0x1268 0038fb30 77039902 7efde000 7733d33e 00000000 kernel32!BaseThreadInitThunk+0x12 0038fb70 770398d5 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x63 0038fb88 00000000 01201389 7efde000 00000000 ntdll!RtlInitializeExceptionChain+0x36STACK_COMMAND: ~0s; .ecxr ; kbSYMBOL_STACK_INDEX: 0SYMBOL_NAME: errordll!XError::ErrorFun+6FOLLOWUP_NAME: MachineOwnerIMAGE_NAME: ErrorDLL.dllBUCKET_ID: WRONG_SYMBOLSFAILURE_BUCKET_ID: NULL_CLASS_PTR_DEREFERENCE_c0000005_ErrorDLL.dll!XError::ErrorFunWATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/TEST1_exe/0_0_0_0/5a5c1877/ErrorDLL_dll/0_0_0_0/5a5d4b1a/c0000005/00001036.htm?Retriage=1Followup: MachineOwner

    大家可以發(fā)現(xiàn),如果pdb文件不存在的話,WinDbg就無法分析出源碼位置了。

    七、總結

  • PE文件中會記錄對應的pdb文件路徑,pdb文件中會記錄源碼位置,若三者路徑都是正確的,即:都存在,WinDbg不僅可以定位到行號,還可以顯示源碼。
  • 若沒有源碼,則只能定位到行號,不能定位到源碼!
  • 若PE文件中記錄的對應的pdb文件路徑下沒有pdb文件,則WinDbg就連行號也無法定位了,而且結果也是值得商榷了。
  • 八、源碼

    http://download.csdn.net/download/itworld123/10207344

    總結

    以上是生活随笔為你收集整理的VS2010下使用dmp文件和pdb文件定位到dll中崩溃位置的方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。