2011-11-22 30 views
6

我參與了各種C++項目(主要使用MSVC6到MSVC10),其中我們最近發現了一些句柄泄漏(由CreateThread函數給出的線程句柄)。我懷疑還有很多其他的手柄正在泄漏,我想集成一個測試來驗證沒有把手泄漏到我們的夜間測試結果中。是否有可連接到現有應用中的手柄泄漏檢測器?

我的想法是開發一個DLL,它可以檢測相關的kernel32.dll函數(CreateThread,OpenProcess,CreateProcess和其他一些函數)以及CloseHandle函數。然後,對於獲取的每個句柄,DLL將記住一個回溯。在該過程結束時,DLL會打印所有未關閉的句柄的反向跟蹤,然後由測試框架解析該日誌文件。

這當然也會產生所有仍然可以訪問的句柄的回溯(因此從技術上說,它們沒有泄漏 - 也許作者希望操作系統在進程終止時回收它們),但是我猜測明確地關閉它們並不會,不會受到傷害 - 尤其是因爲我們已經有了一些不錯的RAII這種東西的包裝,我們只是不會像我們應該那樣使用它。

現在我想知道 - 這看起來像一個相當簡單的方法;也許這裏的某個人意識到圖書館已經這樣做了?

回答

3

這絕對是可能的,但我不認爲有一個圖書館,它還沒有。

我認爲最簡單的方法是使用Application Verifier。你可以從微軟的Debugging Tools for Windows中獲得。將其配置爲跟蹤應用程序的句柄,在調試器中運行一下應用程序,然後在應用程序退出時轉儲一系列句柄。

如果沒有Application Debugger,另一種方法是在應用程序退出前設置斷點或暫停。在應用程序暫停時,使用諸如Process Explorer之類的東西來獲取所有打開的句柄的列表。

爲了您的目的,我認爲後者會是更好的選擇。我不確定任何使用調試輸出的自動化工具。您可以使用WDK的某些功能來檢索當前進程(或另一進程的)打開句柄的列表,但它有點複雜。

+0

應用程序驗證似乎相當不錯!可惜我似乎無法得到它產生任何有用的結果。即使是在測試情況下的應用程序,明確泄漏的句柄,它永遠不會fidns任何錯誤或警告(即使我運行'ntsd'調試器下的應用程序): -/ –

+0

你確定你hav它配置正確嗎?也許嘗試測試內存泄漏來檢查。我不熟悉'ntsd',但我認爲它只適用於JIT調試。也許嘗試用'windbg'或Visual Studio的調試器來運行你的應用程序。 –

+0

對於應用程序驗證程序的第一步,您應該閱讀:http://geekswithblogs.net/akraus1/archive/2010/06/25/140610.aspx –

2

Mark Russinovich在他的系列文章中解釋爲推動Windows的極限如何更好地處理handles以及如何跟蹤手柄泄漏。

他提到Windows調試器和應用程序驗證器,他正在解釋如何使用它來跟蹤您的手柄泄漏。

在同一頁面中,他還提到了他着名的Process Explorer的一個整潔的功能,它對於進程創建/關閉句柄呈綠色和紅色閃爍。

+0

感謝您指出這一點!我並不知道「推動Windows的極限」,但它看起來很有趣。 –

+0

他描述的原理是用Process Explorer +來檢測幾個進程之間的泄漏,調試它們的方式爲我節省了不止一次 – Boud

1

如果您已經閱讀了Windows推文的限制文章,那麼您會看到它提到了WinDbg!htrace擴展,我認爲它符合您的第一個要求處理創建相關的kernel32.dll函數的要求。

要自動調用!htrace,您可以在您的測試工具中嵌入調試引擎,或者您可以使用諸如PyDbgEng之類的軟件來啓動應用程序並調用!htrace擴展,然後在應用程序完成時收集堆棧。有一個PyDbgEng這種類型的自動化的例子,但在http://pydbgeng.svn.sourceforge.net/viewvc/pydbgeng/trunk/PyDbgEng/Examples/RegMon.py?view=markup的註冊表功能,但我認爲你可以用這個例子來調用一個擴展,請參閱示例中的(dbg.idebug_control.CallExtension)。

1

我們在當前工作場所使用Memory Validator。它可以配置爲跟蹤每個內存分配,COM調用(和ref count)和句柄。您可以啓動它,然後啓動需要驗證的代碼或附加到要驗證的代碼。從那時起,它就會跟蹤你告訴它跟蹤的任何資源。當代碼退出時,它將得到一份報告,說明它正在追蹤的資源是否未分配,以及分配的位置。這是一個商業產品,但它有一個試用期,所以你可以測試它,看看它是否符合你的需求。當我們在複雜的情況下遇到麻煩的泄漏時,對自己和同事有些幫助,但它本身並不是一個神奇的解決方案。良好的泄漏檢測技術仍然需要遵循,它只是給你額外的信息,關於哪些分配仍然懸而未決,以及它們來自哪裏。

0

我玩過Deleaker,並且在內存和處理泄漏方面取得了成功。它可以在Visual Studio中使用或單獨使用。從Deleaker網站:

不要緊,什麼類型的泄漏發生,Deleaker發現他們都: 內存泄漏,泄漏GDI,泄漏(通過堆,虛擬內存,或OLE分配器 等生產) Windows用戶對象和處理。」