Как зарегистрировать malloc - PullRequest
       55

Как зарегистрировать malloc

4 голосов
/ 09 сентября 2008

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

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

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

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

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

Ответы [ 10 ]

4 голосов
/ 09 сентября 2008

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

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

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

4 голосов
/ 09 сентября 2008

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

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

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

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

Это практично? Я думаю, что до тех пор, пока скоростной удар приемлем.

3 голосов
/ 09 сентября 2008

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

2 голосов
/ 09 сентября 2008

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

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

1 голос
/ 09 сентября 2008

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

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

[1]: http://www -01.ibm.com / программное обеспечение / awdtools / Очистить / Очистить

[2]: http://www.compuware.com/products/devpartner/visualc.htm BoundsChecker

1 голос
/ 09 сентября 2008

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

0 голосов
/ 02 июня 2009

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

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

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

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

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

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

  1. РЕЖИМ 1, umdh {-p: идентификатор-процесса | -pn: имя-процесса} [-f: имя файла] [-g]
  2. РЕЖИМ 2, umdh [-d] {Файл1} [Файл2] [-f: Имя файла]

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

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

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

0 голосов
/ 21 октября 2008

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

0 голосов
/ 21 октября 2008

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

0 голосов
/ 09 сентября 2008

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

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

...