Что такое дескриптор события? - PullRequest
6 голосов
/ 17 ноября 2009

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

РЕДАКТИРОВАНИЕ: Во всей программе нет ни одного экземпляра CreateEvent, CreateEventEx или OpenEvent.

Ответы [ 6 ]

2 голосов
/ 17 ноября 2009

Сколько из этих протекающих ручек вы видите?

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

Чтобы отследить утечку, вы можете использовать точку останова только для печати. Войдите в функцию CreateEvent (используя представление сборки) и установите точку останова в ее первой инструкции. Затем щелкните правой кнопкой мыши точку останова, выберите «При ударе ...» и отредактируйте параметры, чтобы они не ломались в отладчике, а выводили некоторую полезную информацию (например, см. Макрос $ CALLER). Затем запустите свое приложение ... и будьте готовы увидеть ОГРОМНЫЙ журнал. Если есть настоящая утечка, вы увидите повторяющийся шаблон в журнале, который идентифицирует нарушителя.

1 голос
/ 17 ноября 2009

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

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

1 голос
/ 17 ноября 2009

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

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

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

1 голос
/ 17 ноября 2009

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

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

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

Создание дескрипторов событий
Функция CreateEvent @ MSDN
Функция CreateEventEx @ MSDN

Ручки для очистки
Функция CloseHandle @ MSDN

0 голосов
/ 17 ноября 2009

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

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

0 голосов
/ 17 ноября 2009

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

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

...