8.5.1 Устранение утечек памяти

Предыдущая  Содержание  Следующая V*D*V

В этом разделе мы обсудим инструменты для устранения утечек памяти mtrace и dmalloc.

 

mtrace

 

mtrace является инструментом glibc для борьбы с утечками памяти. Как следует из названия, он используется для отслеживания выделения и освобождения памяти. Для этой цели предназначены два вызова glibc:

 

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

muntrace(void): останавливает трассировку, убирая обработчики трассировки.

 

Распечатка 8.4 показывает простую программу, которая вызывает утечку памяти. Мы покажем, как эта утечка может быть обнаружена с помощью mtrace. Скомпилируйте программу и выполните следующие шаги:

 

# gcc -g leak.c -o leak

# export MALLOC_TRACE=./log

# ./a.out

# cat log

= Start

@ ./a.out:(mtrace+0xf5)[0x8048445] + 0x8049a40 0x13

@ ./a.out:(mtrace+0x105)[0x8048455] + 0x8049a58 0x11

@ ./a.out:(mtrace+0x162)[0x80484b2] - 0x8049a58

= End

 

Как видите, файл журнала, который был сформирован mtrace, довольно загадочный. Glibc предоставляет другую программу с  таким же именем, mtrace (которая является производным от Perl скрипта mtrace.pl). Эта программа анализирует содержимое файла журнала и показывает фактические утечки в дружественном человеку виде.

 

# mtrace ./a.out log

Memory not freed:

-----------------

Address     Size      Caller

0x8048445   0x13  at  ./leak.c:6

 

Таким образом, пользователю сообщается, что когда была включена трассировка, была обнаружена утечка памяти. Кусок памяти размером 19 байт (0x13), не была освобождена память, выделенная в файле leak.c в строке номер 6.

 

dmalloc

 

dmalloc это более совершенный инструмент, который обеспечивает обнаружение утечек памяти, а также множество других функций, таких как проверка смещения (fencepost error, ошибка на единицу при вычислении смещения или числе циклов итерации) и проверка "кучи". Данный раздел посвящён использованию dmalloc в первую очередь для обнаружения утечек памяти. Официальным веб-сайтом для dmalloc является http://dmalloc.com.

dmalloc реализован с помощью библиотеки, которая предоставляет обёртку вокруг интерфейсов выделения памяти, таких как malloc, free, и так далее. Поэтому, чтобы пользоваться dmalloc, приложение должно быть скомпоновано с этой библиотекой. Проиллюстрируем это далее с помощью примера, показанного в Распечатке 8.5. Скомпилируем и скомпонуем dmalloc_test.c с libdmalloc.a. (* для многопоточных программ компонуем с libdmallocth.a. Для программ C++ компонуем с libdmallocxx.a и для многопоточных программ C++ компонуем с libdmallocthcxx.a.)

 

# ls -l libdmalloc.a

-rw-rw-r-- 1 raghav raghav 255408 Sep 4 10:48 libdmalloc.a

# gcc dmalloc_test.c -o dmalloc_test ./libdmalloc.a

 

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

 

# export DMALLOC_OPTIONS=debug=0x3,log=dlog

# ./dmalloc_test

 

Вывод показан в Распечатке 8.6. Строки, выделенные жирным шрифтом, показывают количество утечек памяти. Обратите внимание, что отладочная информация, такая, как имя файла и номер строки, отсутствует. Мы можем получить эту информацию, используя такие инструменты, как gdb или addr2line. Тем не менее, dmalloc предоставляет механизм включения более  подробной отладочной информации в файле журнала с помощью файла dmalloc.h. Этот файл поставляется вместе с пакетом dmalloc. Во все файлы языка Си, которые скомпонованы для создания приложения, которое будет отлаживаться, необходимо включить этот заголовочный файл. Этот заголовочный файл определяет такие функции выделения памяти, как malloc() и free(), с такими макросами препроцессора, как __FILE__ и __LINE__. Например, определение malloc в dmalloc.h сделано следующим образом:

 

#undef malloc

#define malloc(size) \

dmalloc_malloc(__FILE__, __LINE__, (size), DMALLOC_FUNC_MALLOC, 0, 0)

 

Первая строка отменяет все определения malloc, которые поступают из ранее подключённых заголовочных файлы (stdlib.h). Разумеется, dmalloc.h должен быть последним подключённым файлом.

DMALLOC_OPTIONS, как показано в приведённом выше примере, управляет отладкой во время выполнения. Эта переменная окружения может быть установлена вручную или с помощью программы под названием dmalloc. Для встроенных сред вы можете предпочесть установить этот параметр вручную. Чтобы получить более подробную информацию об утилите dmalloc, запустите её из командной строки с аргументом --usage. DMALLOC_OPTIONS представляет собой список из следующих (важных) параметров, разделённых запятыми:

 

debug: этот параметр имеет шестнадцатеричное значение, получающееся путём сложения всех функциональных параметров. Параметр функциональности включает отладку во время выполнения. Например, параметр функциональности 0x1 включает ведение журнала общей статистики, а 0x2 включает ведение журнала утечек памяти. Поэтому добавление значения 0х3 включает и регистрацию общей статистики, и утечек памяти. Список всех функциональных параметров можно получить, запустив программу dmalloc с аргументом --DV.

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

addr: когда он установлен, при обращении к этому адресу выполнение dmalloc прервётся.

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

 

Предыдущая  Содержание  Следующая