SleuthQA CodeWatch 跟踪程序资源泄漏
2009-12-29 14:27
337 查看
某日,一个我编写的Delphi 应用(dll 插件)被发现运行一段时间后,系统的PF 占用其高且下不来。
后在任务管理器中发现此应用所在的exe 在运行期间的句柄计数会稳定累积增加, user对象、GDI对象计数未发现明显异常。
使用SleuthQA CodeWatch( 以下简称 CW) 调试此dll, 过程如下:
Step1. 准备工作
1.1 CW-File-NewProject,选择要分析的模块,即本应用的dll
1.2 选择模块对应的Host EXE
Step 2 运行应用,采集信息
1.3 CW 主界面,点击执行程序,正常进行操作,CW自动采集EXE执行期间的event。
Step 3 结束exe, 查看采集的信息
3.1 正常退出exe,CW弹出初步结果, 这里可以看到在刚才的运行期间中该DLL发生了3次未预计的操作系统资源泄漏 、1次捕获的内存泄漏
3.2 这里可以看到3次的资源泄漏其实是-1个window未关闭、1个process handle、1个ThreadHandle未关闭。窗口泄漏的根源发现是在某个单元中创建TTimer未释放,VCL的TTimer其实就是开个窗口接收WM_TIMER,暂且不表。
3.3 泄漏时的线程栈表明发生在 uExtractor1.pas 181行处,代码片断如下。 此处创建了一个额外的工作exe,如果该工作exe在规定时间内正常退出则会关闭该工作exe的进程、线程句柄;但是如果超时了,会调用另一个公共函数 KillProc 杀掉该exe及其子孙进程,这里范了错误,在杀掉后没有关闭该exe的句柄。
3.4 修改代码即使KillProc 也要关闭 hProcess hThread。 OK! 泄漏问题解决
总结:
1. Dll 的代码一定要谨慎编写,因为申请的系统资源都是隶属于主调exe的,主调exe不退出,中间泄漏的资源操作系统都没办法帮你自动回收;
2. CreateProcess后打开的进程句柄一定要释放,即使该程序被另外的地方杀掉了,因为只要一处打开的句柄不关闭,操作系统为该进程维护的内核对象的句柄计数都不会减到0,导致泄漏
后在任务管理器中发现此应用所在的exe 在运行期间的句柄计数会稳定累积增加, user对象、GDI对象计数未发现明显异常。
使用SleuthQA CodeWatch( 以下简称 CW) 调试此dll, 过程如下:
Step1. 准备工作
1.1 CW-File-NewProject,选择要分析的模块,即本应用的dll
1.2 选择模块对应的Host EXE
Step 2 运行应用,采集信息
1.3 CW 主界面,点击执行程序,正常进行操作,CW自动采集EXE执行期间的event。
Step 3 结束exe, 查看采集的信息
3.1 正常退出exe,CW弹出初步结果, 这里可以看到在刚才的运行期间中该DLL发生了3次未预计的操作系统资源泄漏 、1次捕获的内存泄漏
3.2 这里可以看到3次的资源泄漏其实是-1个window未关闭、1个process handle、1个ThreadHandle未关闭。窗口泄漏的根源发现是在某个单元中创建TTimer未释放,VCL的TTimer其实就是开个窗口接收WM_TIMER,暂且不表。
3.3 泄漏时的线程栈表明发生在 uExtractor1.pas 181行处,代码片断如下。 此处创建了一个额外的工作exe,如果该工作exe在规定时间内正常退出则会关闭该工作exe的进程、线程句柄;但是如果超时了,会调用另一个公共函数 KillProc 杀掉该exe及其子孙进程,这里范了错误,在杀掉后没有关闭该exe的句柄。
bCreateProcess := CreateProcess(nil, PChar(sCommand), nil, nil, True, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, lpStartupInfo, lpProcessInformation); if bCreateProcess then begin case WaitForSingleObject(lpProcessInformation.hProcess, WaitForSec * 1000) of WAIT_TIMEOUT: begin Result:= 4; KillProc(lpProcessInformation.dwProcessId, True, Result); end; WAIT_OBJECT_0: begin GetExitCodeProcess(lpProcessInformation.hProcess, ResultCode); CloseHandle(lpProcessInformation.hProcess); CloseHandle(lpProcessInformation.hThread); Result := ResultCode; end; end; end else Result := 9;
3.4 修改代码即使KillProc 也要关闭 hProcess hThread。 OK! 泄漏问题解决
总结:
1. Dll 的代码一定要谨慎编写,因为申请的系统资源都是隶属于主调exe的,主调exe不退出,中间泄漏的资源操作系统都没办法帮你自动回收;
2. CreateProcess后打开的进程句柄一定要释放,即使该程序被另外的地方杀掉了,因为只要一处打开的句柄不关闭,操作系统为该进程维护的内核对象的句柄计数都不会减到0,导致泄漏
相关文章推荐
- GDI资源泄漏导致的程序异常的解析
- Winxp+SP2对MDI程序存在GDI资源泄漏
- 用Windbg调试.NET程序的资源泄漏
- 用Windbg调试.NET程序的资源泄漏
- 一个GDI资源泄漏检测程序
- 编写高质量代码改善C#程序的157个建议——建议69:应使用finally避免资源泄漏
- 程序中GDI资源占用与泄漏的初步分析
- 如何让浏览器调用你的程序来打开资源
- 关于应用程序出现窗口不完整,GDI对象猛增,GDI资源泄漏的问题的探讨
- 如何用CodeBlocks分多个文件编写一个C++程序
- windows 2012(64位) IIS配置asp程序 500 - 内部服务器错误。您查找的资源存在问题,因而无法显示。
- ulimit命令_Linux ulimit 命令用法详解:控制shell程序的资源
- 遇到问题--Nginx---tomcat启动web程序访问静态资源时404找不到
- 利用__FILE__, __LINE__, __FUNCTION__跟踪调试程序
- 《Boost程序完全开发》跟踪学习训练一:Boost::date_time库的使用
- 关于“此程序集中已使用了资源标识符 "Test.Searchn.resources”问题的解决办法
- 来自OpenCV安装目录下Samples文件夹中的官方示例程序-彩色目标跟踪操作
- libgdx示例-SuperJumper分析 1. 程序入口与初始化资源,加载配置信息
- win32汇编 CreateDC GetDC CreatePen CreateSolidBrush 与GDI资源泄漏
- Code Fragment-当前程序结束的时候,做一些清理的操作。