29 ==8720== To see them, rerun with: --show-reachable=yes
Строки 17–29 предоставляют отчет об утечке; эта память была выделена в строке 11
ch15-badmem1.с
.
Помимо отчетов о неправильном использовании динамической памяти, Valgrind может диагностировать использование неинициализированной памяти. Рассмотрим следующую программу,
ch15-badmem3.c
:
1 /* ch15-badmem3.c --- плохое обращение с нединамической памятью */
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 int main(int argc, char **argv)
7 {
8 int a_var; /* Обе не инициализированы */
9 int b_var;
10
11 /* Valgrind
не отметит это; см. текст. */
12 a_var = b_var;
13
14 /* Использование неинициализированной памяти; это отмечается. */
15 printf("a_var = %d\n", a_var);
16
17 return 0;
18 }
При запуске Valgrind выдает этот (сокращенный) отчет:
==29650== Memcheck, a.k.a. Valgrind, a memory error detector for x86-linux.
...
==29650== Use of uninitialised value of size 4
==29650== at 0x42049D2A: _IO_vfprintf_internal (in /lib/i686/libc-2.2.93.so)
==29650== by 0x420523C1: _IO_printf (in /lib/1686/libc-2.2.93.so)
==29650== by 0x804834D: main (ch15-badmem3.с:15)
==29650== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
==29650==
==29650== Conditional jump or move depends on uninitialised value(s)
==29650== at 0X42049D32: _IO_vfprintf_internal (in /lib/i686/libc-2.2.93.so)
==29650== by 0x420523C1: _IO_printf (in / lib/i686/libc-2.2.93.so)
==29650== by 0x804834D: main (ch15-badmem3.c:15)
==29650== by 0x420158D3: __libc_start_main (in /lib/i686/libc-2.2.93.so)
...
a_var = 1107341000
==29650==
==29650== ERROR SUMMARY: 25 errors from 7 contexts (suppressed: 0 from 0)
==29650== malloc/free: in use at exit: 0 bytes in 0 blocks.
==29650== For a detailed leak analysis, rerun with: --leak-check=yes
==29650== For counts of detected errors, rerun with: -v
В документации Valgrind объясняется, что копирование неинициализированных данных не выдает сообщений об ошибках. Оболочка memcheck отмечает состояние данных (неинициализированные) и отслеживает его при перемещениях данных. Таким образом,
a_var
считается неинициализированной, поскольку это значение было получено от
b_var
, которая была неинициализированной.
memcheck
сообщает о проблеме лишь тогда, когда неинициализированное значение используется. Здесь это происходит в библиотеке С (
_IO_vfprintf_internal
), которая должна преобразовать значение в строку, для этого, она проводит с этим значением вычисления.
К сожалению, хотя Valgrind может обнаружить использование неинициализированной памяти вплоть до уровня битов, он не может осуществлять проверки границ массивов для локальных и глобальных переменных. (Valgrind может осуществлять проверку границ для динамической памяти, поскольку он сам обрабатывает такую память, поэтому знает о начале и конце каждой области.)
В заключение, Valgrind является мощным инструментом отладки памяти. Он использовался в таких крупномасштабных, многопоточных производственных программах, как KDE 3, OpenOffice и веб-браузер Konqueror. Он конкурирует с несколькими коммерческими предложениями, а другая его версия была даже использована (совместно с эмулятором WINE [182] ) для отладки программ, написанных для Microsoft Windows с использованием Visual С++! Вы можете получить Valgrind с его веб-сайта [183] .
182
http://www.winehq.com
— Примеч. автора.
183
http://valgrind.kde.org
— Примеч. автора.
15.5.2.5. Другие отладчики malloc
Две статьи Cal Ericson в Linux Journal описывают
mtrace
и
dmalloc
,
а также большинство других перечисленных ниже инструментов. Эти статьи Memory Leak Detection in Embedded Systems, выпуск 101 [184] , сентябрь 2002 г., и Memory Leak Detection in C++, выпуск 110 [185] , июнь 2003 г. Обе статьи доступны на веб-сайте Linux Journal.
184
http://www.linuxjournal.com/article.php?sid=6059
— Примеч. автора.
185
http://www.linuxjournal.com/article.php?sid=6556
— Примеч. автора.
Другие инструменты сходны по природе с описанными ранее.
ccmalloc
Замещающая
malloc
библиотека, которая не нуждается в особой компиляции и может использоваться с С++. См.
Пакет с большими возможностями настройки для отладки памяти и тестирования. См
http://www.cbmamiga.demon.со.uk/mpatrol
.
memwatch
Пакет, требующий использования специального заголовочного файла и опций времени компилирования. См.
http://www.linkdata.se/sourcecode.html
.
njamd
«Не просто еще один отладчик malloc» (Not Just Another Malloc Debugger). Эта библиотека не требует специальной компоновки с приложением; вместо этого она использует
LD_PRELOAD
для замены стандартных процедур. См.
http://sourceforge.net/projects/njamd
.
yamd
Похож на Electric Fence, но со многими дополнительными опциями. См.
http://www3.hmc.edu/~neldredge/yamd
.
Почти все из этих пакетов используют для точной настройки своего поведения переменные окружения. В таблице 15.1 на основе статей из Linux Journal сделана сводка различных пакетов.
Таблица 15.1. Сводка особенностей инструментов памяти