Обнаружение утечек дескриптора файлов с помощью Win32 C++
есть ли способ обнаружить утечки дескриптора файла при завершении программы?
в частности, я хотел бы убедиться, что все мои дескрипторы, которые создаются, освобождаются в коде.
например, у меня может быть CreateFile() где-то, и при завершении программы я хочу обнаружить и убедиться, что все они закрыты.
10 ответов
я использовал !htrace команда windbg.
!htrace -enable
!htrace -snapshot
!htrace -diff
позволяет сравнить ситуацию дескриптора двух точек выполнения и помочь вам найти точку, где был выделен просочившийся дескриптор.
это сработало хорошо для меня.
Если вы можете (т. е. если это не огромная устаревшая кодовая база, которую вы исправляете), вы должны рассмотреть возможность использования RAII идиома, чтобы обернуть вокруг ваших дескрипторов файлов. "Взяв" дескриптор файла в конструкторе и выпустив его в деструкторе, вы можете быть уверены, что к тому времени, когда ваш RAII выйдет из области действия, ваш дескриптор файла также будет хорошо очищен.
Это тот же принцип, что и смарт-указатели, и это очень полезная концепция, чтобы иметь в вашем наборе инструментов для избежания таких проблем, как это в C++.
если вы не можете позволить себе BoundsChecker или похожие...
один трюк, который я использовал, - это замена CreateFile
etc. своими фантиками. В дополнение к возвращению значения дескриптора они делают запись _ _ FILE__ и _ _ LINE__ для каждого дескриптора. Вам нужно будет обернуть CloseHandle
также, чтобы убедиться, что правильно закрытые дескрипторы не вызывают ложных срабатываний.
все просто:
// StdAfx.h
#include <windows.h>
#undef CreateFile
#if defined(UNICODE)
#define CreateFile DbgCreateFileW
#else
#define CreateFile DbgCreateFileA
#endif
// etc.
затем следует определить DbgCreateFileW
и DbgCreateFileA
где-то в вашем код.
это предполагает, что у вас есть контроль над соответствующими частями кода. Если нет, вы можете сделать что-то подобное, используя (например) Microsoft Detours (вам понадобится лицензия для включения его в выпущенный продукт, но я считаю, что он может свободно использоваться для отладки/тестирования/и т. д.)
в долгосрочной перспективе, однако, вы должны посмотреть на преобразование кода, чтобы использовать "умный" тип дескриптора, который автоматически вызывает CloseHandle
когда он выходит за рамки.
BoundsChecker или другие подобные программы сделают это. Я также думал, что запуск под отладчиком в VC6 и выше сообщит о списке утечек. Возможно, это потому, что у меня всегда были инструменты плагинов для такого рода вещей.
другой совет будет Sysinternals FileMon (ссылке).
Он показывает вам файловую систему acitivity, поэтому он должен поддерживать вас в поиске открытых дескрипторов.
Как заявил MadKeithV, вы можете использовать RAII для большого эффекта.
также простой способ (и бесплатно) использовать Визуальный Детектор Утечки. Это не идеально, но хороший способ убедиться, что у вас есть free'D/delete[]d/close'D и т. д.
windbg или ntsd есть !handle расширение, которое говорит вам, что обрабатывает приложение имеет открыт. Я полагаю, вы могли бы поставить точку останова в конце своей программы и сбросить ручки там.
также может быть что-то, что вы можете сделать в powerdbg (http://www.codeplex.com/powerdbg) для автоматизации этого процесса.
конечно, это предполагает, что ваше время стоит дешевле, чем покупать решение :)