2009-11-17 174 views
5

我在一個大的舊程序中有句柄泄漏。使用sysinternals handle.exe我推斷,泄漏的句柄類型是一個「事件」句柄。但我不確定我的代碼中應該包含哪些部分。是否有一個函數返回句柄的地方?什麼是事件句柄?

編輯:在整個程序中沒有一個CreateEvent,CreateEventEx或OpenEvent實例。

回答

2

你看到這些泄漏的手柄有多少?

事件由臨界區段隱式創建(請參閱InitializeCriticalSection et.al.),可能還有其他一些我目前不記得的Win32元素。此外,它們可以由您正在使用的框架(如果有)(如MFC)或您正在使用的庫創建。

要追蹤泄漏情況,可以使用僅打印斷點。步入CreateEvent函數(使用程序集視圖)並在其第一條指令上放置一個斷點。然後右鍵單擊斷點,選擇'When Hit ...'並編輯選項,以便它不會打入調試器,但會打印一些有用的信息(例如,請參閱$ CALLER宏)。然後運行你的應用程序...並準備好看到一個巨大的日誌。如果存在真正的泄漏,您會在日誌中看到一個重複模式,用於標識違規者。

+0

在最初的亂舞之後,該程序逐漸穩定下來,每秒鐘創建一個或兩個。 - 這個答案聽起來非常可行,但直到明天我都無法嘗試。乾杯。 – Mick 2009-11-17 20:18:20

0

據我所知,幾乎創建事件的唯一事情是CreateEvent和CreateEventEx。其他一些函數可以返回一個事件句柄(例如WaitForMultipleObjects),但它是一個你以前創建並傳遞給它的句柄。

編輯:由於你的代碼顯然不是直接創建事件,你可能會希望通過使用detours來查看對CreateEvent(Ex)的調用,然後追溯堆棧以查看代碼的哪個部分正在導致它們被創建,以及創建它們時調用的是什麼。

1

正如其他人所提到的,CreateEvent/CreateEventEx用於創建「事件」句柄。這些表示同步對象經常用於門禁訪問,向其他線程提供信號(可能),也可以用作鎖的基礎。

如果您嘗試調試涉及事件句柄的泄漏,則應嘗試查找沒有相應的CloseHandle()時調用CreateEvent(Ex)的地方。根據您用來獲取事件的框架,您可能還會發現,如果它們是另一個對象/結構的成員,您可能會在清理時忽略它們(例如,具有在清理時跳過的通用HANDLE成員變量的東西,或者指向HANDLE的指針等)。

如果您不記得在您自己的代碼中創建了這些對象,您可能在其他內部使用它們的類或提供程序上缺少類似的Close()或其他清理方法。做後臺處理,發信號或者提供等待操作完成的方法的東西是這裏通常的嫌疑犯。

創建事件句柄
CreateEvent Function @ MSDN
CreateEventEx Function @ MSDN

清理把手
CloseHandle Function @ MSDN

1

如果你不知道什麼是DLL或第三方組件呼籲CreateEvent或CreateEventEx然後使用Dependency Walker中看看每個DLL導入的內容:

http://www.dependencywalker.com/(它是免費的)

這至少有助於將問題縮小到一組特定的交互 - 那麼您需要查看對該庫的所有調用,並檢查是否正確清理了所有內容。

1

即使您不直接自己創建事件,操作系統或其他庫代碼當然也可以。你可能想看看應用程序打開/創建的某些其他資源沒有被清理的可能性。有可能你真的在泄漏其他東西,但是這件事情會帶來一個事件對象。

它可能有助於在CreateEvent(和朋友)上設置調試器斷點,以查看創建它的內容,但如果這種情況經常發生,以至於您的問題在噪音中丟失,我不會感到驚訝。