本文转载于:http://blog.csdn.net/xdkui/archive/2008/12/19/3560143.aspx
最近在论坛里看到很多人问怎样检查内存泄漏,对于Windows CE/Windows Mobile开发,微软已经为我们提供了很好的工具Application Verifier。AppVerifier是一个辅助开发工具,不用修改代码,可以检测出程序内存,句柄, GDI对象泄漏,并报告分配泄漏对象的调用栈,有过在大规模代码里查资源泄漏的兄弟应该知道这个调用栈的价值。
在中文google里搜了下,没有发现讲这个工具使用的文章,我就写个简单的使用说明,让大家知道并利用好这个工具吧。在MSDN里有很多关于AppVerifier的资料,有兴趣可以直接去http://msdn.microsoft.com搜。后面我附上几个不错的链接。注意:
1. AppVerifier的原理是hook分配和释放资源的API,在程序调用这些API时记录信息,在程序退出时报告出未释放的资源。
2. 只能检测Native代码。
3. 程序正常退出才行,强行杀进程不能得到正确的报告。
4. 基于原理,只能做Run-time检测。尽量使用程序的所有功能已保证检测到更多代码。
测试代码
void LeakMemory()
{
BYTE* p = new BYTE[10];
NKDbgPrintfW(L"Allocated memory: 0x%X", p);
}
void LeakHandle()
{
HANDLE h = CreateEvent(NULL, FALSE, FALSE, L"leaked_event");
NKDbgPrintfW(L"Created event: 0x%X", h);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
LeakMemory();
LeakHandle();
return 0;
}
很简单,泄漏一点内存和一个Event句柄。编译该代码生成Leak.exe/Leak.pdb/Leak.map,AppVerifier使用MAP文件查找调用栈的函数符号。下面我会分别说在Windows CE和Windows Mobile下的使用。
Windows CE
我是基于Windows CE 6测试的。PB6已经集成到Vistual Studio里了。
1. PB自带了AppVerifier, 拷贝D:/Program Files/Microsoft Platform Builder/6.00/cepb/wcetk/ddtk/armv4i目录下的下面这些与AppVerifier相关的文件到Release或者设备的/Windows目录。
appverif.exe
htracker.dll
shimexp.exe
shim_heap.dll
shim_hleak.dll
shim_usergdi.dll
shim_verifier.dll
shimeng.dll
vlog.dll
symhlp.dll
在D:/Program Files/Microsoft Platform Builder/6.00/cepb/wcetk/ddtk目录下有desktop/x86/armv4i等子目录。Desktop目录下的文件是运行在desktop版Windows里(2000/XP/Vista)的,需要通过ActiveSync或者KITL等连接到Device上。别的目录是运行在相应平台的Device上的。后面Windows Mobile里AppVerifier的目录结构一样。
上面的appverif.exe是AppVerifier在Device上运行的程序,带UI,也支持命令行参数,在PB的Target Control里输入s appverif –h即可看到帮助。
Ø 为了简单,我拷贝了这个目录下所有文件到Release目录:
在PB里打开Build Window,然后
D:/WINCE600>copy "D:/Program Files/Microsoft Platform Builder/6.00/cepb/wcetk/ddtk/armv4i/*" %_FLATRELEASEDIR%
Ø 也可以使用Remote File Viewer把这些AppVerifier相关的文件拷贝的/Windows目录。
2. 拷贝待测试程序和MAP文件到Release或者Device的Windows目录,也就是Leak.exe/Leak.map。
3. 运行D:/Program Files/Microsoft Platform Builder/6.00/cepb/wcetk/ddtk/desktop/AppVerifCE.exe (PB的安装目录下)
4. 选择Add…,输入待检测的exe文件名Leak.exe,不用全路径,并选中右边Test settings里要测试的项目,一般全选
5. 选择Connect…
6. 选择Connect…
这里选要连接的Device,我这里选Default Device,属性如下,运行在Device Emulator里带KITL的image。
7. 连接成功以后运行Leak.exe,在PB的Target Control里输入s Leak.exe。可以看到Output窗口里有如下输出:
1532862 PID:206001e TID:207001e Allocated memory: 0x2C022DD0 //这两行是程序输出的
1532878 PID:206001e TID:207001e Created event: 0x521603
1532985 PID:206001e TID:207001e Application verifier core unloaded from: leak.exe - 11:39:44 PM
1533001 PID:206001e TID:207001e DLL_PROCESS_DETACH: Shim_heap checking for abandoned heaps/allocations...
1533094 PID:206001e TID:207001e Heap statistics for heap 0x2c020010:
1533108 PID:206001e TID:207001e Initial size: 0, Maximum size: 0
1533122 PID:206001e TID:207001e Current bytes: 10, Max: 10
1533136 PID:206001e TID:207001e Current count: 1, Max: 1
1533150 PID:206001e TID:207001e Free list bytes: 0
1533164 PID:206001e TID:207001e Free list size: 0
1533183 PID:206001e TID:207001e Checking for un-freed items in heap 0x2c020010...
1533244 PID:206001e TID:207001e ----------------------------------------
1533260 PID:206001e TID:207001e TrackedItem count: 1
1533273 PID:206001e TID:207001e Callstack:
1533368 PID:206001e TID:207001e Console NOT redirected for process 0x206001E
1533506 PID:400002 TID:207001e RELFSD: Opening file shim_heap.map from desktop
1535138 PID:206001e TID:207001e 0x41e98310: shim_heap.dll!APIHook_HeapAlloc + 5d0h
1535220 PID:206001e TID:207001e 0x41e9b378: shim_heap.dll!APIHook_LocalAlloc + a8h
1535303 PID:206001e TID:207001e 0x41e9c2f4: shim_heap.dll!APIHook_malloc + 18h
1535392 PID:206001e TID:207001e 0x41e9c54c: shim_heap.dll!APIHook_new + 14h
1535596 PID:400002 TID:207001e RELFSD: Opening file leak.map from desktop
1535746 PID:206001e TID:207001e 0x000110e0: leak.exe!?LeakMemory@@YAXXZ + ch //这是内存泄漏的调用栈
1535892 PID:206001e TID:207001e 0x0001116c: leak.exe!WinMain + 10h
1536088 PID:206001e TID:207001e 0x00011208: leak.exe!WinMainCRTStartupHelper + 28h
1536210 PID:206001e TID:207001e 0x000111cc: leak.exe!WinMainCRTStartup + 20h
1536341 PID:400002 TID:207001e RELFSD: Opening file coredll.map from desktop
1546679 PID:206001e TID:207001e 0x40071f5c: coredll.dll!MainThreadBaseFunc + 2a0h
1546768 PID:206001e TID:207001e Un-freed items:
1546854 PID:206001e TID:207001e 0x2c022dd0 10 bytes, process: 0x0206001e, thread://泄漏的内存地址和大小,可以看出和程序里的一致
0x0207001e, PerfCount: 1021127120
1546941 PID:206001e TID:207001e Total: 10 bytes
1547026 PID:206001e TID:207001e Checking for leaks in marshall helper api's...
1547043 PID:206001e TID:207001e ------------------------------------------------------------------------
1547045 PID:206001e TID:207001e Shim HLeak detaching from process /Release/leak.exe
1547046 PID:206001e TID:207001e Num of un-freed handles = 1
1547046 PID:206001e TID:207001e Check log file for details
1547046 PID:206001e TID:207001e ------------------------------------------------------------------------
1547047 PID:206001e TID:207001e ----------------------
1547256 PID:206001e TID:207001e EVENT Handle = 0x00521603 Name: 'leaked_event' PerfCount: 1021895588 //泄漏的句柄,可以看出何程序里是一样的
1547338 PID:206001e TID:207001e Callstack:
1547430 PID:400002 TID:207001e RELFSD: Opening file shim_hleak.map from desktop
1548302 PID:206001e TID:207001e 0x41e84814: shim_hleak.dll!My_TrackerInsertItem2 + e0h
1548409 PID:206001e TID:207001e 0x41e84710: shim_hleak.dll!My_TrackerInsertItem + 24h
1548486 PID:206001e TID:207001e 0x41e84c00: shim_hleak.dll!APIHook_CreateEventW + 68h
1548653 PID:206001e TID:207001e 0x0001112c: leak.exe!?LeakHandle@@YAXXZ + 18h //泄漏句柄的调用栈
1548819 PID:206001e TID:207001e 0x00011170: leak.exe!WinMain + 14h
1548979 PID:206001e TID:207001e 0x00011208: leak.exe!WinMainCRTStartupHelper + 28h
1549136 PID:206001e TID:207001e 0x000111cc: leak.exe!WinMainCRTStartup + 20h
1549219 PID:206001e TID:207001e 0x40071f5c: coredll.dll!MainThreadBaseFunc + 2a0h
1549240 PID:206001e TID:207001e DLL_PROCESS_DETACH: Shim_usergdi checking for abandoned resources...
1549340 PID:206001e TID:207001e --------------------------------------------------------------------------------
1549355 PID:206001e TID:207001e VLOG exiting - check for verifier logs (22 info, 5 warnings, 0 errors)
1549368 PID:206001e TID:207001e Process log: /release/AppVerifier_leak_2339.log //这是日志文件,文本格式,可以直接打开看
1549381 PID:206001e TID:207001e --------------------------------------------------------------------------------
对于日志文件,也可以在图1的界面里选择Get Logs…保存日志到本地,然后选择View Exported Log…看,如本测试的日志文件
Windows Mobile
1. 去下面地址下载安装。虽然写的是for Windows Mobile 5,但也适用于Windows Mobile 6。
http://www.microsoft.com/downloads/details.aspx?FamilyID=d275348a-d937-4d88-ae25-28702c78748d&DisplayLang=en
注意Instructions节里的:
For systems that have never installed Platform Builder, complete the following additional steps:
1. Install the Windows CE 5.0 Stand Alone CETK (this provides connection libraries needed).
2. Replace the Application verifier binaries in the processor folder for the device type. For example, replace C:/Program Files/Windows CE platform builder/5.00/CEPB/wcetk/DDTK/ARMV4I with C:/Program Files/Application Verifier for Mobile 5.0/Armv4i.
当你需要在Desktop上运行AppVerifier然后连接Device(像我在演示Windows CE里做的)时需要做这两步。我下面将演示直接在Device上运行,所以不用这两步。
2. 启动Mobile设备,我这里用的Device Emulator
3. 拷贝D:/Program Files/Application Verifier for Mobile 5.0/Armv4i目录下的与AppVerifier相关的文件到Device Emulator里的Windows目录。
4. 拷贝待测试程序和MAP文件到Device,也就是Leak.exe/Leak.map,其中Leak.map得拷贝到/Windows目录,不然生成的日志里看不到函数符号。生成MAP文件需要修改工程属性如下,改Generate Map File为Yes。
5. 在Device Emulator里运行/Windows/AppVerif.exe,选择Add…添加Leak.exe并选择Test settings。
6. 在Device上运行Leak.exe,会在Device的根目录生成日志文件,比如/ AppVerifier_Leak_1643.log。直接用记事本打开就可以看到日志,或者运行D:/Program Files/Application Verifier for Mobile 5.0/Desktop/ AppVerifCE.exe,然后选择View Exported Log…看。
7. 发现有时候打开log,里面的符号不能被正确解析。解决方法:
1) 打开log文件, 把类似下面callstack里不正确解析的符号
| shim_heap.dll 30 | 0 nk.exe 8803754c' 0x1c04eac4: !(null) + 4eac4h
| shim_heap.dll 30 | 0 nk.exe 8803754c' 0x1c04b2f0: !(null) + 4b2f0h
| shim_heap.dll 30 | 0 nk.exe 8803754c' 0x1c04bad4: !(null) + 4bad4h
| shim_heap.dll 30 | 0 nk.exe 8803754c' 0x1c0530f0: !(null) + 530f0h
都改为:
| shim_heap.dll 30 | 0 nk.exe 8803754c' 0x1c04eac4: leak.exe!(null) + 4eac4h
然后像第6步里一样打开log,会提示map文件的位置,选择即可。
2) 手动在map文件里找地址。比如上面的!(null) + 4eac4h, 在map文件的第3列,也就是Rva+Base,里找第一个比4eac4h小的地址就是了。
Windows Desktop(2000/XP/Vista…)
AppVerifier也有Windows desktop上的版本,可惜不支持Memory Leak等检测,但说明说可以检测double free。不知道有什么好的检测资源泄漏的方案?听过BoundsChecker,Rational Purify。了解的朋友请告诉我下。
之外,可以修改代码使用C Run-time库提供的些函数辅助检查。Debug版本下,在程序退出前加_CrtDumpMemoryLeaks,可以打出泄漏内存的内容,不过没有调用栈,比如:
Detected memory leaks!
Dumping objects ->
{110} normal block at 0x00917D88, 4 bytes long. //110是内存分配的ID
Data: < > 01 00 00 00 //这是泄漏的内容, 可以根据大小和内容大概猜是什么东西
Object dump complete.
每个内存分配有个ID,比如上面110, 然后在程序入口处_CrtSetBreakAlloc(110),再重新开始debug,下次分配这个对象时就会断下来,你就可以看到调用栈了。如果每次分配内存的顺序是一样的,ID在多次运行程序会一样,这种方法不错,但在多线程环境下有局限。这种方法类似于ATL的QIThunk,见ATL Internals: Working with ATL 8, Second Edition第4章的Debugging节。
附录
1. Application Verifier for Windows CE and Windows Mobile 5.0
http://msdn.microsoft.com/en-us/library/aa446904.aspx
2. 视频教材 Using AppVerifier to debug Windows Mobile Applications
http://download.microsoft.com/download/0/9/f/09fb0ed3-cc89-4f94-a022-c362902f50a2/UsingAppVerifierWindowsMobile.wmv
分享到:
相关推荐
使用Entrek工具查找CE内存及资源泄漏
Application Verifier For Wince5.0,wince 5.0上内存泄漏监控工具
Application Verifier For Wince6.0,wince6.0下监控内存泄漏的工具
Application Verifier PC端工具包,可用于连接wince5.0的内存泄漏检测工具。
对于Windows CE/Windows Mobile...AppVerifier是一个辅助开发工具,不用修改代码,可以检测出程序内存,句柄, GDI对象泄漏,并报告分配泄漏对象的调用栈,有过在大规模代码里查资源泄漏的兄弟应该知道这个调用栈的价值。
ApplicationVerifier记录运行程序句柄
验证检查文件(请选择或拖放一个检查文件, 然后点击 "验证检查文件" 验证文件的完整性.)MD5 Checksum Verifier 是一款基于时间证明的 MD5 算法文件完整性检查工具,帮你轻松地创建文件的校验和,并在未来验证...
开发windows驱动,在发布之前都需要通过driver verify来进行测试,如何进行设置以及如何解决测试中报出来的问题,这本书都给了详细解释。
防止程序做这样的操作,比如程序用异常捕获,以防止错误继续抛出。检测句柄错误检测内存中的堆栈错误检测读写文件,读写网卡数据等的错误等
规则 2:必须包含至少一个特殊字符,不是字母或数字。 规则 3:必须至少包含一个大写字母。 规则 4:必须至少包含一个小写字母。 规则 5:必须至少包含一位数字。 包含文件: .java 文件查看代码和注释.class 文件...
Fast Email Verifier 邮箱验证 很好用
该文档是由展讯下发的CTS Verifier指导文档,按照上面的指导去操作就能测完Verifier测试
usb audio cts verifier tests usb audio cts verifier tests
cts verifier camerafov
MD5Verifier.exe是一个功能强大的MD5码计算工具,小巧易用,绿色不用安装
展讯平台的 CTS Verifier测试手册,提供需要的人参考测试。
google cts verifier的测试的包,因为需要出去下,所以分享给大家
杂项验证:包括免费的电子邮件提供商检查,角色帐户验证,一次性电子邮件地址(DEA)验证 电子邮件可达性:检查是否有信心将电子邮件发送到该地址 安装 使用go get安装此软件包。 go get -u github....
Verifier测试驱动时,常常会发现一些莫名的问题。参考这个文档和WDK,可以更快速的找到问题的原因。