Как работают средства обнаружения утечки памяти, такие как очистка и valgrind?
Как я могу спроектировать и реализовать собственный инструмент?
Как работают средства обнаружения утечки памяти, такие как очистка и valgrind?
Как я могу спроектировать и реализовать собственный инструмент?
Такие инструменты обычно используют exeutable с их собственным кодом. например, они заменяют каждый вызов на malloc()
и free()
своими собственными функциями, что позволяет им следить за каждым распределением.
В Visual Studio это можно сделать автоматически, используя только C Runtime Library, используя функции из семейства _CrtDumpMemoryLeaks()
Для обнаружения основной утечки вам просто нужно подключиться к низкоуровневым программам распределения памяти, например. путем исправления malloc/free. Затем вы отслеживаете все распределения и затем сообщаете о тех, которые не были освобождены в соответствующей точке, например. как раз перед выходом.
Для настоящей работы valgrind работает достаточно хорошо. Он обнаруживает недопустимые утечки чтения/записи и утечки памяти.
Для проекта hobby вы можете создать свой собственный модуль управления памятью, который отслеживает распределение различных указателей и его использование. Если вы не видите какое-либо место mem, которое используется в течение длительного времени, это может быть утечка.
Вы можете найти некоторые варианты BSD для управления памятью/профилирования для примеров кода. Например http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
Я разрабатываю этот инструмент: Deleaker.
Конечно, очевидная идея - зацепить все функции, которые выполняют распределения и освобождения. Это не только malloc и free, скорее HeapAlloc/HeapFree (если речь идет о платформе Windows), потому что современные версии VС++ (после VC 6.0) просто перенаправляют malloc/free в winapi HeapAlloc/HeapFree.
Для каждого распределения сохраняется стек и сохраняется объект. При каждом освобождении объект освобождается. На первый взгляд это так просто: просто сохраните список выделенных объектов и удалите объект на крючок перераспределения.
Но есть сложные части:
Вам нужно сохранить список выделенных объектов. Если вы добавляете/удаляете объект в каждой подключенной функции, процесс выполняется в режиме suooo slooow. Это похоже на общую проблему таких инструментов.
Использование функции dbghelp.dll для получения трассировки стека занимает много времени. Вы должны быстрее получать записи стека: например, путем ручного считывания памяти процесса.
Некоторые утечки производятся с помощью системных DLL. Если вы покажете им все, у вас есть тонны утечек, но пользователь не может "решить" его: у него нет доступа к его исходному коду и он не может предотвратить выполнение этого кода. Невозможно остановить эту утечку. Некоторые из них являются однократными выделениями в точке входа в систему dll, поэтому это не настоящая утечка (хороший вопрос, какая утечка вообще?). Как распознать те утечки, которые должны быть показаны? Хорошая фильтрация - это ответ.
Надеюсь, что это поможет.