Обычно блоки памяти выделяются функцией malloc
Если вы записываете в область, расположенную после конца выделенного блока (или перед началом блока), вы с большой долей вероятности повредите структуры данных, используемые библиотекой malloc, следящей за распределением памяти. В этом случае в какой-то момент времени вызов malloc
free приведет к нарушению сегментации, и ваша программа завершится аварийно. Определение точного места возникновения сбоя может оказаться очень трудной задачей, поскольку нарушение могло возникнуть задолго до события, вызвавшего аварийное завершение программы.Неудивительно, что существуют коммерческие и бесплатные средства, способные помочь в решении проблем этих двух типов. Например, есть много разных версий функций malloc
free, которые содержат дополнительный код для проверки выделения и освобождения блоков памяти и пытаются учесть двойное освобождение блока и другие типы неправильного использования памяти.ElectricFence
Библиотека ElectricFence была разработана Брюсом Перенсом (Bruce Perens). Она доступна как необязательный компонент в некоторых дистрибутивах Linux, таких как Red Hat (Enterprise и Fedora), SUSE и openSUSE, и может быть легко найдена в Интернете. Это средство пытается применять виртуальную память системы Linux для защиты памяти, используемой функциями malloc
free, и аварийного останова программы в момент повреждения памяти.Выполните упражнение 10.3.
Далее приведена программа efence.c, которая выделяет память с помощью функции malloc
#include
#include
int main() {
char *ptr = (char *)malloc(1024);
ptr[0] = 0;
/* Теперь пишет за пределы блока */
ptr[1024] = 0;
exit(0);
}
Когда вы откомпилируете и выполните программу, то не увидите некорректного поведения. Однако вероятно, что область памяти, выделенная malloc
$ cc -о efence efence.с
$ ./efence
$
Тем не менее, если вы возьмете ту же самую программу и скомпонуйте ее с библиотекой ElectricFence (libefence.a), то получите немедленный отклик:
$ cc -о efence efence.с -lefence
$ ./efence
Electric Fence 2.2.0 Copyright (С) 1987-1999 Bruce Perens
Segmentation fault
$
Выполнение под контролем отладчика позволяет получить подробное описание проблемы;
$ cc -g -о efence efence.с -lefence
$ gdb efence
(gdb) run
Starting program: /home/neil/BLP4e/chapter10/efence
Electric Fence 2.2.0 Copyright (C) 1987-1999 Bruce Perens bruce@perens.com
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1024 (LWP 1869)]
0x08048512 in main () at efence.c:10
10 ptr[1024] = 0;
(gdb)
Как это работает
Библиотека ElectricFence заменяет функцию malloc
Средство valgrind
Для применения valgrind
valgrindДалее приведена программа checker.c, которая выделяет некоторый объем памяти, читает область памяти и записывает данные за пределами выделенного участка, а затем делает выделенный участок недоступным.
#include
#include
int main() {
char *ptr = (char *)malloc(1024);
char ch;