Uživatelské nástroje

Nástroje pro tento web


gdb

Toto je starší verze dokumentu!


GDB

Výpis paměti

  • seznam dostupných proměnných na daném break pointu, lze zjistit pomoci info locals
  • vypsat hodnotu proměnné/struktury lze pomocí print nebo zkráceně p
  • výpis bloku paměti se dělá pomocí x
x/nfu addr
x addr
x 
  • přičemž:
    • n - počet prvků k vypsání (normálně číslo)
    • f - formát zobrazení (x - hexa, s - string, i - instrukce)
    • u - velikost (b bajt, h 2B, w 4B, g 8B)
    • addr - adresa v paměti (buď přímo nebo přes název proměnné. Lze použít i operátory */&)

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.1399385959.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki