使用Application Verifier (AppVerifier)檢查資源泄漏

來源:互聯網
上載者:User

最近在論壇裡看到很多人問怎樣檢查記憶體流失,對於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

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/xdkui/archive/2008/12/19/3560143.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.