今天QA发现在他一台机器上启动我们的软件的时会提示某个DLL(a.dll)找不到(a.dll是b.dll内部用到的一个DLL, 我们软件直接用的是b.dll)。
刚开始我们怀疑是不是a.dll没有下载下来或是没有下载完整,但是到安装目录下看了,a.dll在那边,用dependency看了下,DLL的导出函数也都是正常的。既然DLL本身没有问题,那就是搜索路径的问题了,可以修改的搜索路径一般包括当前路径(current directory)和DLL路径(dll directory), 正好我们这2项在我们的Trace中都有记录。通过查看Trace,发现dll directory在后面确实被修改成了我们另外一个软件的路径。
那么究竟是谁改了这个路径? 这就需要借助Windbg了。我们知道修改DLL路径的API是SetDllDirectory,所以我们可以通过设置API断点,然后查看堆栈就可以了。因为我们这个程序这里是由其他程序调用启动的,所以我们可以通过子进程的方式来调试。
在QA的机器上安装windbg, 首先将Windbg Attach到父进程,输入命令 .childdbg 1, 表示允许调试子进程,然后F5,继续运行。接下来触发父进程创建子进程的动作,我们可以看到Windbg会中断下来, 我们可以通过命令|. 查看是不是我们的目标进程建立起来了,接下来输入断点命令bp Kernel32!SetDllDirectoryA 和 bp Kernel32!SetDllDirectoryW, 然后F5运行。果然很快Windbg又被中断下来了,通过命令kv查看堆栈,我们可以看到果然有人调用SetDllDirectoryA,原来是我们的底层通讯模块触发的, 另外我们可以通过da poi(esp+4)查看SetDllDirectory传入路径的值。
那么是不是只要我们把DLL路径改回原来的NULL,就不会有这个Bug了呢?我们可以在调用SetDllDirectory中断时,直接输入ed esp+4 0修改传入参数成0,然后F5运行,果然后面dll的加载就都正常了。
找到原因后,接下来就是让QA给对应的模块开发人员报Bug,让他们把DLL路径用完后改回来。
可以看到无论对于开发还是测试人员,windbg很多时候可以帮我们快速的定位问题, 如果借助符号文件,Windbg完全可以实现比VC IDE更强大的调试供功能, 并且有时候我们不需要源代码,不需要重新编译,直接就可以通过windbg调试和解决问题。
posted on 2012-06-26 20:33
Richard Wei 阅读(3636)
评论(3) 编辑 收藏 引用 所属分类:
windbg