今天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

FeedBack:
# re: 用Windbg解决一个Bug
2012-06-27 13:06 | zgpxgame
mark  回复  更多评论
  
# re: 用Windbg解决一个Bug
2012-07-01 00:40 | 朱峰everettjf
这得需要专业的测试人员了。

最近遇到个类似的默认路径被改变的问题。CFileDialog。  回复  更多评论
  
# re: 用Windbg解决一个Bug
2012-07-08 02:16 | weolar
其实vs这些功能都.调试的时候,在"debug"里调出commandline窗口,就能下这些命令了.只是windbg比vs多了些扩展命令.  回复  更多评论
  
# re: 用Windbg解决一个Bug
2012-07-08 10:08 | Richard Wei
@weolar
是的, 理论上Vc和Windbg用的是相同的的调试引擎,但是我试了些VC的command,设置断点的bp和察看堆栈的kv都不支持,不知道怎么回事。
另外windbg本身很小,在QA机器上安装也很方便。  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理