如何检测S60内存泄露
检测内存泄露的方法有很多种,这里介绍一个HookLogger工具来检测内存泄露。
相信S60的程序开发者都会遇到内存泄露的毛病,这并不是很大的问题,但如果代码量一多起来找起来就会很困难,有时甚至会让人抓狂。这里介绍一个HookLogger工具可以很方便的检测出内存泄露的原因已经具体地址。
这篇文章是基于S60 3 rd 的SDK和HookLogger 1.1版对HookLogger 进行简单介绍。
1、如何下载HookLogger:
http://developer.symbian.com/main/downloads/files/HookLogger_Setup.zip
2、安装HookLogger:
运行HookLogger.Setup.exe,按默认安装。它将位于以下路径下:
C:/Program Files/Common Files/Symbian/tools
3、HookLogger 的界面如下。如果设置不是这样,请将设置调整为下图的设置。
4、设置系统环境变量:
在系统环境边量里,添加环境变量EPOCROOT,其值为/symbian/9.1/S60_3RD_MR/
5、修改HookEUSER.pl
如果你的HookLogger是安装在默认路径下的话,用Notepad打开C:/Program Files/Common Files/Symbian/tools/HookEUSER.pl
找到 my $cmd = "copy $hooks_src";
将其改为 my $cmd = "copy /"$hooks_src/"";
找到 $cmd = "$Bin/AttachDll $euser $hooks $hooked_euser";
将其改为 $cmd = "/"$Bin/AttachDll/" $euser $hooks $hooked_euser";
保存后退出Notepad.
5、运行CMD,将当前路径设为C:/Program Files/Common Files/Symbian/tools/
运行 hookeuser winscw
显示如下说明设置成功。
Target path is /Symbian/9.1/S60_3rd_MR/epoc32/release/winscw/UDEB 1 file(s) copied.
Modified euser.dll to hook EUserParasite_eka2.dll, original is euser.orig.dll.
Run HookEUSER with -r to restore
6、如果遇到其他问题:
运行 hookeuser -r winscw
这个能恢复设置之前的状态。
7、简单测试。测试程序为HookLoggerTest。这是用Symbian 3 rd 的HelloWorld模版生成的一个程序。
void CHookLoggerTestAppUi::HandleCommandL( TInt aCommand )
{
switch( aCommand )
{
case EHookLoggerTestCommand1:
{
// Load a string from the resource file and display it
HBufC* textResource = StringLoader::LoadLC( R_HEWB_COMMAND1_TEXT );
// Show the information Note with
// textResource loaded with StringLoader.
CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote;
informationNote->ExecuteLD( *textResource );
// Pop HBuf from CleanUpStack and Destroy it.
CleanupStack::PopAndDestroy( textResource );
}
break;
default:
Panic( EHookLoggerTestUi );
break;
}
}
菜单中有一个命令EHookLoggerTestCommand1,选择后出现一个信息通知“HelloWorld”。如上代码所示。
现对代码作简单修改,CleanupStack::PopAndDestroy( textResource );改为
CleanupStack::Pop( textResource );显而易见,描述符textResource没有正确删除,这在程序退出的时候将会出现内存泄露。编译,运行如下:
出现一个内存泄露,位置在24a47340。
8、现在介绍使用HookLogger来检测内存泄露到底发生在那里。
首先,启动HookLogger。在Thread选项卡里是空的。在标题栏里出现的是
EPOC Hook Logger: emulator not connected.说明当前HookLogger没有连接到任何模拟器。
从开始菜单中启动模拟器。可以看到和未启动模拟器是HookLogger发生了变化。HookLogger连接到了S60 3 rd winscw平台的udeb的模拟器,内核架构为2版本(EKA2)。而且Thread选项卡中出现了很多线呈。其中打勾得说明HookLogger将会监测他们的内存。我们先选择None,将他们都选空,然后选到我们向监测的程序,HookLoggerTest。这要在启动HookLogger的前提下。如果程序没有启动将不会出现在Thread中。
重新进行一次会产生内存泄露的错误。记下内存泄露的地址。从图中可以看出内存泄露地址24b37340
转到HookLogger的Heap选项卡,单击List All Alloc则会列出所有的内存泄露的信息。如下图所示,有两个内存泄露。
根据应用程序内存泄露在24b37340。在列表中找到这个内存地址。双击这一行,或者单击Alloc Details将会得到具体的内存泄露的信息。
我们将这一行展开CHookLoggerTestAppUi::HandleCommandL(int) <C:/My_Job/S60_3rd/HookLoggerTest/HookLoggerTest/src/HookLoggerTestAppUi.cpp #81> + 12
可以发现,内存泄露发生在HookLoggerTestAppUi.cpp的第81行。我们再双击这一行,可以找到具体的出错位置。
光标闪烁的地方就是出现内存泄露的对象。从这里可以发现HookLogger找到的内存泄露的对象是textResouce.。根据这个线索我们可以对上下文进行查找,从而最终将错误定位在
// Pop HBuf from CleanUpStack and Destroy it.
CleanupStack::Pop( textResource );
它并没有删除掉对内存对象textResouce。需要将它改为CleanupStack::PopAndDestroy( textResource );
至此,我相信大家应该知道HookLogger的使用方法了。这我使用HookLogger的过程中,我发现它还是很有用的。我有几个项目出现了内存泄露的问题,我每次都花费很多时间去去找这些错误,有时甚至几天。在我发现HookLogger之后,内存泄露都十分容易的解决掉了。
希望这个对大家有所帮助。如在这方面有需要了解得,可以随时和我联系。