Меню:


Electric Fence — библиотека предназначенная для поиска ошибок работы с памятью в программах, использующих стандартные функции библиотеки языка C — malloc, calloc, realloc и т.п. Данная библиотека написана Bruce Perens в 1990-х годах и является широко известным средством для поиска ошибок, хотя в последние годы у нее появились очень мощные конкуренты в лице Valgrind и Google Performace Tools.

С помощью Electric Fence вы можете производить поиск двух типов ошибок:

Для выполнения этих задач Electric Fence использует механизмы защиты участков виртуальной памяти, предоставляемых операционной системой1 — для ее работы требуется наличие функций mprotect & mmap.

Работа с библиотекой

Использование библиотеки достаточно просто — необходимо слинковать вашу программу с библиотекой efence2 или загрузить ее с помощью LD_PRELOAD, например:

# ulimit -c unlimited
# LD_PRELOAD=/usr/lib/libefence.so.0.0 ./your_program

Первая строка необходима для того, чтобы разрешить генерацию посмертного дампа состояния программы, что по умолчанию запрещено на большинстве систем.

Если код пытается получить доступ к памяти за пределами выделенного блока, или осуществить доступ к освобожденному блоку памяти, то это приводит к возникновению аппаратной ошибки и аварийному завершению программы (segmentation fault). После этого вы можете использовать отладчик для того, чтобы посмотреть стек вызова функций приведший к возникновению ошибки. Например, рассмотрим выполнение следующей программы, содержащую двойное освобождение памяти:

#include <stdlib.h>

int main(int argc, char** argv) {
    char* mem=(char*)(malloc(10));
    free(mem);
    free(mem);
    return 0;
}

Скомпилируем программу с отладочной информацией и запустим ее под управлением Electric Fence:

# LD_PRELOAD=/usr/lib/libefence.so.0.0  ./test-double-free

  Electric Fence 2.1 Copyright (C) 1987-1998 Bruce Perens.

ElectricFence Aborting: free(b7d31ff4): address not from malloc().
[1]    5928 illegal hardware instruction (core dumped)  LD_PRELOAD=/usr/lib/libefence.so.0.0 ./test-double-free

После завершения программы в текущем каталоге вы найдете файл core, который и содержит посмертный дамп состояния программы. С помощью отладчика заглянем в полученный дамп чтобы найти место, в котором возникла ошибка:

# gdb ./test-double-free core
................................................................
..... пропущенные строки с сообщениями о загрузке библиотек ....
Core was generated by `./test-double-free'.
Program terminated with signal 4, Illegal instruction.
#0  0xb7eea410 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7eea410 in __kernel_vsyscall ()
#1  0xb7da2366 in kill () from /lib/tls/i686/cmov/libc.so.6
#2  0xb7ee5c54 in EF_Abort () from /usr/lib/libefence.so.0.0
#3  0xb7ee50a2 in free () from /usr/lib/libefence.so.0.0
#4  0x080483da in main () at test-double-free.c:6

С помощью команды bt отладчика gdb мы получаем стек вызова функций, который нам показывает, что ошибка возникла в строке 6 файла с исходным текстом test-double-free.c. Остается исправить эту ошибку и снова запустить программу на выполнение.

Управление поведением библиотеки

В большинстве случаев для использования библиотеки достаточно стандартных настроек. Но если необходимо, то пользователь может изменить поведение библиотеки с помощью определенных переменных среды:

EF_PROTECT_BELOW
При значении этой переменной равном 1 включается режим проверки доступа к областям памяти, которые находятся до выделенного блока (по умолчанию проверяется доступ к памяти за верхней границей выделенного блока)
EF_PROTECT_FREE
При ненулевом значении, Electric Fence прекращает возвращать освобождаемую память в пул свободной памяти, откуда она снова может быть выделена программе. Стоит отметить, что при работе в данном режиме, программе может понадобиться значительно большее количество свободной памяти.
EF_ALLOW_MALLOC_0
При ненулевом значении этой переменной, Electric Fence разрешает выделение блоков памяти с длиной 0, что по умолчанию приводит к возникновению ошибки.
EF_ALIGNMENT
Устанавливает значение, которое будет использоваться для выравнивания границ выделяемых блоков памяти. По умолчанию это значение равно sizeof(int). Установка нестандартных значений может быть полезна для обнаружения некоторых видов ошибок, но перед тем как это делать прочитайте раздел "Word-alignment and Overrun Detection" в справочной странице libefence.3, входящей в состав пакета.
EF_FILL
позволяет указать число от 0 до 255, которое будет использоваться как заполнитель для выделяемых областей памяти

Использование EF_PROTECT_BELOW очень полезно для проверки того, не происходит ли доступ к областям памяти, которые находятся до выделенного блока. Обычно проверка программы происходит следующим образом — сначала исправляются все ошибки, возникающие при использовании стандартных настроек, а затем, включается режим EF_PROTECT_BELOW и все проверки выполняются снова.


1. Работа библиотеки была протестирована на Linux, Solaris, AIX, HP-UX и еще некоторых операционных системах. В принципе, библиотека должна работать на всех POSIX-совместимых системах, реализующих функции mmap & mprotect.

2. Нельзя использовать Electric Fence вместе с другими библиотеками, которые предназначены для поиска ошибок работы с памятью.

Last change: 05.03.2013 16:54

blog comments powered by Disqus