Hlavní navigace

Valgrind - závěr

29. 5. 2003
Doba čtení: 5 minut

Sdílet

V poslední části se o valgrindu dozvíte vše důležité, co zatím nebylo řečeno :). Třeba to, že valgrind lze použít i na wine a tím pádem na programy psané ve Windows, dále si popíšeme skiny addrcheck, helgrind a cachegrind a vysvětlíme některá chybová hlášení.

Addrcheck

Skin addrcheck pustíme tak, že na příkazové řádce napíšeme --skin=addrcheck jako argument valgrindu.

Addrcheck je zjednodušená verze memchecku, o kterém jsme mluvili v předešlém dílu. Shoduje se s ním ve všem, až na fakt, že na rozdíl od memchecku nekontroluje, zda je hodnota proměnné definovaná. Znamená to, že addrcheck je přibližně dvakrát rychlejší než memcheck a používá méně paměti. Dokáže najít tyto chyby:

  • Čtení / zápis do paměti poté, co byla uvolněna
  • Čtení / zápis za konec alokovaných bloků
  • Čtení / zápis na nepatřičné místo v zásobníku
  • Memory leaks (místa v paměti, ke kterým natrvalo ztratíme přístup)
  • Neodpovídající si použití operátorů malloc / new / new[] a free / delete / delete []
  • Některá chybná použití POSIXových API vláken

Místo toho, abych zde přepisovala většinu toho, co jsem už řekla, odkážu vás na předešlý díl a budu se věnovat jenom rozdílům.

  • Addrcheck nekontroluje, zda je hodnota definovaná, proto jsou tzv. V-bity irelevantní, naproti tomu A-bity se využívají.
  • Addrcheck přijímá ty samé argumenty jako memcheck
  • Stejně jako memcheck, addrcheck umí najít memory leaks (je tam implementován stejný zdrojový kód).

Hlavní rozdíl je v tom, jak se tyto dva skiny rozhodují, které oblasti v paměti mají prohledat, když chtějí nalézt ukazatele k jednotlivým blokům. Memcheck prohledá jenom čtyřbytové uspořádané oblasti, které jsou adresovatelné a ve kterých jsou definované hodnoty. Addrcheck se nesnaží vypátrat, zda je hodnota definovaná, a tak jeho jediným kritériem je, aby byly byty adresovatelné. Výsledkem je to, že addrcheck může objevit ukazatele na bloky, které memcheck nemůže najít. Může se tedy stát, že memcheck (správně) prohlásí, že došlo v daném bloku k memory leaku, kdežto addrcheck k tomuto výsledku nedospěje. Zatím není jisté, zda tento fakt má, nebo nemá nějaký efekt v praxi. Autor je přesvědčen, že ne, ale diskuse není až tak jednoznačná :).

Chybové hlášky addrchecku nerozlišují zápisy od čtení. Výpisy vypadají třeba jako: „Invalid memory access of size 4“ (memcheck by řekl, zda jde o zápis, nebo čtení). Díky tomu, že se nedělají testy na to, zda je hodnota definována, nebo ne, je výstup čitelnější než u memchecku a je jednodušší sledovat chyby.

Protože je addrcheck rychlejší a „menší“ než memcheck, je použitelnější pro velké, ale méně detailní testování. Na počítači s 512MB RAM a s procesorem 1,7 GHz P4 je použitelný i výsledek z testování KDE-3.1.

Helgrind

Tento skin se spouští parametrem --skin=helgrind.

Helgrind je skin, který pomocí algoritmu Eraser detekuje neošetřené kritické sekce v C/C++ programech, které používají knihovnu pthreads. Je to stav, když na nějaké místo v paměti přistupuje více vláken. Helgrind si pamatuje, která vlákna přistupovala ke kterým datům, a udržuje si přehled o tom, jaký (pokud nějaký) mutex byl použit při přístupu k proměnným. Pokud nalezne alespoň jeden takový zámek, který používají všechna vlákna, kritická sekce je ošetřena. Pokud nelze zámek najít, zdá se, že pro tuto oblast neexistuje žádné konzistentní zabezpečení, a tak se může jednat o neošetřenou kritickou sekci.

Cachegrind

Cachegrind se používá s přepínačem --skin=cachegrind.
Je to nástroj, který simuluje cache a ke každému řádku zdrojového kódu připíše počet výpadků cache. Všímá si:

  • čtení a výpadků L1 instrukční cache
  • čtení, zápisů a výpadků z L1 datové cache
  • výpadků L2 cache

Na moderním x86 stroji je cena výpadku L1 přibližně 10 cyklů a výpadku L2 až 200 cyklů. Podrobná analýza výpadků cache tedy může zvýšit výkon vašeho programu.
Cachegrind vytiskne po skončení běhu programu statistiky cache. Všechny informace se ukládají do souboru cachegrind.out.pid, kde pid je číslo procesu valgrindu.
Lze získat i souhrnná data pro jednotlivé funkce, resp. pro jednotlivé soubory, pomocí dodávaného programu cg_annotate. Soubory, které mají být takto okomentovány, lze specifikovat přímo na příkazové řádce, nebo se můžeme spolehnout na přepínač --auto=yes, který pak přidá informace k „zajímavým“ zdrojovým kódům.

Cachegrind používá simulaci pro procesor s oddělenou L1 cache a spojenou L2 cache, což je nejběžnější konfigurace moderních x86 strojů.

Momentálně je ale cachegrind ve stavu, když není moc použitelný kvůli nasledujícím omezením:

  • Nepočítá s tím, že v systému může běžet více než jeden proces, takže zcela ignoruje efekt systémových volání na obsah cache.
  • Nesimuluje adresové mapování z virtuální do fyzické paměti.
  • Nebere ohled na výpadky cache, které nejsou na instrukční úrovni viditelné. Mám na mysli třeba výpadky TLB nebo spekulativní provádění instrukcí.
  • Vlastní funkce valgrindu malloc() alokuje paměť jiným způsobem než standardní malloc(), a to může zkreslovat výsledek.
  • Implementace plánování vláken ve valgrindu je jiná než ve skutečnosti, což způsobuje nepřesnosti ve výsledku při srovnání s reálným spuštěním programu.
  • Instrukce pro jednotku pracující s pohyblivou desetinnou čárkou, jejichž velikost je 28 nebo 108 bytů (např. fsave) jsou považovány za instrukce o délce 16 bytů. Tyto instrukce jsou ale používány velice zřídka, a tak by to neměly mít velký vliv na výsledek.

Dalším faktem je, že výsledky jsou všeobecně velmi „citlivé“. Stačí změnit velikost souboru valgrind.so, velikost profilovaného souboru nebo dokonce jenom délku jeho názvu a výsledky jednotlivých spuštění se budou lišit. I když budou tyto změny jenom velmi malé, nelze očekávat stejné výsledky po nějakých změnách v souborech. To celé znamená, že byste neměli věřit všem výsledkům, protože nejsou zcela přesné.

Chybová hlášení

Teď si popíšeme několik chybových výpisů valgrindu. Většina z nich se může objevit, jenom když program běží s parametrem -v (–verbose).

root_podpora

More than 50 errors detected. Subsequent errors will still be recorded,
but in less detail than before 
More than 300 errors detected. I'm not reporting any more. Final error
counts may be inaccurate. Go fix your program! 
Warning: client switching stacks? 
Warning: client attempted to close Valgrind's logfile fd <číslo> 
Warning: noted but unhandled ioctl <číslo> 
Warning: set address range perms: large range <číslo> 

Na závěr…

…si povíme o tom, že začátkem května programátoři valgrindu vypustili nový balíček valgrind-1.9.6-wine.tar.bz2, který umožňuje pouštět valgrind na Wine a ladit tak aplikace pro Windows.
Valgrind 1.9.6-wine bude pracovat s jakoukoliv aktuální CVS verzí Wine nebo s libovolným snapshotem vypuštěným od 8. dubna 2003. Za předpokladu, že spustitelné soubory mají formát PDB a DLL, valgrind rozumí callstacku kódu, zkompilovanému v MSVC. Vícevláknové programy jsou plně podporovány, momentálně ale nefunguje hledání memory leaků.

Tímto bych ukončila seriál o hledání chyb pomocí valgrindu. Doufám, že se vám líbil a naučil vás něco nového. Tento nástroj je sice relativně nový, ale získává si velkou oblibu u linuxových programátorů. Nám nezbývá než doufat, že se vývojářům podaří odstranit všechny nedostatky a možná i vymyslet něco nového, co by nám ulehčilo práci :).

Byl pro vás článek přínosný?

Autor článku

Seriál Valgrind