做为程序员,开发程序是基本功,而调试程序也是必不可少的技能之一。软件在主体功能开发完成后会经历各个阶段的测试,才会被发布。在测试过程当中,出现较多的可能就是内存泄漏,句柄泄漏,异常崩溃等属于非功能型的软件Bug。而Windows做为一个至关成熟的平台,对于软件的调试也支持很到位。今天想要记录的是此次调查的一个模块的句柄泄漏问题。程序员
关于句柄泄漏的文章网上不少,不少关于调试的书籍中也有说明,并且有些也比较详细。以前也解决过这类的问题,因此绝不在乎。先介绍一下基本状况:工做机是Windows 7 64bit 专业版SP1,Windbg使用的是32bit的版本,出问题模块是32bit,依赖也多个外部模块,均为32bit,且自身包含了dbghelp.dll(后面介绍为何单独说这个)。函数
照着Bug的描述,开始操做前搞上Windgb,设置好pdb,!htrace开启。操做了一番,在任务管理器中,发现被调试模块的句柄数蹭蹭蹭往上涨,中止操做后也没见有回落的迹象。见此情形,只好断入Windbg看看状况,看到!htrace -diff输入后显示的结果立马傻眼了。全都是虚地址,没有任何堆栈信息,立马想到是否是pdb不对,lmvm一看,显示正确。可是k显示的堆栈确实是有被调试模块的堆栈。一时想不到问题出在哪,那么就本身写个demo,看下是否是同样,写完demo挂上windbg,状况竟然同样!这是感受就有点诡异,问题应该不是出在被调试程序上,就度娘了一把,无任何发现。却是在高端调试网站上有人发了个帖子,情况和我同样,可是没人回答怎么解决,无果。翻阅书籍,看到的都是千篇一概的,对于上述碰到的问题,无任何说起,无果。偶然在网上找到个工具http://pan.baidu.com/s/1jGIopqm,能够检测内存泄漏、句柄泄漏。将上面写的demo用上后,确实如实反映出了事件的泄漏点,感受不错。而后就把出问题的模块用上。Inject的时候爆出一个错误,说被调试进程已经加载过dbghelp.dll。也就是上面特别说起的那点,无果。工具
想来想去,后来干脆就上了个64bit的Windbg,在调试32bit的demo时,!htrace -diff竟然显示了几行堆栈,切换到x86模式下显示,确实显示了CreateEvent字眼,瞬间好像明白了什么。把demo编译条件切换到64bit,用64bit windbg再试,堆栈所有显示。而后就将泄漏的模块装在32bit机子上,用32bit windbg一看。未关闭句柄的堆栈全有了。至此水落石出。测试
为何在64bit机器上,32bit的windbg调试32bit的进程,通常的函数调用,都可以显示堆栈,而对于差别的句柄堆栈,却不显示,没有答案。通过这一次发现,只关注问题的自己很重要,但有时每每会被一切外部的因素干扰到咱们对事物的判断,这时候就应该站在一个高的高度,看待这问题,那么一切都明了了。网站