280 likes | 365 Views
Debugov ání v C/C++. Co musíme však nejdříve udělat?. Přeložit program s debug informacemi Umožníme přidáním volby –g do překladače POZOR!!! Pokud se program skládá z více modulů ( .o souborů) je potřeba přidat volbu –g při tvorbě každého takového modulu.
E N D
Co musíme však nejdříve udělat? • Přeložit program s debug informacemi • Umožníme přidáním volby –g do překladače POZOR!!! Pokud se program skládá z více modulů ( .o souborů) je potřeba přidat volbu –g při tvorbě každého takového modulu
Co by jsme naopak dělat neměli • Debugovat programy které jsme prohnali přes optimalizující překladač • Tj. pokud budu debugovat tak nepřidávám volbu –o ( a už vůbec ne -o2 -o3 ) • Pokud tak učiníme tak debugovaný program bude odlišný od toho který máme před sebou ve zdrojovém textu
Rozdíl debbugování v C oproti C++ • C++ umožňuje používat šablony. Tj. při pádu programu přidává i názvy šablon • C++ umožňuje dědičnost a špatně se dohledává pokud je chyba ve virtuální destruktoru některé z nadřezených tříd • Debuggování v C++ je tudíž trošku těžší a někdy velice nepřehledné
Jaké máme možnosti ? • Debugovat ze souboru vzniklých při pádu programu • Debugovat přímo spuštěný program
Debugování z core-dumpu 1 • Musíme nejdříve donutit OS tvořit core-dumpy - Zvládneme pomocí příkazu “ulimit –c unlimited“ - Příkaz “ulimit“ má spoustu dalších užitečných vlastností ( změna počtu vláken, max. procesorového času apod.)
Debugování z core-dumpu 2 • Po spadnutí programu se nám nyní vytvoří soubor core( číslo procesu ) • Tento soubor můžeme nyní předhodit debbugeru a podívat se kde se stala chyba • Provedeme pomocí: gdb ( název programu ) ( coredump )
Debugování z core-dumpu 3 • Nyní když jsme v debbugeru tak vidíme řádek na kterém se stala chyba • Zadáme teda příkaz “bt“ ať vídíme kde přesně se stala chyba a jaké volání funkcí jí předcházelo
Debugování z core-dumpu 4 • Další příkazy které se mohou hodit • ptype ( typ proměnné ) • print ( název proměnné nebo výraz ) • set print pretty print struktura->jmeno p pole[3]@5 • list
Debugování z core-dumpu 5 Pozitiva + Nezdržujeme běh programu debbugerem + Debbugujeme až když skutečně víme, že něco spadlo Negativa - Né každý pád programu tvoří coredump ( např. signál pipe ) - Z coredumpu debbuger nikdy nezíská tolik informací jako přímo při běhu programu
Debugování za běhu 1 • Můžeme používat přímo a nepotřebujeme k němu žádný coredump • Musíme však počítat s někdy mnohonásobně větší zátěží při běhu programu
Debugování za běhu 2 - GDB • Možnost číslo 1 – použijeme gdb • Tuto možnost velice nedoporučuju. Osobně používám na debugování gdb v “bojových situacích“ • Podíváme se teda na pár užitečnách příkazů které můžou pomoc
Debugování za běhu 3 - GDB • Nejdříve spustíme program pod gdb gdb ( název programu) • Takto spuštěný program je zatím zastavený. Spustíme ho tedy příkazem run ( argumenty z příkazové řádky )
Debugování za běhu 4 - GDB • Breakpointy • break ( číslo řádky ) • break ( název funkce ) • clear ( číslo řádky / název funkce ) • Info breakpoints • Krokování • next • continue
Debugování za běhu 5 - strace • Strace je prográmek který nám sobrazuje veškeré systémové volání • Hodí se tedy pokud chceme vyzkoumat co program volal a s jakými argumenty a nebo kvůli čemu a kde dostal signál • Pokud tušíme, že nám program zhodil nějáký signál je toto nejlepší program na nalezení problému
Debugování za běhu 6 • Všechny předchozí programy jsou užitečné ale nezobrazují všechny užitečné informace. • Např. Nevíme kde jsme uvolnili proměnnou do které jsem se pak pokusili něco napsat • Nekontolují memory-leaky apod.
Debugování za běhu 6 - strace • Použití strace ( název programu ) • Na obrazovce pak uvidíme postupně všechna volání i s parametry
Debugování za běhu 7 - valgrind • Valgrind je užitečný prográmek který kontroluje veškeré operace s pamětí • Odborně – Program na kontrolu konzistence heapu • Asi nejlepší ze všech programů na debugování • Bohužel zatím použitelný jen pod Linuxem
Debugování za běhu 7 - valgrind • Program není ve standratní knihovně a porot ho musíme stáhnout z internetu • Např z. www.valgrind.org • apt-get install valgrind ( Debian ) • yum install valgrind ( Red Hat )
Debugování za běhu 8 - valgrind • Program se skládá z několika částí kde každá se soustředí na jiný druh problémů • Nejvíce používané jsou • error-check • leak-check
Debugování za běhu 9 - valgrind • Pokud valgrind spustíme bez jakýchkoliv parametrů tak použijeme modul pro kontrolu chyb • Použití valgrind ( název programu )
Debugování za běhu 10 - valgrind • Ve výpise se nám pak zobrazí chyby • Proměnné bez defaultních hodnot • Dvojí uvolnění paměti • Zápis mimo paměť • Přepis paměti • Zápis do paměti kterou jsme nealokovali
Debugování za běhu 10 - valgrind • Nejlepší je, že valgrind nám i ukáže proč k chybě došlo! • Například pokud zapisujeme do předtím uvolněné paměti tak nám i ukáže místo kde jsme jí uvolnili • Pokud zapisujeme mimo alokovanou oblast tak nám ukáže o kolik jsme se přepsali a kde máme zaalokovat více místa
Debugování za běhu 11 - valgrind • Dalším skvělým modulem je kontrola memory-leaků • Stačí spusti valgrind s jinou volbou valgrind --leak-check=full ( název programu ) • Valgrind nám nyní ukáže všechnu paměť kterou jsme alokovali ale neuvolnili a taky paměť na kterou se již nemůžeme dostat
Debugování za běhu 12 Pozitiva + Máme mnohem více informací + Můžeme ovlivňovat chování programu + Valgrind ;) Negativa - Běh s debbugerem je mnohonásboně náročnější než bez debbugeru
IDE • Další věc která se pro debugování hodí jsou různá IDE • Z vlastní zkušeností můžu doporučit Eclipse s pluginem pro C/C++ • Další skvělý nástroj je KDevelop který v sobě integruje strace/GDB/valgrind a spoustu dalších užitečných věcí
Shrnutí • Pokud jsem si jistý, že v programu už nemám chybu tak mi stačí ladění z coredumpu • Pokud potřebuju ladit intenzivně tak nechám běžet program pod debbugerem