gdb
Toto je starší verze dokumentu!
GDB
Příklady
Kdo zapísuje do proměné?
- cílem bylo zjistit, kdo mi přepisuje globální proměnou LogFacility, čimž program začal logovat do jiného souboru než jsem původně zamýšlel
- binárka by měla být zkompilovaná s debug symoboly
- spustění gdb a navěšení na běžící proces (s PID 2453)
# gdb (gdb) attach 2453
- po attach je program zastaven, je možné vypsat informace o současném stavu.
- Pozor! Program se po attach zastaví a čeká.
- backtrace - informace o volání a obsah zásobníku (zobrazený výpis je bohužel zrovna bez debug symbolů)
(gdb) bt #0 0x00002b3f9dd525a5 in gcheckglo4k () from /usr/cachesys/bin/libcachet.so #1 0x00002b3f9dd4f6ad in getloc () from /usr/cachesys/bin/libcachet.so #2 0x00002b3f9dd90350 in gsetjrn () from /usr/cachesys/bin/libcachet.so #3 0x00002b3f9dd8f7ce in gset () from /usr/cachesys/bin/libcachet.so #4 0x00002b3f9e0f3af2 in Cgset () from /usr/cachesys/bin/libcachet.so #5 0x00002b3f9da192ff in ZCdisp () from /usr/cachesys/bin/libcachet.so #6 0x00002b3f9e961668 in ?? () #7 0x000000000afd5738 in ?? () #8 0x00007fff00000000 in ?? () #9 0x00002b3f9e142e77 in ?? () from /usr/cachesys/bin/libcachet.so #10 0x0000000000000000 in ?? ()
- vypsání globálních/statických proměných začínajících na LogF
(gdb) info variables LogF All variables matching regular expression "LogF": Non-debugging symbols: 0x000000376a951120 LogFile 0x000000376a951124 LogFacility
- vypsání hodnoty proměné
(gdb) print LogFacility $1 = 8
- obsah proměné je možné přepsat (ale to teď není potřeba)
(gdb) set variable LogFacility = 24 (gdb) print LogFacility $2 = 24
- nastavíme watchpoint na proměnou LogFacility. Pokud někdo zapíše do proměné a hodnota se změní, program se zastaví.
watch LogFacility
- do watchpoint/breakpoint lze zadat libovolné příkazy, které se mají provést. Umožňuje to vypsat nepříklad informace o stavu programu nebo i něco změnit. Do příkazů lze psát přímo C kód. V mém případě jsem pouze potřeboval zjístit, kdo do proměné zapsal a pokračovat dál.
commands bt print LogFacility continue end
- nastavení watchpointu/breakpointu lze zkontrolovat pomocí
(gdb) info breakpoints
Num Type Disp Enb Address What
1 hw watchpoint keep y LogFacility
bt
print LogFacility
continue
- nyní by mělo stačit program odpauzovat a počkat na výsledek. GDB ale může běh programu zastavit i z jiných důvodů, jako například při chybě, signálu, …
- nejdříve jsem narazil na problém s vlákny. Program vytvářel několik vláken, ve kterých spouštěl pouze jednu funkci. Vlákno často skončilo dřív, než gdb stihl vyčíst informace o vlákně a zobrazoval chybu
[New Thread 0x7fe1aea75950 (LWP 26614)] Cannot get thread event message: debugger service failed
- řesení bylo vypnout zobrazování informací o threads (starší verze GDB nemusí podporovat)
set print thread-events off
- pak mi to vyskočilo po signal handleru
Program received signal SIGUSR1, User defined signal 1. 0x000000376a20fdd5 in __tls_get_addr () from /lib64/ld-linux-x86-64.so.2
- GDB vidí signály a může zastavit při signálu, vytisknout, poslat programu nebo schovat signál před programem
- aktuální stav signálu lze zjístit
(gdb) info signals Signal Stop Print Pass to program Description SIGHUP Yes Yes Yes Hangup SIGINT Yes Yes No Interrupt SIGQUIT Yes Yes Yes Quit SIGILL Yes Yes Yes Illegal instruction SIGTRAP Yes Yes No Trace/breakpoint trap ... SIGUSR1 Yes Yes Yes User defined signal 1 ...
- změnit chování lze takto
(gdb) handle SIGUSR1 nostop
Zdroje
gdb.1396509019.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)
