Linux программирование в примерах - Роббинс Арнольд
Шрифт:
Интервал:
Закладка:
Хотя из руководства Valgrind у вас могло сложиться впечатление, что существуют отдельные команды memcheck, addrcheck и т.д., это не так. Вместо этого программа оболочки драйвера с именем valgrind запускает отладочное ядро с соответствующей «оболочкой», указанной в опции --skin=. Оболочкой по умолчанию является memcheck; таким образом, запуск просто valgrind равносильно 'valgrind --skin=memcheck' (Это обеспечивает совместимость с более ранними версиями Valgrind, которые осуществляли лишь проверку памяти, это имеет также больший смысл, поскольку оболочка memcheck предоставляет большую часть сведений.)
Valgrind предусматривает ряд опций. За всеми подробностями мы отсылаем вас к его документации. Опции поделены на две группы; из тех, которые используются с ядром (т. е. работают для всех оболочек), наиболее полезными могут быть следующие:
--gdb-attach=no/yes
Запускается с подключенным к процессу GDB для интерактивной отладки. По умолчанию используется no.
--help
Перечисляет опции.
--logfile=<i>файл</i>
Записывает сообщения в <i>файл.pid</i>.
--num-callers=<i>число</i>
Выводит число вызывающих в трассировке стека. По умолчанию 4.
--skin=<i>оболочка</i>
Использует соответствующую оболочку. По умолчанию memcheck.
--trace-children=no|yes
Запускает трассировку также в порожденных процессах. По умолчанию используется no.
-V, --verbose
Использует более полный вывод. Это включает перечисление загруженных библиотек, а также подсчеты всех различных видов ошибок.
Из опций для оболочки memcheck мы полагаем, что эти являются наиболее полезными.
--leak-check=no|yes
Искать утечки памяти после завершения программы. По умолчанию используется no.
--show-reachable=no|yes
Показать доступные блоки после завершения программы. Если используется --show-reachable=yes, Valgrind ищет динамически выделенную память, на которую все еще есть указывающий на нее указатель. Такая память не является утечкой, но о ней все равно следует знать. По умолчанию используется no.
Давайте посмотрим на Valgrind в действии. Помните ch15-badmem.c? (См. раздел 15.5.2.2 «Electric Fence».) Опция -b записывает в память, находящуюся вне выделенного malloc() блока. Вот что сообщает Valgrind:
$ <b>valgrind ch15-badmem1 -b</b>
1 ==8716== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
2 ==8716== Copyright (C) 2002-2003, and GNU GPL'd, by Julian Seward.
3 ==8716== Using valgrind-20030725, a program supervision framework for x86-linux.
4 ==8716== Copyright (C) 2000-2003, and GNU GPL'd, by Julian Seward.
5 ==8716== Estimated CPU clock rate is 2400 MHz
6 ==8716== For more details, rerun with: -v
7 ==8716==
8 p = <not 30 bytes>
9 ==8716== Invalid write of size 1
10 ==8716== at 0x8048466: main (ch15-badmem1.c:18)
11 ==8716== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
12 ==8716== by 0x8048368: (within /home/arnold/progex/code/ch15/ch15-badmem1)
13 ==8716== Address 0x4104804E is 12 bytes after a block of size 30 alloc'd
14 ==8716== at 0x40025488: malloc (vg_replace_malloc.с:153)
15 ==8716== by 0x8048411: main (ch15-badmem1.c:11)
16 ==8716== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
17 ==8716== by 0x8048368: (within /home/arnold/progex/code/ch15/ch15-badmem1)
18 ==8716==
19 ==8716== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
20 ==8716== malloc/free: in use at exit: 30 bytes in 1 blocks.
21 ==8716== malloc/free: 1 allocs, 0 frees, 30 bytes allocated.
22 ==8716== For a detailed leak analysis, rerun with: --leak-check=yes
23 ==8716== For counts of detected errors, rerun with: -v
(Были добавлены номера строк в выводе, чтобы облегчить обсуждение.) Строка 8 является выводом программы; остальные от Valgrind в стандартную ошибку. Сообщение об ошибке находится в строках 9–17. Она указывает, сколько байтов было записано неверно (строка 9), где это случилось (строка 10), и показывает трассировку стека. Строки 13–17 описывают, откуда была выделена память. Строки 19–23 подводят итоги.
Опция -f программы ch15-badmem1 освобождает выделенную память, а затем записывает в нее через висячий указатель. Вот что сообщает Valgrind в этом случае:
$ <b>valgrind ch15-badmem1 -f</b>
==8719== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
...
p = <not 30 bytes>
==8719== Invalid write of size 1
==8719== at 0x8048498: main (ch15-badmem1.с:21)
==8719== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
==8719== by 0x8048368: (within /home/arnold/progex/code/ch15/ch15-badmem1)
==8719== Address 0x41048024 is 0 bytes inside a block of size 30 free'd
==8719== at 0x40025722: free (vg_replace_malloc.с:220)
==8719== by 0x8048491: main (ch15-badmem1.c:20)
==8719== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
==8719== by 0x8048368: (within /home/arnold/progex/code/ch15/ch15-badmem1)