mprmap программа |
Преобразует адреса программы в журнале mpr в имена функций и местоположения в исходном коде. В аргументе указывается имя исполняемого файла, для которого должен генерироваться журнал. Чтобы увидеть все распределения в программе вместе с цепочкой вызовов функций, которые осуществили эти распределения, можно использовать mprmap программа < mpr.log . По умолчанию отображаются имена функций. При указании флажка -f отображаются также имена файлов, а при указании -l — еще и номера строк внутри файлов. Флажок -l подразумевает наличие -f . Вывод этой программы является допустимым журнальным файлом mpr , который может быть связан каналом с любой другой утилитой mpr . |
mprchain |
Преобразует журнал в вывод, сгруппированный по цепочкам вызовов. Цепочка вызовов функций — это список всех функций, активных в программе на определенный момент. Например, если main() вызывает getargs() , которая впоследствии вызывает parsearg() , активная цепочка вызовов во время работы parsearg() отображается как main:getargs:parsearg . Для каждой отдельной цепочки вызовов, в которой распределялась память во время выполнения программы, mprchain отображает количество распределений и общее количество распределенных байт. |
mprleak |
Этот фильтр просматривает журнальный файл на предмет наличия всех неосвобожденных фрагментов памяти. В качестве стандартного вывода генерируется новый журнальный файл, содержащий только те распределения, которые могут привести к утечкам памяти. Вывод этой программы является допустимым журнальным файлом mpr , который может быть связан каналом с любой другой утилитой mpr . |
mprsize |
Этот фильтр сортирует распределения памяти по размеру. Чтобы просмотреть утечки памяти по размеру, нужно передать вывод mprleak на вход mprsize . |
mprhisto |
Отображает гистограмму распределений памяти. |
Теперь, когда известно об анализаторах журнальных файлов, очень просто найти утечки памяти в нашей тестовой программе. Для этого достаточно воспользоваться командой mprleak mpr.log | mprmap -l ./broken
(что эквивалентно mprmap -l ./broken mpr.log | mprleak
) и в результате обнаружить утечку памяти в строке 20.
$ mprleak mpr.log | mpr map -l ./broken
m:broken(broken.c,20): main(broken.c,47):5:134518624
7.4. Обнаружение ошибок памяти с помощью Valgrind
Valgrind (http://valgrind.kde.org/) представляет собой специфический для Intel х86 инструмент, эмулирующий центральный процессор класса х86 для непосредственного наблюдения над всеми обращениями к памяти и анализа потока данных (он может, например, выявлять чтения неинициализированной памяти, тем не менее перенос содержимого неинициализированной ячейки в другую ячейку, которая никогда для читается, как неинициализированное чтение он не трактует). Valgrind обладает множеством других возможностей, включая просмотр использования кэша и поиск состязаний в многопоточных программах. В действительности, в Valgrind имеется универсальное средство для добавления большего количества возможностей, основанных на его эмуляторе центрального процессора. Однако для наших целей мы лишь кратко рассмотрим выполнение с его помощью агрессивного поиска ошибок памяти, что представляет его стандартное поведение.
Valgrind не требует повторной компиляции программы, хотя, как и все средства отладки, он имеет возможность компилировать программы с отладочной информацией.
$ valgrind ./broken
==30882== Memcheck, a.k.a. Valgrind, a Memory ERROR detector for x86-linux.
==30882== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
==30882== Using valgrind-2.0.0, a program super vision framewok for x86-linux.
==30882== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
==30882== Estimated CPU clock rate is 1547 MHz
==30882== For more details, rerun with: -v
==30882==
==30882== Invalid write of size 1
==30882== Недопустимая запись размером 1
==30882== at 0xC030DB: strcpy (mac_replace_strmem.с:174)
==30882== by 0x8048409: broken (broken.с:15)
==30882== by 0x804851F: main (broken.с:47)
==30882== by 0x802BAE: libc_start_main (in /lib/libc-2.3.2.so)
==30882== Address 0x650F029 is 0 bytes after a block of size 5 alloc'd
==30882== at 0xC0C28B: malloc (vg_replace_malloc.с:153)
==30882== by 0x80483F3: broken (broken.с:14)
==30882== by 0x804851F: main (broken.с:47)
==30882== by 0x802BAE: libc_start_main (in /lib/libc-2.3.2.so)
==30882==
==30882== Conditional jump or move depends on uninitialised value(s)
==30882== Условный переход или перемещение зависит от
неинициализироваиного значения(й)
Читать дальше