==30882== Invalid read of size 1
==30882== at 0x857910: _IO_file_xsputn@@GLIBC_2.1 (in /lib/libc-2.3.2.so)
==30882== by 0x835309: _IO_vfprintf_internal (in /lib/libc-2.3.2.so)
==30882== by 0x83BC31: _IO_printf (in /lib/libc-2.3.2.so) ==30882== by 0x804847A: broken (broken.c:2 6)
==30882== Address 0x650F061 is 0 bytes after a block of size 5 alloc'd
==30882== at 0xC0C28B: malloc (vg_replace_malloc.с:153)
==30882== by 0x8048437: broken (broken.с:20)
==30882== by 0x804851F: main (broken.с:47)
==30882== by 0x802BAE: __libc_start_main (in /lib/libc-2.3.2.so)
3: 12345678
4: 12345
==30882==
==30882== Invalid write of size 1
==30882== at 0x80484A6; broken (broken.c:3 2)
==30882== by 0x804851F: main (broken.с:47)
==30882== by 0x802BAE: __libc_start_main (in /lib/libc-2.3.2.so)
==30882== by 0x8048354: (within /usr/src/d/lad2/code/broken)
==30882== Address 0xBFF2D0FF is just below %esp. Possibly a bug in GCC/G++
==30882== v 2.96 or 3.0.X. To suppress, use: --workaround-gcc 296-bugs = yes
5: 12345
6: 12345
7: 12345
==30882==
==30882== ERROR SUMMARY: 22 ERRORS from 12 contexts (suppressed: 0 from 0)
==30882== malloc/free: in use at exit: 5 bytes in 1 blocks.
==30882== malloc/free: 2 allocs, 1 frees, 10 bytes allocated.
==30882== For a detailed leak analysis, rerun with: --leak-check=yes
==30882== For counts of detected ERRORS, rerun with: -v
Обратите внимание, что Valgrind нашел все, кроме глобального переполнения и недогрузки, и указал на ошибки более точно, нежели любое другое ранее описанное средство.
Имеется опция, позволяющая включить агрессивную проверку утечек памяти, при которой для каждого распределения находятся все доступные указатели, хранящие ссылку на эту память. Это более точный способ, поскольку часто в программе память распределяют, но в конце не освобождают, так как память в любом случае будет возвращена операционной системе после того, как программа завершится.
$ valgrind --leak-check=yes ./broken
...
==2292== searching for pointers to 1 not-freed blocks.
==2292== checked 5318724 bytes.
==2292==
==2292== 5 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2292== at 0хЕС528В: malloc (vg_replace_malloc.с:153)
==2292== by 0x8048437: broken (broken.с:20)
==2292== by 0x804851F: main (broken.с:47)
==2292== by 0x126BAE: __libc_start_main (in /lib/libc-2.3.2.so)
==2292==
==2292== LEAK SUMMARY:
==2292== definitely lost: 5 bytes in 1 blocks.
==2292== possibly lost: 0 bytes in 0 blocks.
==2292== still reachable: 0 bytes in 0 blocks.
==2292== suppressed: 0 bytes in 0 blocks.
==2292== Reachable blocks (those to which a pointer was found) are not shown.
==2292== To see them, rerun with: --show-reachable=yes
Инструмент Valgrind включает детализированную информацию по своим возможностям и поддерживает множество опций командной строки, которые модифицируют его поведение. Поскольку Valgrind использует эмулятор центрального процессора, программа в нем выполняется во много раз медленнее, чем обычно в системе. Точное замедление зависит от программы, однако Valgrind задумывался для интерактивных программ.
Valgrind могут слегка ввести в заблуждение программы, скомпилированные с высокими уровнями оптимизации. Если вы получаете отчет об ошибке памяти, которая не выглядит осмысленно, попробуйте перекомпилировать программу с -О
вместо -O2
(или выше) и сгенерировать новый отчет.
7.5. Electric Fence
Следующее средство, которое мы рассмотрим — это Electric Fence (доступен на ftp://sunsite.unc.edu/pub/Linux/devel/lang/c и во многих дистрибутивах). Несмотря на то что Electric Fence не обнаруживает утечки памяти, он очень помогает в изоляции переполнений буфера. Каждый современный компьютер (включая все машины, работающие под Linux) обеспечивают аппаратную защиту памяти. Linux этим пользуется для изоляции программ друг от друга (например, сеанс vi
не имеет доступа