首页
社区
课程
招聘
[求助]软件调试基础--10搞定句柄泄露
发表于: 2016-1-27 15:16 4980

[求助]软件调试基础--10搞定句柄泄露

2016-1-27 15:16
4980

相比内存泄露,句柄泄露的发生情况还算少数,其实句柄也是一个很有限的资源,而且句柄几乎都关联了一段内存,所以大多数情况下,有句柄泄露的地方其实也是有内存泄露的,任务管理器里可以查看到某进程中的句柄数量,如果我们的程序运行过程中,发现句柄数量在稳增不减,那基本上就说明这个程序有句柄泄露了,当程序执行时间足够长,就会导致崩溃,或创建新的句柄失败。本文讲解,如何查找泄露的句柄,在创建这个句柄的时候的调用堆栈,有了调用堆栈,我们就可以找到这个句柄是否有释放过,如果没有,我们就可以在合适的时机对其进行释放了。

原理:思路跟找内存泄露基本一样,也是捕获两个时间点时程序中的句柄,然后对比两个时间点里不同的句柄,并打印出这些句柄的创建时的调用堆栈。

下面以一个最简单的例子,来演示一下。主要代码如下:

void CMFCTestDlg::OnBnClickedOk()

{

// TODO:  在此添加控件通知处理程序代码

HANDLE hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);

}

点击一下按钮的时候,创建了一个事件对象,并且没有CloseHandle。本文实验环境为XP系统,Win7下由于Windbg版本较低,有些内容显示不正常。

Windbg启动调试,并开启句柄监视,其实就是把句柄创建的调用堆栈存储起来,同样是之前讲解的用户态栈回溯数据库。(看吧,很多表面上的问题,其实底层原理都一样的)如下图:



然后创建一个句柄快照,如下图:



继续执行,点击按钮,创建一个Event,然后ctrl + break中断下来,执行对比,如下图:



这里可能显示很多个调用堆栈,但不一定每一个句柄都是泄露,和前面内存泄露一样,两次对比产生的差异未必都是泄露,有一部分系统本身的,只是我们第二个时间点之前还没有释放,而之后是有释放的。

总结:本篇内容比较少,其实就是几个命令而已,很简单,重点是知道原理,windows为我们开发者提供了哪些支持,适当的时候要学会利用这些支持解决问题。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//