Electric Fence

Electric Fencebiblioteka służąca do debugowania dostępu do pamięci w programach bez konieczności ich powtórnej kompilacji. Biblioteka Electric Fence została stworzona przez Bruce'a Perensa.

Dostępy poza zaalokowany obszar pamięci często powodują trudne do wykrycia błędy – program zamiast zakończyć działanie nadpisuje zawartość innej zmiennej i trudno jest zidentyfikować źródło problemu. Electric fence każdą alokacje umieszcza pod koniec (lub na początku) strony pamięci, tak że każde wykroczenie za (odpowiednio przed) zaalokowany obszar spowoduje wygenerowanie wyjątku przez procesor. Ponieważ strony pamięci (przynajmniej na procesorach rodziny x86) muszą mieć rozmiar będący wielokrotnością 4096 bajtów, nie ma możliwości ochrony przed oboma tymi przypadkami jednocześnie, jednak przy użyciu Electric Fence przekroczenia w drugą stronę nadpisywać będą bezużyteczne bajty, a nie inne zmienne.

Electric Fence wykrywa błędy polegające na czytaniem lub pisaniu obszaru danych poza zaalokowanym obszarem, a nie wykrywania wielu innych rodzajami błędów dostępu do pamięci.

Weźmy prosty program w C z błędem off by one:

#include <stdlib.h>
#define SIZE 100

int main()
{
    int* foo;
    int i;

    foo = (int*) malloc (sizeof(int) * SIZE);
    for(i=0; i<=SIZE; ++i)
        foo[i] = 0;

    return 0;
}

Chociaż program ma błąd, prawdopodobnie uruchomi się prawidłowo, ponieważ malloc alokuje zwykle kilka bajtów więcej niż jest to żądane. Użycie gdb w połączeniu z Electric Fence powoduje otrzymanie sygnału i możemy sprawdzić co spowodowało błąd. (komenda gdb efence pojawi się dopiero po skopiowaniu do pliku .gdbinit odpowiedniego fragmentu rozpowszechnianego razem z Electric Fence).

$ gdb ./foo
GNU gdb 6.1-debian
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-linux"...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) r
Starting program: /home/taw/foo

Program exited normally.
(gdb) efence
Enabled Electric Fence
(gdb) r
Starting program: /home/taw/foo
[Thread debugging using libthread_db enabled]
[New Thread 1073830880 (LWP 3227)]

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

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1073830880 (LWP 3227)]
0x0804839f in main () at foo.c:11
11              foo[i] = 0;
(gdb) p i
$1 = 100