2018-01-15  创建人: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);   //调用dll中含有崩溃代码的函数,源码第19行return 0;
}long  __stdcall CrashInfocallback(_EXCEPTION_POINTERS *pexcp)
{//创建 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文件内容::MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),hDumpFile,MiniDumpNormal,&dumpInfo,NULL,NULL);}return 0;
}

三、要点

  1. PE文件中包含了对应的pdb文件的校验码和路径,二者必须和pdb文件保持一致,即:PE文件和pdb文件必须同时生成,pdb文件必须在PE文件中记录的路径下。
  2. pdb文件中记录了源码的位置,若该位置下有源码,则定位时不仅可以定位到行号而且还能显示对应的源码,反之只能显示行号。通常情况下不方便提供源码,故pdb文件必须在所属的PE文件下。

四、定位dll文件中崩溃位置行号步骤

1、修改工程1的pdb文件生成目录,如下所示。
项目 -> 工程名 + 属性,按照下图修改

将“生成程序数据库文件”改为上图所示,意思是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会自动根据信息分析出崩溃的代码行数,部分结果如下:


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
写入空指针,违规访问。
---------------------------------------------------------------
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源码位置。

任务达成!

五、注意事项

  1. exe、pdb和dmp文件保持版本一致。
  2. 在dll工程设置的 pdb生成目录下存在对应的pdb文件。
  3. 源码存在于原来的位置,路径没有改动。

六、分析

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

大家可以发现,虽然WinDbg仍然可以分析出源码异常行号,但是不能再显示出对应的源码。
在源码对应位置显示的内容如下:

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

大家可以发现,WinDbg不能在该路径下发现源码文件,故无法显示对应的异常源码。那么这个源码路径哪来的呢?之前的文章介绍过,这个源码路径就是存储在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

大家可以发现,如果pdb文件不存在的话,WinDbg就无法分析出源码位置了。

七、总结

  1. PE文件中会记录对应的pdb文件路径,pdb文件中会记录源码位置,若三者路径都是正确的,即:都存在,WinDbg不仅可以定位到行号,还可以显示源码。
  2. 若没有源码,则只能定位到行号,不能定位到源码!
  3. 若PE文件中记录的对应的pdb文件路径下没有pdb文件,则WinDbg就连行号也无法定位了,而且结果也是值得商榷了。

八、源码

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

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

  1. VS2010下使用dmp文件和pdb文件定位程序异常代码行号的注意事项

    2018-01-12 创建人:Ruo_Xiao 2018-01-15 修改人:Ruo_Xiao 添加为dump.exe和pdb版本保持一致的原因. 一.minidump文件 崩溃转储是创建一个应用程序 ...

  2. vs2010下使用dmp文件和pdb文件调试时dump、exe和pdb三个文件要保持版本一致的原因

    一.pdb文件简介 英文:Program Data Base,即程序的基本数据,是 VS 编译链接时生成的文件. pdb文件主要存储了如下调试信息: (1)public,private 和 stati ...

  3. vs2010 利用DMP文件、pdb文件查找release下的异常行号的方法

    2018-01-12 创建人:Ruo_Xiao 开发环境:Windows7,VS2010,WinDbg 6.12. 一.源码 #include "stdafx.h" #includ ...

  4. vs2010调试c语言找不到exe文件夹,VS2010,在bin下面的debug文件中没有exe文件,只有dll文件和pdb文件。...

    你是链接的时候出错的,在菜单栏-项目-属性-配置属性-清单工具-输入输出-嵌入清单里面修改一下就好了. s2012运行c语言出现:无法查找或打开 PDB 文件. "ConsoleApplic ...

  5. 将本机文件复制到安装的虚拟机系统中的两种方法

    大家可直接跳到第二种方法,比较简单 第二种方法 一.第一种方法 1.首先打开虚拟机,选择自己安装的操作系统(已经安装的虚拟机系统),鼠标点击一下 2.在展开的操作系统详情页面,选择硬盘,鼠标左键双击 ...

  6. VS2010下ocx开发:(2)在C#程序中调用ocx控件

    在本文中,给出一个C#示例程序,调用上一篇博文中创建的MultiplyDemo.ocx控件.注意需要保证该控件已经注册过. 启动Visual Studio 2010,使用C#创建一个Windows窗体 ...

  7. iis服务器文件上传大小限制,windows服务器中iis限制文件大小方法

    本文章来介绍一下在windows服务器中如何来利用iis限制各个上传文件的大小问题,有需要的同学可以参考一下. 一.上传文件大小限制修改: 1 .运行iisreset –stop,关闭 iis adm ...

  8. python基于django框架下读代码——页面元素和数据元素在代码中的位置查找

    Python+django写的集成版本自动打包发布,用户意见禅道问题收集的项目 本篇的主要目的是: 1.**页面元素查询:**查找网页中"构建"部分代码所在位置 2.**数据信息查 ...

  9. 说说Debug文件夹下的.pdb文件

    .PDB文件,全称为"程序数据库"文件.我们使用它(更确切的说是看到它被应用)大多数场景是调试应用程序.目前我们对.PDB文件的普遍认知是它存储了被编译文件的调试信息,作为符号文件 ...

最新文章

  1. 最新(2019/3)CSDN博客Markdown编辑格式说明,包含效果图
  2. 有关Visual Studio 2008 SP1和SQL Server 2008的一些说明
  3. 1.10a – 如何设计你的第一个程序
  4. 配置https后访问返回403 forbidden
  5. innerHTML与innerText
  6. Spark 编程模型(上)
  7. nodejs里socket.on和socket.once的单步调试
  8. 后台模板 开源_3个开源样板网页设计模板
  9. Spring配置XML本地提示:点击eclipse属性——选择XML Catalog
  10. Django官方中文文档
  11. 迈达斯导出html计算书,MIDAS计算书整理正文..doc
  12. 租用服务器多开虚拟机,云服务器多开虚拟机
  13. 新iPhoneSE定价较低,置国产旗舰手机于尴尬境地!
  14. 手机文件夹为什么是英文?哪些可以删除?看完清理能多出10G内存
  15. 使用starUML一步一步画顺序图
  16. 查询京东快递物流状态,快速筛选出代收的单号
  17. Java验证辛钦大数定理
  18. 2019规划:放下所有,轻松上阵,大胆尝试,勇于实践,经商赚钱,考证提高,随时煅炼
  19. 【历史上的今天】12 月 10 日:世界上第一位程序员诞生;Ada 语言发布;第一人称射击游戏的开拓者
  20. 灰帽编程C++系列——端口扫描

热门文章

  1. mybatis-generator 插件扩展,生成支持多种数据库的分页功能
  2. AngularJS学习笔记
  3. MapReduce:Simplified Data Processing on Large Clusters中文版from百度文库
  4. [linux]在Linux里设置环境变量的方法(export PATH)
  5. android 开机启动服务。
  6. 数据中心的企业正羽科技技术收购虚拟主机VantiCore
  7. sun cluster3.1
  8. 496. 下一个更大元素 I
  9. 解决go项目报错:fatal: could not read Username for ‘https://gitee.com‘: terminal prompts disabled
  10. goland开启go mod管理