Вопрос

Это немного гипотетично и сильно упрощено, но...

Предположим, что это программа, которая будет вызывать функции, написанные третьими лицами.Можно предположить, что эти стороны не являются враждебными, но нельзя считать их "компетентными".Каждая функция будет принимать некоторые аргументы, иметь побочные эффекты и возвращать значение.У них нет состояния, пока они не запущены.

Цель состоит в том, чтобы убедиться, что они не могут вызвать утечку памяти, регистрируя все mallocs (и т.п.), А затем освобождая все после завершения функции.

Возможно ли это?Практично ли это?

p.s.Важной частью для меня является обеспечение того, чтобы никакие выделения не сохранялись, поэтому способы устранения утечек памяти без этого для меня бесполезны.

Это было полезно?

Решение

Вы не указываете операционную систему или среду, этот ответ предполагает Linux, glibc и C.

Вы можете установить __malloc_hook, __free_hook и __realloc_hook, чтобы указывать на функции, которые будут вызываться из malloc(), realloc() и free() соответственно.Существует справочная страница __malloc_hook, показывающая прототипы.Вы можете добавить выделение дорожек в эти перехваты, затем вернуться, чтобы позволить glibc обрабатывать выделение / освобождение памяти.

Похоже, вы хотите освободить все текущие ассигнования, когда вернется сторонняя функция.Есть способы заставить gcc автоматически вставлять вызовы при каждом входе в функцию и выходе с использованием -finstrument-functions, но я думаю, что это было бы неэлегантно для того, что вы пытаетесь сделать.Можете ли вы использовать свой собственный код для вызова функции в вашей библиотеке отслеживания памяти после вызова одной из этих сторонних функций?Затем вы могли бы проверить, есть ли какие-либо выделения, которые сторонняя функция еще не освободила.

Другие советы

Во-первых, вы должны указать точки входа для malloc() и free() и друзья.Потому что этот код уже скомпилирован (верно?) вы не можете зависеть от #define для перенаправления.

Затем вы можете реализовать их очевидным способом и зарегистрировать, что они пришли из определенного модуля, связав эти подпрограммы с этими модулями.

Самый быстрый способ включает в себя никаких протоколирований вообще. Если объем используемой ими памяти ограничен, почему бы предварительно не выделить всю "кучу", которая им когда-либо понадобится, и не написать из нее распределитель?Затем, когда это будет сделано, освободите всю "кучу", и все готово!Вы могли бы распространить эту идею на несколько куч, если она более сложная, чем эта.

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

Практично ли это?Я думаю, что это так, при условии, что скорость удара приемлема.

Вы могли бы запустить сторонние функции в отдельном процессе и закрыть процесс, когда закончите использовать библиотеку.

Лучшим решением, чем попытка протоколировать mallocs, может быть изолирование функций при их вызове — предоставление им доступа к фиксированному сегменту памяти, а затем освобождение этого сегмента по завершении выполнения функции.

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

Разве вы не можете просто заставить их выделить всю свою память в стеке?Таким образом, было бы гарантировано освобождение после завершения работы функции.

В прошлом я написал программную библиотеку на C, в которой была подсистема управления памятью, которая содержала возможность регистрировать выделения и освобождения и вручную сопоставлять каждое выделение и освобождение.Это было в некоторой степени полезно при попытке обнаружить утечки памяти, но использовать его было сложно и отнимало много времени.Количество журналов было огромным, и потребовалось много времени, чтобы разобраться в них.

При этом, если ваша сторонняя библиотека имеет обширные ресурсы, то, скорее всего, нецелесообразно отслеживать это с помощью ведения журнала.Если вы работаете в среде Windows, я бы посоветовал использовать такой инструмент, как Purify [1] или BoundsChecker [2], который должен быть способен обнаруживать утечки в ваших сторонних библиотеках.Инвестиции в инструмент должны окупиться сэкономленным временем.

[1]: http://www-01.ibm.com/software/awdtools/purify/ Очищать

[2]: http://www.compuware.com/products/devpartner/visualc.htm Ограничитель

Поскольку вы беспокоитесь об утечках памяти и говорите о malloc / free, я предполагаю, что вы находитесь на C.Я также предполагаю, основываясь на вашем вопросе, что у вас нет доступа к исходному коду сторонней библиотеки.

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

Если у вас есть свободные деньги, подумайте о том, чтобы использовать Purify для отслеживания проблем.Это творит чудеса и не требует исходного кода или перекомпиляции.Существуют также другие доступные библиотеки malloc для отладки, которые стоят дешевле.Электрический забор - это единственное название, которое я помню.Тем не менее, отладочные хуки, упомянутые Дентоном Джентри, тоже кажутся интересными.

Если вы слишком бедны для Purify, попробуйте Valgrind.Это намного лучше, чем было 6 лет назад, и в это намного легче погрузиться, чем Очищать.

Microsoft Windows предоставляет (используйте SUA, если вам нужен POSIX), вполне возможно, самую продвинутую инфраструктуру heap + (другой API, известный для использования heap) из всех существующих на сегодняшний день ОС.

отладочные хуки __malloc() и связанные с ними интерфейсы отладки CRT хороши для случаев, когда у вас есть исходный код для тестов, однако они часто могут пропускать выделения стандартными библиотеками или другим связанным кодом.Это ожидаемо, поскольку они являются инфраструктурой отладки кучи Visual Studio.

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

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

umdh - это инструмент, который может помочь оценить состояние на различных контрольных точках, однако данные постоянно накапливаются во время выполнения целевого задания. o это не простая остановка отладки с контрольными точками в традиционном контексте.Также, ПРЕДУПРЕЖДЕНИЕ, По крайней мере, в последний раз, когда я проверял, общий размер циклического буфера, в котором хранится информация стека, для каждого запроса несколько невелик (64 тыс. записей (entries + stack)), поэтому вам может потребоваться быстрый сброс для пользователей с большим количеством кучи.Существуют и другие способы доступа к этим данным, но umdh довольно прост.

ПРИМЕЧАНИЕ есть 2 режима;

  1. РЕЖИМ 1, umdh {-p:Process-id/-pn:ProcessName} [-f: имя файла] [-g]
  2. РЕЖИМ 2, umdh [-d] {File1} [File2] [-f: имя файла]

    Я не знаю, какое безумие охватило разработчика, который решил чередовать спецификатор аргумента -p: foo и голый порядок аргументов, но это может немного сбить с толку.

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

Выполните gflags без аргументов для режима пользовательского интерфейса, +arg и /args являются другой также "режимы" использования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top