现在的位置: 首页 > 综合 > 正文

使用远程工具跟踪Windows CE应用程序中的内存泄漏(3)- -

2013年11月11日 ⁄ 综合 ⁄ 共 7918字 ⁄ 字号 评论关闭

使用远程工具跟踪Windows CE应用程序中的内存泄漏(3)- -

                                      

 

第 5 部分:其他 Windows CE 远程工具

Windows CE 附带有许多可用于考察嵌入式设备所用操作系统的工具。您需要考察 Application Verifier 工具、Remote Call Profiler 工具以及 Monte Carlo Profiler 工具的使用情况。

Application Verifier 工具

在本部分练习中,您要执行以下过程:

启动 Application Verifier 工具 
 
从 Application Verifier 工具考察 GDILeak.exe 应用程序的输出  

Application Verifier 工具评估应用程序的稳定性,并检测常见的编程错误。该工具在应用程序运行的同时,附加至该应用程序并执行测试。有了此工具,您也许就能诊断出应用程序中的细小问题;反之,将很难在 Microsoft Windows CE 中诊断出它们。

Application Verifier 工具所运行的每个测试都称为填充程序。该工具将这一填充程序插入调用函数和预期目标函数之间的代码路径中。

对于给定的应用程序,您可以选择 Application Verifier 工具使用的填充程序来测试该应用程序。适用于该工具的填充程序示例包括内存泄漏测试、特定 API 使用测试以及内存损坏测试。

在本例中,将运行一个简单的 Win32 应用程序,该程序将位图显示在应用程序窗口的工作区中。要启用该功能,需通过使用 LoadBitmap 从应用程序资源加载位图,使用 GetObject 获得该位图的尺寸,将该位图选入临时设备上下文(通过使用 CreateCompatibleDC 创建的),然后,通过使用 BitBlt 将该位图复制到主设备上下文。

这个过程似乎非常简单,但是,Win32 开发人员仍然容易犯几个错误,例如,在没有清理结束使用资源的情况下,创建临时设备上下文。

以下是绘图例程的代码。

void DrawLogo(PAINTSTRUCT *ps)
{
    HBITMAP hBmp=SHLoadDIBitmap(L"//Windows//Windowsce.bmp");
    BITMAP bmp;

    GetObject(hBmp,sizeof(bmp),&bmp);

    HDC hDCTemp=CreateCompatibleDC(ps->hdc);
    HBITMAP hBmpOld=(HBITMAP)SelectObject(hDCTemp,hBmp);
    int iXPos=(ps->rcPaint.right-bmp.bmWidth)/2;
    int iYPos=(ps->rcPaint.bottom-bmp.bmHeight)/2;

    BitBlt(ps->hdc,iXPos,iYPos,bmp.bmWidth,bmp.bmHeight,hDCTemp,0,0,SRCCOPY);

}

可以从 Windows CE Test Kit 启动 Application Verifier 工具。在以下过程中,您将启动 Application Verifier 工具并针对 ICOP x86 参考板运行它。

要启动 Application Verifier 工具

1.在 Platform Builder 中,选择 Tools | Application Verifier。Windows CE Application Verifier 对话框显示该工具未连接至目标设备。 
 
2.Application Verifier 工具使用一套填充程序 DLL 来截获 API 调用。Windows CE 附带有三个填充程序 DLL,这些填充程序 DLL 用于跟踪句柄 SHELL 和 HEAP。

在示例应用程序 (GDILeak.exe) 中,先分配资源,然后,不要将这些资源交回操作系统。每个句柄泄漏 4 字节。这个量也许看来并不算非常大,但是,对于嵌入式系统生存期而言,随着应用程序在其上日复一日、月复一月甚至年复一年毫不间断地运行,这 4 字节泄漏可能会增加至数兆字节的内存。
 
3.单击 Connect。Device Connection 对话框提示选择连接至目标设备的方式。 
 
4.清除 Use Windows Sockets for the client/server communication 复选框。
 
5.在 Platform Manager 下,单击 Connect。系统会提示您要连接至的设备。
 
6.选择 Windows CE Default Device。
 
7.单击 OK。  

现在,可以运行应用程序并从 Application Verifier 工具考察输出。需要从 Application Verifier 工具启动应用程序。在本例中,将跟踪用户和 GDI 对象。

要从 Application Verifier 工具考察 GDILeak.exe 应用程序的输出

在 Application Verifier 工具中,选择 Shell Verifier。 
 
单击 Add 将测试设置添加至该测试。 
 
展开 Windows 文件夹,然后选择 GdiLeak.exe。 
 
单击 Open。 
 
单击 Run。下图显示了 x86 参考板上的应用程序外观。可以清楚地看到,从应用程序资源加载 Windows CE .NET 位图,并将其显示在应用程序的工作区上。 
 
关闭该应用程序。

接下来,可以在 Application Verifier 工具中查看结果。 
 
在 Application Verifier 工具中,单击 Get Logs。 
 
在 Application Verifier 工具中,单击 View Exported Log。可以看到对 LoadBitmap 和 CreateCompatibleDC 的调用中的泄漏。  

注应当在使用完对象后,调用 DeleteDC 和 DeleteObject 来清理。

该过程举例示范了如何使用 Application Verifier 工具来跟踪应用程序中的泄漏。在本例中,使用了 GDI 对象。您还可以在该应用程序上运行其他测试,以验证句柄(文件、注册表)和堆的使用。

Remote Call Profiler 工具

在本部分练习中,将执行以下过程:

通过 Remote Call Profiler 工具打开 Philosophers 应用程序  

Remote Call Profiler 工具用图形接口将分析和解析工具合并,以使您能够识别代码中的算法瓶颈。

Remote Call Profiler 工具中的技术提供有图形环境,以显示希望分析的信息。您可以比较来自数据不同部分的信息,并以多种格式查看数据。

在本例中,将使用 Remote Call Profiler 工具来确定 Philosophers 应用程序中花费时间的地方。

要通过 Remote Call Profiler 工具打开 Philosophers 应用程序

1.在 Platform Builder 中,选择 Tools | Remote Call Profiler。
 
2.连接到 Windows CE .NET Default Device。
 
3.选择 Launch。
 
4.在 Launch 对话框中,键入应用程序名 Philo.exe。

Philosopher 应用程序将运行,但不显示任何用户界面。该应用程序的确将数据输出到 Platform Builder 中的调试窗口。以下是输出的示例。

3722641 PID:e3c55f36 TID:23a08d72 #0 waiting forever on right chopstick 23a0889a
3722643 PID:e3c55f36 TID:23a08d72 #0 waiting forever on left chopstick 23a088fa
3722652 PID:e3c55f36 TID:239e2802 #1 Eating
3722653 PID:e3c55f36 TID:239e2802 #1 waiting forever on right chopstick 23a088fa
3722681 PID:e3c55f36 TID:239e2fa6 #2 Eating
3722682 PID:e3c55f36 TID:239e2fa6 #2 waiting forever on right chopstick 23a0895a
3722683 PID:e3c55f36 TID:239e2fa6 #2 waiting forever on left chopstick 23a08a62
3722691 PID:e3c55f36 TID:239e2f66 #3 Eating
3722692 PID:e3c55f36 TID:239e2f66 #3 waiting forever on right chopstick 23a08a62
3722706 PID:e3c55f36 TID:239de1aa #4 Eating
3722707 PID:e3c55f36 TID:239de1aa #4 waiting forever on right chopstick 23a08af2
3722708 PID:e3c55f36 TID:239de1aa #4 waiting forever on left chopstick 23a0889a
3723145 PID:e3c55f36 TID:23a08d72 #0 PonderNothingness
3723146 PID:e3c55f36 TID:239e2802 #1 waiting forever on left chopstick 23a0895a
3723185 PID:e3c55f36 TID:239e2fa6 #2 PonderNothingness
3723186 PID:e3c55f36 TID:239e2f66 #3 waiting forever on left chopstick 23a08af2
3723649 PID:e3c55f36 TID:239de1aa #4 PonderNothingness
3723688 PID:e3c55f36 TID:239e2802 #1 PonderNothingness
3724147 PID:e3c55f36 TID:23a08d72 #0 Eating
3724148 PID:e3c55f36 TID:23a08d72 #0 waiting forever on right chopstick 23a0889a
3724149 PID:e3c55f36 TID:23a08d72 #0 waiting forever on left chopstick 23a088fa
3724151 PID:e3c55f36 TID:239e2f66 #3 PonderNothingness
3724187 PID:e3c55f36 TID:239e2fa6 #2 Eating

Remote Call Profiler 工具提供了许多数据视图。视图列出了所有在应用程序中调用的函数、每个函数的调用次数以及调用每个函数所花费的时间。您可以看到,大部分时间都花在了函数 MySleep 中。如果分析 MySleep 的代码,您会看到该函数调用 Sleep(dwMilliseconds)。

要使用 Remote Call Profiler 工具,应用程序必须包含 cecap.h,必须通过 /Gh 标志进行编译(或如果不是为 x86 构建,则为 /callcap),必须通过 cecap.lib 链接。x86 lib 文件在此处 — C:/Program Files/Common Files/Microsoft Shared/Windows CE Tools/Platman/sdk/wce420/platman/lib/target/x86。  

Monte Carlo Profiler 工具

Monte Carlo Profiler 工具是一种统计软件诊断工具,其中操作系统频繁中断,并记录下这些中断地址。从该信息中,可导出每个例程的调用次数。这种类型的分析不会测量或记录执行时间。

Monte Carlo 分析提供了两种方法。第一种,称为进程分析,定期跟踪当前的运行例程。严格意义上讲,这是 Monte Carlo 分析。第二种分析技术,称为对象调用分析,类似于 Monte Carlo 分析。

Monte Carlo 分析依赖于支持 Windows CE 配置文件的内核(本文第 1 - 2 部分中,已启用了 Profiling 内核)。这一版本的内核包含进程和函数标识例程,以及结果收集和显示例程。进程分析方法还依赖于 OEM 适配层 (OAL) 的定期中断。

该分析器一启动就开始收集数据。停止后,它会分析数据并通过调试端口发送结果。

Windows CE 不会自动启动或停止该分析器。可以通过让应用程序调用 ProfileStart 和 ProfileStop 函数,来启动和停止该分析器。也可以利用默认键盘驱动程序(它支持控制该分析器的键)来启动和停止该分析器。此外,还可以使用 Target Control 窗口中的 prof 命令来控制该分析器。

要从 Windows CE Target Control 窗口使用 Monte Carlo Profiler 工具,请使用以下命令:

prof on — 打开分析 
 
s philo — 启动 Philo.exe 应用程序(与使用 Remote Call Profiler 工具时所用应用程序相同) 
 
prof off — 关闭分析
 

注 在关闭 Monte Carlo Profiler 工具之前,应当等待应用程序结束。

以下取自针对 Philo.exe 应用程序运行分析器后的输出。

Total samples recorded = 120814
Module        Hits        Percent
------------  ----------  -------
nk.exe            118695     98.2
coredll.dll          905      0.7
tcpstk.dll           226      0.1
afd.dll               52      0.0
ndis.dll              46      0.0
cxport.dll            26      0.0
relfsd.dll            20      0.0
Philo.exe             18      0.0
gwes.exe              15      0.0
VMini.dll             11      0.0
netbios.dll            7      0.0
filesys.exe            6      0.0
fsdmgr.dll             4      0.0
ddi.dll                4      0.0
explorer.exe           3      0.0
shell.exe              2      0.0
pm.dll                 1      0.0
commctrl.dll           1      0.0
tapi.dll               1      0.0
redir.dll              1      0.0
ohci2.dll              1      0.0
UNKNOWN              769      0.6

Hits       Percent Address  Module       Routine
---------- ------- -------- ------------:---------------------
113891    94.2 8055ab26 nk.exe      : IDLE STATE
   320     0.2 8054e977 nk.exe      : WaitOneMore
   292     0.2 80549ca6 nk.exe      : KCNextThread
   244     0.2 8054f292 nk.exe      : SC WaitForMultiple
   153     0.1 805451e6 nk.exe      : RunqDequeue
   144     0.1 8054b2d4 nk.exe      : SleepOneMore
   134     0.1 80540c88 nk.exe      : memcpy
   133     0.1 805430a4 nk.exe      : KCall
   120     0.0 03fd10a0 coredll.dll : memset
   103     0.0 8054921b nk.exe      : NextThread
   101     0.0 8054191f nk.exe      : INTERRUPTS ENABLE
   101     0.0 805430cd nk.exe      : Int22KCallHandler
    98     0.0 80540c10 nk.exe      : memset
     3     0.0 03f33e1b relfsd.dll  : write header
     3     0.0 03f343aa relfsd.dll  : rreadnocs
     3     0.0 03de1090 fsdmgr.dll  :?ExitVolume
     3     0.0 03cc3a37 cxport.dll  : CTEpEventThread
     3     0.0 03bc26d6 afd.dll     : WsaBufToNdisBuf
     3     0.0 03bc5988 afd.dll     : EnterCriticalSection
     3     0.0 03a5cf70 tcpstk.dll  : InterlockedIncrement
     3     0.0 03a7990b tcpstk.dll  : UDPRcv
     3     0.0 03a95e71 tcpstk.dll  : GetAddrType
     3     0.0 00011915 Philo.exe   :?OutputDebug
     3     0.0 00011ee3 Philo.exe   :?IsAvailable
     3     0.0 0001257f Philo.exe   :?IsInhibitProfiling
     2     0.0 00011018 Philo.exe   :?MyWaitForSingleObject
     2     0.0 000120bf Philo.exe   :?CeCapInit
     1     0.0 0001113a Philo.exe   :?MySleep
     1     0.0 000114fa Philo.exe   :?Eat
     1     0.0 000125c1 Philo.exe   :  penter
     1     0.0 02cb8b2c ohci2.dll   :?GetPortStatus
   773     0.6                      :

您可以从分析信息中看出,philo.exe 应用程序运行时,所需时间的 94% 花费在 IDLE STATE 中。

附Code Clip下载地址

http://download.microsoft.com/download/2/1/2/212a8c47-0971-4ca9-bdbd-f2d6126d6948/Windows%20CE%205.0%20Embedded%20Development%20Labs.msi

repainted from http://www.microsoft.com/china/MSDN/library/windev/default.mspx

抱歉!评论已关闭.