1062078174: 1: top 10 allocations:
1062078174: 1: total-size count in-use-size count source
1062078174: 1: 30 1 30 1 ra=0x8048412
1062078174: 1: 30 1 30 1 Total of 1
1062078174: 1: dumping not-freed pointers changed since 0:
1062078174: 1: not freed: '0x804c008|s1' (30 bytes) from 'ra=0x8048412'
1062078174: 1: total-size count source
1062078174: 1: 30 1 ra=0x8048412 /* Выделение здесь */
1062078174: 1: 30 1 Total of 1
1062078174: 1: unknown memory: 1 pointer, 30 bytes
1062078174: 1: ending time = 1062078174, elapsed since start = 0:00:00
Вывод содержит много статистических данных, которые нам пока не интересны. Интересна строка, в которой указывается не освобожденная память, с адресом возврата, указывающим на выделившую память функцию ('ra=0х8048412
'). Документация dmalloc
объясняет, как получить расположение в исходном коде этого адреса с использованием GDB.
$ gdb ch15-badmem1 /* Запустить GDB */
GNU gdb 5.3
...
(gdb) x 0x8048412 /* Проверить адрес */
0x8048412 <main+26>: 0х8910с483
(gdb) info line *(0x8048412) /* Получить сведения о строке */
Line 11 of "ch15-badmem1.с" starts at address 0x8048408 <main+16>
and ends at 0x8048418 <main+32>.
Это трудно, но выполнимо, если нет другого выбора. Однако, если вы включите в свою программу заголовочный файл "dmalloc.h
" (после всех остальных операторов #include
), вы можете получить сведения из исходного кода непосредственно в отчете.
...
1062080258: 1: top 10 allocations:
1062080258: 1: total-size count in-use-size count source
1062080258: 1: 30 1 30 1 ch15-badmem2.c:13
1062080258: 1: 30 1 30 1 Total of 1
1062080258: 1: dumping not-freed pointers changed since 0:
1062080258: 1: not freed: '0x804c008|s1' (30 bytes) from 'ch15-badmem2.c:13'
1062080258: 1: total-size count source
1062080258: 1: 30 1 ch15-badmem2.с:13
1062080258: 1: 30 1 Total of 1
...
(Файл ch15-badmem2.c
является аналогичным ch15-badmem1.с
, за исключением того, что он включает "dmalloc.h"
, поэтому мы не стали беспокоиться с его отображением).
Отдельные возможности отладки включаются или выключаются посредством использования лексем (tokens) — специально распознаваемых идентификаторов — и опций -р
для добавления лексем (свойств) или -m
для их удаления. Имеются предопределенные комбинации, 'low
', 'med
' и 'high
'. Чем являются эти комбинации, вы можете увидеть с помощью 'dmalloc -Lv
'.
$ dmalloc low /* Установить low */
$ dmalloc -Lv /* Показать установки */
Debug Malloc Utility: http://dmalloc.com/
For a list of the command-line options enter: dmalloc --usage
Debug-Flags 0x4e40503 (82052355) (low) /* Текущие лексемы */
log-stats, log-non-free, log-bad-space, log-elapsed-time, check-fence,
free-blank, error-abort, alloc-blank, catch-null
Address not-set
Interval 100
Lock-On not-set
Logpath 'log2'
Start-File not-set
Полный список лексем вместе с кратким объяснением и соответствующим каждой лексеме числовым значением можно получить с помощью 'dmalloc -DV
':
$ dmalloc -DV
Debug Tokens:
none (nil) -- no functionality (0)
log-stats (lst) -- log general statistics (0x1)
log-non-free (lnf) -- log non-freed pointers (0x2)
log-known (lkn) -- log only known non-freed (0x4)
log-trans (ltr) -- log memory transactions (0x8)
log-admin (lad) -- log administrative info (0x20)
log-blocks (lbl) -- log blocks when heap-map (0x40)
log-bad-space (lbs) -- dump space from bad pnt (0x100)
log-nonfree-space (lns) -- dump space from non-freed pointers (0x200)
log-elapsed-time (let) -- log elapsed-time for allocated pointer (0x40000)
log-current-time (let) -- log current-time for allocated pointer (0x80000)
check-fence (cfe) -- check fence-post errors (0x400)
check-heap (che) -- check heap adm structs (0x800)
check-lists (cli) -- check free lists (0x1000)
check-blank (cbl) -- check mem overwritten by alloc-blank, free-blank (0x2000)
check-funcs (cfu) -- check functions (0x4000)
force-linear (fli) -- force heap space to be linear (0x10000)
catch-signals (csi) -- shutdown program on SIGHUP, SIGINT, SIGTERM (0x20000)
realloc-copy (rco) -- copy all re-allocations (0x100000)
free-blank (fbl) -- overwrite freed memory space with BLANK_CHAR (0x200000)
error-abort (eab) -- abort immediately on error (0x400000)
alloc-blank (abl) -- overwrite newly alloced memory with BLANK_CHAR (0x800000)
heap-check-map (hem) -- log heap-map on heap-check (0x1000000)
print-messages (pme) -- write messages to stderr (0x2000000)
catch-null (cnu) -- abort if no memory available (0x4000000)
never-reuse (nre) -- never re-use freed memory (0x8000000)
allow-free-null (afn) -- allow the frees of NULL pointers (0x20000000)
error-dump (edu) -- dump core on error and then continue (0x40000000)
К этому времени у вас должно быть ощущение того, как использовать dmalloc
, и его гибкости, dmalloc
является избыточным для нашей простой демонстрационной программы, но он неоценим для более крупномасштабного, реального приложения.
15.5.2.4. Valgrind: многосторонний инструмент
Инструменты, описанные в предыдущем разделе, все фокусируются на отладке динамической памяти, и это в самом деле является значительной проблемной областью для многих программ. Однако, проблемы динамической памяти не являются единственной разновидностью. Программа Valgrind под лицензией GPL охватывает большое разнообразие проблем, включая те, которые происходят от динамической памяти.
Руководство по Valgrind описывает программу также или лучше, чем можем мы, поэтому мы будем цитировать (и сокращать) его по мере продвижения вперед.
Valgrind является гибким инструментом для отладки и профилирования исполняемых файлов Linux-x86. Инструмент состоит из ядра, которое программно обеспечивает искусственный процессор x86, и ряда «оболочек», каждая из которых является отладочным или профилирующим инструментом. Архитектура модульная, так что можно легко создавать новые «оболочки», не нарушая существующую структуру.