Выявление и устранение утечек памяти при помощи MALLOCDEBUG в ОС AIX 5.3

Полезный инструмент для скучной работы

Воспользуйтесь преимуществами MALLOCDEBUG – утилиты для мониторинга подсистемы malloc, входящей в состав AIX® версии 5.3, которая поможет вам в поиске утечек памяти. Решение проблем с утечками памяти может быть сложным и утомительным, а значит, для этого нужен хороший инструмент, чтобы найти источник утечек. Познакомьтесь с примерами кода в этой статье и используйте их для выявления утечек.

Маниш Катьяр, инженер по программному обеспечению, IBM

Маниш Катьяр (Manish Katiyar) работает инженером по программному обеспечению в IBM India Software Labs. Последние два года его работа в IBM в основном касается SARPC. У него есть опыт работы с инструментами хранилищ данных (Ab-Initio). Маниш имеет степень бакалавра в области химии, полученную в Индийском технологическом институте (Kharagpur, India). С ним можно связаться по e-mail manish.katiyar@in.ibm.com.



Ваарун Виджайрагхаван, разработчик системного ПО, IBM

Photo of Vaarun VijairaghavanВаарун Виджайрагхаван (Vaarun Vijairaghavan) является разработчиком системного ПО в IBM India Software Labs в Пуне. Последние три года он участвовал в разработке проекта Distributed Computing Environment (DCE). Он занимается сетевой безопасностью, отказоустойчивостью и распределенными вычислениями. Ваарун имеет степень бакалавра в области компьютерных наук, полученную в Университете Пуны. С ним можно связаться по e-mail vivaarun@in.ibm.com



25.06.2010

Введение

При создании приложений динамическое выделение памяти является благом – оно помогает выделять необходимую память во время работы программы вместо того, чтобы заранее резервировать ее при запуске. Однако очень важно эффективно управлять этой памятью. В больших, сложных приложениях утечки памяти являются обычным делом. Утечка памяти происходит, если ранее выделенный фрагмент памяти уже не нужен или стал недоступен, но его не освободили, и приводит к нехватке общего объема доступной памяти для процесса. Хотя правильные методы программирования сокращают количество утечек, но если некоторые блоки памяти используются для множества функций, это создает риск утечки памяти. Это особенно верно при наличии ошибок в путях.

В этой статье рассматриваются методы отслеживания утечек памяти и преимущества утилиты MALLOCDEBUG, входящей в состав AIX®.

В чем сложность решения проблем с утечками памяти

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

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

Обнаружение утечек памяти

Следующие симптомы указывают на возможное наличие утечек памяти.

  • Команда malloc возвращает набор errno для ENOMEM.
  • Создается дамп core, и одна из функций стека относится к подсистеме malloc.
  • Необычно большой размер процесса.
  • Размер процесса (можно выяснить при помощи команды ps) быстро растет.

Если обнаружены эти симптомы, то это означает, что возникли утечки памяти и имеет смысл воспользоваться средством мониторинга памяти. Существуют некоторые утилиты третьих фирм, такие как Zerofault и IBM Rational® Purify®, но в этой статье обсуждается утилита MALLOCDEBUG, которая входит в состав ОС AIX.

Использование MALLOCDEBUG для отчета об утечках памяти

MALLOCDEBUG – это удобная утилита для мониторинга подсистемы malloc. Вы можете просто включить отладку подсистемы malloc для заданного приложения при помощи двух переменных среды MALLOCDEBUG и MALLOCTYPE. Вам необходимо задать эти переменные для оболочки shell, в которой запускается приложение. В AIX 5.3 отчет об ошибках записывается на стандартное устройство stderr.

MALLOCTYPE

Переменная MALLOCTYPE определяет, какая подсистема malloc должна использоваться, и будет ли включена отладка. В таблице 1 показаны различные значения переменной MALLOCTYPE. В разделе Ресурсы приведена ссылка на справочник IBM «Разработка и портирование приложений C/C++ для AIX».

Таблица 1. Переменные MALLOCTYPE
MALLOCTYPE=Используемый распределитель памятиПодробное описание в справочнике IBM «Разработка и портирование приложений C/C++ для AIX»
3.1Распределитель памяти для версии 3.1Раздел 4.2.1. Распределитель памяти для версии 3.1
NULLРаспределитель памяти по умолчаниюРаздел 4.2.2. Распределитель памяти по умолчанию
bucketsРаспределитель памяти по умолчанию с расширением наборов mallocРаздел 4.2.3. Распределитель памяти по умолчанию с расширением наборов malloc
debugОтладочный распределитель памятиРаздел 4.2.4. Отладочный распределитель памяти
user:archive_nameПользовательский распределитель памятиРаздел 4.2.5. Пользовательский распределитель памяти

Вы должны убедиться, что MALLOCDEBUG настроен на использование выделителя по умолчанию.

MALLOCDEBUG

Переменной MALLOCDEBUG может быть присвоено несколько значений из таблицы 2, разделенных запятыми.

Таблица 2. Переменная MALLOCDEBUG
MALLOCDEBUG=Краткое описание
Align:nЗадает режим выравнивания памяти, где n – это размер ячейки в байтах. За дополнительной информацией обратитесь к разделу Ресурсы.
postfree_checkingУказывает сообщать о попытках доступа к очищенной памяти с последующей попыткой закрыть программу.
validate_ptrsУказывает при появлении указателя, который предварительно не был выделен при помощи malloc, и передан вызову free(), выводить сообщение об ошибке и завершать программу.
override_signal_handlingПри обнаружении ошибок памяти MALLOCDEBUG вынуждает программу создать файл core при помощи вызовов SIGSEGV или SIGABRT. Использование параметра override_signal_handling гарантирует, что программа завершит свою работу и создаст файл core, даже если эти сигналы обрабатывались приложением.
allow_overreading Игноририрует попытки прочитать данные из области за концом выделенного участка памяти.
report_allocations Выводит отчет обо всех выделениях памяти, не закрытых после выхода из приложения.
record_allocations Выводит отчет обо всех выделениях памяти.
continueВыводит отчет об ошибках, кроме аварийной остановки программ. Эта полезная функция доступна в AIX 5.3.
stack_depth:nВыводит отчет об ошибках стека глубиной n вместо значения по умолчанию 6.

Из этих параметров самый полезный – это report_allocations, поскольку он выводит список утечек, обнаруженных в приложении.

Пример

В этом разделе вы познакомитесь с примером программы и несколькими простыми фрагментами кода, демонстрирующими использование MALLOCDEBUG. Исходный код примеров доступен в разделе Загрузка.

Листинг 1. Настройка параметров MALLOCDEBUG и MALLOCTYPE для оболочки shell
/home/user> export MALLOCTYPE=debug
/home/user> export MALLOCDEBUG=report_allocations
Листинг 2. Вывод из программы
/home/user> ./stud 2>mal_dbg_stud
Student Name: Manish
 Subjects # Maths   English

Student Name: Vaarun
 Subjects # Chemistry   Physics

Student Name: Sandeep
 Subjects # Biology   Maths

	......
	......
	......
	......

Student Name: Govind
 Subjects # Physics   Biology

Student Name: Manish
 Subjects # Maths   English

Current allocation report:

    Allocation #0: 0x2000EFE8
        Allocation size: 0x14
        Allocation traceback:
        0xD0371F64  malloc
        0xD0322194  init_malloc
        0xD0323224  malloc
        0x10000BE4  initialize_leaky

    Allocation #1: 0x20010FF0
        Allocation size: 0xA
        Allocation traceback:
        0xD0371F64  malloc
        0x10000C08  initialize_leaky
        0x10000DD4  main
        0x100001B4  __start

    Allocation #2: 0x20012FF0
        Allocation size: 0xA
        Allocation traceback:
        0xD0371F64  malloc
        0x10000C08  initialize_leaky
        0x10000DD4  main
        0x100001B4  __start
	......
	......
	......
	......
    Allocation #17: 0x20030FF0
        Allocation size: 0x10
        Allocation traceback:
        0xD0371F64  malloc
        0x100008F4  getnode
        0x10000B08  insert
        0x10000DDC  main

    Allocation #18: 0x20032FF8
        Allocation size: 0x8
        Allocation traceback:
        0xD0371F64  malloc
        0x10000894  allocate_for_dbl_ptr
        0x10000910  getnode
        0x10000B08  insert

    Allocation #19: 0x20034FE8
        Allocation size: 0x14
        Allocation traceback:
        0xD0371F64  malloc
        0x10000A5C  allocate_name
        0x10000B18  insert
        0x10000DDC  main

    Allocation #22: 0x2003AFF0
        Allocation size: 0x10
        Allocation traceback:
        0xD0371F64  malloc
        0x100008F4  getnode
        0x10000B3C  insert
        0x10000DDC  main
	......
	......
	......
	......

Формат выдачи MALLOCDEBUG не очень понятен. В нем просто выводятся стеки функции, вызывающей malloc для каждого выделяемого блока, который не был очищен. Также выводится размер блоков и значение указателя, возвращенное malloc.

Чтобы сделать приведенную выше выдачу более понятной, мы написали образец скрипта. (См. раздел Загрузка. Пожалуйста, обратите внимание, что это лишь образец, предназначенный для обработки выдач программ, подобных той, что приведена в примере.) В листинге 3 показана предыдущая выдача набора стеков после обработки скриптом.

Листинг 3. Выдача MALLOCDEBUG, обработанная при помощи скрипта
/home/user> ./format_mallocdebug_op.ksh
Usage : ./stack.ksh stackfile

/home/katiyar/DW> ./format_mallocdebug_op.ksh ./mal_dbg_stud | 
   tee ./mal_dbg_stud_formatted
Parsing output from debug malloc ...
Analyzed 50 stacks ...

main
insert
allocate_subjects
malloc
################################
220 bytes leaked in 22 Blocks
################################
main
insert
allocate_name
malloc
################################
220 bytes leaked in 11 Blocks
################################
__start
main
initialize_leaky
malloc
################################
190 bytes leaked in 16 Blocks
################################
main
insert
getnode
malloc
################################
176 bytes leaked in 11 Blocks
################################
insert
getnode
allocate_for_dbl_ptr
malloc
################################
88 bytes leaked in 11 Blocks
################################
initialize_leaky
malloc
init_malloc
malloc
################################
20 bytes leaked in 1 Blocks
################################

Диагностику следует начинать с самых больших утечек. В первом из приведенных выше стеков видно, что main вызывает insert, который вызывает allocate_subjects. allocate_subjects выделяет блок памяти при помощи malloc, и затем этот блок больше не очищается. В выдаче скрипта упоминается, что за 22 отдельных выделения общая утечка составила 220 байтов. Это означает, что вам необходимо найти все места в коде, где выделяется 10 байтов данных, при помощи функции allocate_subjects и проверить, что память была очищена во всех случаях. Тщательный анализ программы укажет место в коде, в котором блок памяти в запросе должен быть очищен.

Подобный анализ был сделан для всех стеков в отчете, и в код было внесено исправление. Чтобы исправления для программы вступили в силу, необходимо перед ее запуском настроить для оболочки shell переменную FREE_BLOCKS=1.

Листинг 4. Выдача после очистки блоков, выделенных при помощи malloc
/home/katiyar/DW> ./stud
Student Name: Manish
 Subjects # Maths   English

Student Name: Vaarun
 Subjects # Chemistry   Physics

Student Name: Sandeep
 Subjects # Biology   Maths

	......
	......
	......
	......

Student Name: Govind
 Subjects # Physics   Biology

Student Name: Manish
 Subjects # Maths   English

Current allocation report:

Total allocations: 0.

Заключение

Для обслуживания программного обеспечения на клиентских машинах обратите внимание на MALLOCDEBUG – одну из нескольких доступных утилит для мониторинга подсистемы malloc. Чтобы избежать множества ошибок на стороне пользователя, весьма полезно проверить приложение при помощи MALLOCDEBUG до установки клиенту. Мы надеемся, что эта статья поможет разработчикам и специалистам по обслуживанию решить проблемы, связанные с утечками памяти.


Загрузка

ОписаниеИмяРазмер
Пример скрипта для обработки отчета отладки mallocau-mallocdebug.zip2KБ

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=AIX и UNIX
ArticleID=498127
ArticleTitle=Выявление и устранение утечек памяти при помощи MALLOCDEBUG в ОС AIX 5.3
publish-date=06252010