使用Windbg过程中两个使用细节分享

       我们在使用工具的过程中,一般都会遇到一些使用上的细节或者技巧,今天就来给大家分享一下最近使用Windbg过程中遇到的两个问题,以供参考。

C++软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...) icon-default.png?t=M666https://blog.csdn.net/chenlycly/article/details/125529931

1、Windbg6.0版本好像无法到微软在线pdb服务器上下载pdb文件,而Windbg10.0是可以的

       在某次将Windbg动态附加到目标进程上调试时捕获到了异常,输入kn命令查看函数调用堆栈,中间看到了我们的业务模块,再往上看,看到了系统模块devenum.dll和ntdll.dll模块:

使用Windbg过程中两个使用细节分享_第1张图片

有时为了方便确定问题,我们需要查看这些系统模块调用的具体是哪些接口。

从函数调用堆栈中地址偏移来看,比如devenum!DllRegisterServer+0x437a,首先这个函数DllRegisterServer和当前的函数调用堆栈时不搭噶的,再者当前相对于DllRegisterServer函数接口的偏移地址0x437a太大,一般一个函数内部实现不会如此之长,所以肯定是没有加载pdb,没有函数符号,所以这个地址是相对DllRegisterServer导出函数的偏移。对于dll库,其导出函数的符号,对于外界是可见的。

       同事使用的Windbg6.0的绿色版本,附加到进程上动态调试的,捕获到了异常,中断了下来。但是在Windbg6.0中设置了微软在线pdb下载地址,但是Windbg6.0中好像没法从在线的pdb服务器上下载。即使使用.reload /f devenum.dll命令去强制加载库的pdb文件,也是不行的。

       难道WIndbg6.0无法从微软pdb服务器上下载pdb文件,新版本的WIndbg10.0应该是可以的。
这是动态调试,难道要用windbg10.0重新附加到进程上调试运行,重新复现一下现象?

       其实,是不用这么做的,可以在当前使用的Windbg6.0中直接使用命令:

.dump /ma D:\0805.dmp

导出dump文件,然后再用Windbg10.0打开保存的dump文件,然后将包含在线pdb地址的pdb路径:

C:\Users\Administrator\Desktop\pdbdir;srv*f:\mss0616*http://msdl.microsoft.com/download/symbols

这么个一长串组合路径主要由下面三个路径构成:(路径之间使用分号隔开)

1)应用程序库pdb文件路径(非系统库)

C:\Users\Administrator\Desktop\pdbdir。我们开发的模块的pdb文件集中拷贝到该路径中,路径名称可以随意选择。

2)本地安装的Windows系统库pdb文件路径

f:\mss0616,可以到微软官网上下载和Windows系统一致的系统符号库安装包,这个路径就是本机上安装系统pdb的路径。此时安装的系统pdb库是与我们当前系统对应的pdb,但在分析崩溃时dump文件是在在其他机器上产生的,对应模块的pdb是其他机器上安装系统的pdb,那我们本地安装的pdb就用不上了。现在微软官方已经取消了系统pdb文件的下载,统一使用下面给出的微软提供的在线系统pdb服务器地址。

3)Windows系统库在线下载路径

http://msdl.microsoft.com/download/symbols,这是微软提供的在线系统pdb文件下载服务器,如果设置了该地址,Windbg会自动连接该服务器,去自动下载与当前dump文件中用到的系统库版本一致的pdb文件。但这里需要注意一下,有时微软这个服务器会有连接不上或卡顿的情况,会直接导致windbg卡顿。所以遇到windbg比较安顿的时候,可以先将该地址删除掉。但有时我们需要设置该在线地址,因为有时我们想去看到底是调用了系统库中的那个接口出发的崩溃。 

设置到Windbg中,Windbg10.0中是可以在线下载系统的pdb文件的,然后再查看堆栈就能看到调用系统库的接口了,如下所示:

使用Windbg过程中两个使用细节分享_第2张图片

2、没加载pdb时查看到的函数调用堆栈较少,加载pdb文件后可能能看到的更多的函数调用堆栈

      有时发生异常时,去查看函数的调用堆栈,从调用堆栈中只能看到有限的函数调用,比如只能看到系统库的函数调用,堆栈中看不到具体的业务模块的函数;或者是只能看到很少几行的函数调用。比如:

使用Windbg过程中两个使用细节分享_第3张图片

当前这个异常是Access violation内存访问违例的异常,函数调用堆栈中只有一行记录。 

       一般遇到这种情况,可能是因为没有加载pdb库导致的,当前显示的函数调用堆栈中可能是系统库,也有可能是我们的业务库。对于业务库,我们直接使用lm vm命令去查看器其时间戳,然后到到文件服务器对应的目录中去找对应时间点的pdb文件。

一般在正式的项目中,通过自动化软件编译系统,每天都会自动编译软件版本,并将软件的安装包及相关模块的pdb文件保存到文件服务器中,如下所示:

这样我们就可以根据模块的编译时间找到对应版本的pdb文件了。

       如果函数调用堆栈中显示的模块是系统库,可以设置微软在线pdb服务器下载地址:

C:\Users\Administrator\Desktop\pdbdir;srv*f:\mss0616*http://msdl.microsoft.com/download/symbols

让Windbg到微软官方服务器上去下载,等加载pdb文件后可能能看到更多的函数调用堆栈。类似的情况我们在日常排查问题时多次遇到过。当加载pdb符号库文件后,调用堆栈中就看到更多的函数的调用了。

       对于本节的示例,函数调用堆栈中的模块是业务库模块,直接根据时间戳到文件服务器上找到对应的pdb文件,然后就看到了更详细的函数调用堆栈:

使用Windbg过程中两个使用细节分享_第4张图片

又来详细的函数调用堆栈,可能就能更快地分析出问题了。 

你可能感兴趣的:(C++,Windbg,pdb,函数调用堆栈)