Что такое дескриптор события?

У меня утечка ручки в большой старой программе. Использование дескриптора sysinternals.exe я вывел, что тип дескриптора, который протекает, является дескриптором "события". Но я не уверен, какие части моего кода я должен смотреть. Есть ли где-нибудь список функций, которые возвращают дескрипторы событиям?

EDIT: во всей программе нет ни одного экземпляра CreateEvent, CreateEventEx или OpenEvent.

6 ответов


сколько из этих протекших ручек вы видите?

события создаются неявно критическими разделами (см. InitializeCriticalSection et.ал.) и, возможно, некоторые другие элементы Win32, которые я не могу вспомнить на данный момент. Кроме того, они могут быть созданы используемой платформой (если таковая имеется), например MFC, или используемыми библиотеками.

чтобы отследить утечку, вы можете использовать точку останова только для печати. Шаг в функцию CreateEvent (используя вид сборки) и поставьте точку останова на первой инструкции. Затем щелкните правой кнопкой мыши точку останова, выберите " при попадании..."и отредактируйте параметры, чтобы он не взломал отладчик, но напечатал некоторую полезную информацию (например, см. макрос $CALLER). Затем запустите приложение... и будьте готовы увидеть огромное бревно. Если есть истинная утечка, вы увидите повторяющийся шаблон в журнале, который идентифицирует нарушителя.


Как упоминали другие люди, CreateEvent / CreateEventEx используются для создания дескрипторов "событий". Они представляют собой объекты синхронизации, которые часто используются для доступа к воротам, предоставления сигналов (потенциально) другим потокам, а также могут использоваться в качестве основы для блокировок.

Если вы пытаетесь отладить утечку с использованием дескрипторов событий, вы должны попытаться найти места, где createevent(Ex) вызывается без соответствующего CloseHandle(). В зависимости от того, какие принципы вы использовали чтобы получить события, вы также можете обнаружить, что вы можете просто пропустить их при очистке, если они являются членами другого объекта/структуры (например. что-то, что имеет общую переменную-член дескриптора, которая пропускается при очистке, или указатель на дескриптор и т. д.).

Если вы не помните, что создали эти объекты в своем собственном коде, возможно, Вам не хватает аналогичного метода Close() или другого метода очистки в другом классе или поставщике, который использует их внутри. Вещи, которые делают фон обработка, сигнализация или предоставление методов ожидания завершения операций-Обычные подозреваемые здесь.

Создать Обработчики Событий
CreateEvent функция @ MSDN
функция CreateEventEx @ MSDN

Очистка Ручки
функция CloseHandle @ MSDN


Если вы не знаете, какие библиотеки DLL или сторонние компоненты вызывают CreateEvent или CreateEventEx, используйте ходок зависимостей, чтобы увидеть, что импортирует каждая DLL:

http://www.dependencywalker.com/ (это бесплатно)

Это, по крайней мере, поможет сузить проблему до определенного набора взаимодействий - тогда вам нужно будет посмотреть на все вызовы этой библиотеки и проверить, что все очищено правильно.


даже если вы не создаете события непосредственно, ОС или другой код библиотеки, безусловно, может и будет. Возможно, вы захотите взглянуть на возможность того, что есть какой-то другой ресурс, который ваше приложение открывает/создает, который не очищается. Вполне возможно, что ты действительно что-то течет еще, но эта штука приносит объект события вместе для езды.

Это может помочь установить точку останова отладчика на CreateEvent (и друзьях), чтобы увидеть, что его создает, но я не удивлюсь, если это происходит достаточно часто, что ваша проблема теряется в шуме.


следующая ссылка должна помочь вам начать: http://msdn.microsoft.com/en-us/library/ms682655 (VS.85).aspx

CreateEvent и CreateEventEx будут создавать события и возвращать им дескрипторы.


насколько я знаю, почти единственными вещами, которые создают событие, являются CreateEvent и CreateEventEx. Довольно много других функций могут возвращать дескриптор событию (например, WaitForMultipleObjects), но это дескриптор, который вы ранее создали и передали ему..

Edit: поскольку ваш код, по-видимому, не создает событие напрямую, вы можете начать с использования обходов, чтобы посмотреть на вызовы CreateEvent (Ex) и отследить стек, чтобы увидеть, какая часть вашего кода вызывает их быть созданным, и то, что он называет, создает их.