前言
windbg是非常强大的调试工具,具体怎么使用,网上已经有很多的教程了,这里就不复述了。
今天遇到一个崩溃,对于我来说,还是一个新的崩溃,没有这么调试过。所以这里记下来,以便后续回顾。
配置
首先,将pdb文件以及源码在windbg中配置好,同时将截取的dmp文件加载到windbg中。
64位与32位切换
现在越来越多的电脑使用64位的操作系统,但是大多数的软件还是32位的,64位系统使用wow64来帮助运行32位程序。如果一个64位系统上的32位程序崩溃了,得到的dump在不经过转换的情况下,用windbg也看不见有用的信息。
- 用windbg加载dmp,并配好pdb以及源码
- 使用
.load wow64exts加载wow64exts模块,将64位dump转换成32位的dump - 输入
!sw进行转换,命令执行完后提示Switched to 32bit mode - 最后就可以分析这个dump了
调试
当然了,可以使用自动分析的命令开始分析!analyze -v,结果如下图所示:
这里我经过仔细分析,这里应该不会出问题的。其次,我们来仔细看下这个线程的堆栈信息,如下图所示:
我们可看出,没有可能导致线程崩溃的地方,分析发现这个线程就是一直在等待,并没有发现崩溃的地方。所以,我在这里浪费了很多时间。我们再看其他线程的堆栈,如下图所示:
在上图中,其他线程中并没有发现我自己写的代码,所以当时就认定出错的线程一定是第一个线程的堆栈。泪流满面,仔细分析得出第一个线程不可能出错,再次仔细看看4号线程的堆栈,其中有个API UnhandledExceptionFilter,这个API明显就是和异常有关。下面看下这个API的参数:
再看下该参数中结构体的定义:
参数一是EXCEPTION_RECORD结构体的指针,注意第二个参数是异常上下文信息CONTEXT的指针。
所以我们在windbg中切换到4号线程中~4s,使用kb查看相关API的参数,如下图所示
然后使用dd 0414f1dc查看UnhandledExceptionFilter结构体参数的内存,如下图所示,红色标记为结构体中第一个参数地址,蓝色标记的是结构体中第二个参数,也就是异常上下文信息。
这里因为我们要找到异常的上下文信息,也就是出错时线程的堆栈信息,所以我们接着进入到异常上下文中。这里使用.exr 记录地址显示一个异常记录的详细内容,这里的命令为.exr 0414f36c,结果如下图所示(字段含义,自己可以查查):
使用cxr 0414f36c查看出错上下文信息,命令执行完后就可以直接看到出错的位置了,如下图所示:
最后可以使用命令k、dv等查看,或者View-Local,查看局部变量,会发现fileItem指针为空,这里我们就发现了出错的原因了,也找到了出错的真正的线程上下文了,如下图所示:
总结
- 正在被分析的线程,如果没有发现出错的地方,同时,也没有发现和异常相关的API时,需要仔细分析其他线程
- 注意UnhandledExceptionFilter API,清楚该API的参数以及其结构
如果需要此文分析的dmp以及pdb文件,请留言,我会及时回复的。
整理的比较辛苦,如果本文对你有用,请留下你来过的痕迹,转载请注明出处! 2016年8月15号于北京 https://soygrow.github.io