Electric fence
-=-=-=-=-=-=-=-=
Thus spake the master programmer:
"A well-written program is its own heaven; a poorly-written
program is its own hell."
-- Geoffrey James, "The Tao of Programming"
Známou knihovnou pro testování haldy je libefence. Použití
knihovny je podobné jako u mcheck - při linkování přidáte přepínač
-lefence. Je to velmi šikovná knihovna, která nahradí volání pro
alokaci haldy funkcemi, které mezi jednotlivé bloky umístí stránky
zablokované proti čtení i zápisu. Díky tomu se odchytí nejenom zápis
mimo blok ale i čtení. Navíc bloky jsou poměrně daleko od sebe a tak
pravděpodobnost, že ukazatel "přestřelí" z jednoho bloku do druhého
je poměrně malá.
Problém tohoto přítupu je, že stránky nelze samozřejmě dát
kamkoliv. Proto když velikost bloku není dělitelná velikostí
stránky, lze stránka zapasovat pouze z jedné strany (na druhé bude
nějaká mezera). Navíc je nutné brát v úvahu alignment, který ještě
více omezuje přesné měření. Knihovna lze proto ovládat pomocí
několika proměnných (buď jako globálních proměnných v programu, nebo
runtime ze shellu). Ty jsou následující:
EF_ALIGNMENT Určuje na jak velkou hodnotu se mají bloky zarovnávat.
EF_PROTECT_BELOW Pokud je nastavena, stránky se napasují dolu. Bude
se tedy testovat spíše podtečení.
EF_PROTECT_FREE Uvolněné bloky zůstanou v paměti a zablokují se.
Odchytí se tedy přístup do uvolněných bloků.
EF_ALLOW_MALLOC_0 Povolí alokaci velikosti nula.
Výsledky knihovny jsou mnohem pozbudivější, než u knihovny
mcheck:
Chyby pro použití haldy
zapomenuté naalokované bloky paměti
uvolnění nenaalokovaného bloku free() called before first malloc().
vícenásobné uvolnění bloku free(400b5f9c): address not from malloc().
alokace a realokace bloku o velikosti 0 Allocating 0 bytes, probably a bug.
použití paměti bez testu na selhání malloc
Chyby pro použití ukazatelů
použití uvolněného bloku pro zápis crash při přístupu
použití uvolněného bloku pro čtení crash při přístupu
zápis za koncem pole v zásobníku
zápis za koncem alokovaného bloku crash při přístupu
čtení za koncem alokovaného bloku crash při přístupu
zápis daleko za koncem alokovaného bloku crash při přístupu
zápis před koncem alokovaného bloku crash při přístupu
čtení před koncem alokovaného bloku crash při přístupu
čtení neinicalizované paměti načte 0
Knihovna uspěla všude, kde díky svému návrhu mohla vyjma čtení
neinicializované paměti. Možná by knihovna mohla blok zinicializovat
alespoň jinou hodnoutou, než je 0. Také jednoduchá funkce vypisující
zapomenuté bloky by se podle mého názoru hodila.
Díky trikům s mapováním stránek je snížena její portabilita
a pravděpodobně neexistuje verze pro DJGPP a jiné ne-UNIXové
platformy.
Celkově je ale libefence užitečná a jednoduchá knihovna,
která ušetří spostu starostí a tak ji můžu vřele každému doporučit.
Podle mého názoru je to dobrý kompromis mezi účiností a pracností.
Nevyžaduje žádné větši úsilí a nejčastější chyby najde.
Zdrojové kódy najdete na:
sunsite.ms.mff.cuni.cz/pub/Linux/devel/lang/c.
výheň