2012-01-31 2 views
15

Если мы хотим проверить утечки памяти в программе на C++, мы можем перегрузить операторы new и delete, чтобы отслеживать выделенную память. Что делать, если мы хотим проверить утечки в программе на C? Поскольку в C нет перегрузки оператора, можем ли мы переписать указатель функции malloc для перехвата вызовов до malloc и распределения памяти треков? Легче ли использовать внешние утилиты? Пожалуйста, предоставьте некоторый код, поскольку я не знаком с указателями метода перезаписи.Обнаружение утечек памяти в программах на C?

Примечание: Я бы хотел сделать это без каких-либо внешних утилит для практики.

+4

Что не так с Valgrind? –

+0

@MitchWheat я упомянул, что я не могу использовать любые внешние утилиты –

+0

Ну, если это для обучения, вы можете узнать, как это делает valgrind ... –

ответ

35

Как и было предложено, для этого уже существуют отличные инструменты, такие как Valgrind.

Далее:

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

#define malloc(X) my_malloc(X, __FILE__, __LINE__, __FUNCTION__) 

void* my_malloc(size_t size, const char *file, int line, const char *func) 
{ 

    void *p = malloc(size); 
    printf ("Allocated = %s, %i, %s, %p[%li]\n", file, line, func, p, size); 

    /*Link List functionality goes in here*/ 

    return p; 
} 

Вы поддерживаете Связанный список адресов, выделяемых вместе с файлом и номером строки из выделенного места. Вы обновляете список ссылок с помощью записей в вашем malloc.

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

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

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

Надеется, что это помогает, и все самое лучшим :)

+0

Это определенно и интересный подход, могу ли я просто добавить размер к некоторому счетчику при вызове malloc, а затем вычесть размер при вызове free? –

+3

Вы могли бы, но это не даст вам детализации, которую вы, возможно, захотите. Таким образом, вы потеряли 2000 байт. Было ли это одним 2000 байтов распределения или 10 200 байт распределения? Список позволит вам сэкономить много времени, просматривая журнал, пытаясь сопоставить все. – Duck

+0

@MikeG: Да, как правильно сказал Дак, связанный список дает вам гибкость и функциональность, чтобы точно определить распределения сбоев. –

10

Valgrind - это то, что вам нужно.

Помню, что прочитал первую главу Algorithms in a Nutshell, в которой говорилось об этом, хотя он не включал код. Просто добавьте в случае, если вам понравится.

, поскольку нет перегрузки операторов в C мы можем переписывайте таНос функция точка для перехвата вызовов на таНос и отслеживать модуль памяти Allocation

На самом деле, вы можете. GIve LD_PRELOAD читать.

+0

Я знаю, как использовать Valgrind, я просто хочу его реализовать –

+1

@MikeG: Это похоже на то, что у вас рак, и вы «знаете о больницах, но хотите попробовать исцелить его сам для практики». –

+5

@KerrekSB: Ничего плохого в том, чтобы играть с ним, это, безусловно, отличный опыт в учебе. В то же время, valgrind является лучшим, когда в среде реального времени, но я должен признать, что это было хорошим обучением для меня, когда я делал это долго давно. –

4

В дополнении к @ Als Ответит, который обертывают вызовы в исходном коде, если вы используете гну ld, вы можете иметь компоновщик завернуть все вызовы (предположительно до malloc, realloc, calloc и free) во время связи, независимо от того, откуда они взяты. Затем вы пишете __wrap_malloc и т. Д. И можете вызвать исходную функцию, например, с __real_malloc.

--wrap=symbol См в http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html

Я не знаю, как это работает с вызовами из разделяемых библиотек. Я предполагаю, что нет.

1

Вот как вы можете изменить таНос, свободные крючки: Hooks for Malloc

+1

изменение гиперссылок. вам следует описать решение, которое вы нашли по ссылке –

1

Используйте mallinfo функцию он работал для меня на Xilinx Zynq baremetal с использованием Xilinx SDK GCC. Я протестировал с умышленной утечкой памяти - я понятия не имею, почему, но результаты Google были невероятно ужасны при поиске этого решения, распространяющего слово, чтобы помочь другим разработчикам!

Смежные вопросы