2009-08-25 5 views
6

Mam aplikację. Mam kod źródłowy (w C). Mogę to skompilować, tak, jak chcę. Dodaj dowolne narzędzie, jakie zechcę. Itd. Nie chcę jednak pieprzyć kodu źródłowego za pomocą pakietu printf. Chcę być w stanie utworzyć dziennik jakiegoś rodzaju, który pokazuje, kiedy zapisuje się konkretną wartość (na przykład jakiś element struktury globalnej) (zmienia jej wartość). Chciałbym móc pokazać plik źródłowy i numer linii oraz starą i nową wartość.pomoc ze śladami gdb (lub podobnymi)

Chciałbym również móc określić wartość według nazwy, a nie adresu. Ale adres jest OK. Punkty premiowe, jeśli mogę określić wartość lokalną dla funkcji.

Nadal drapię się w głowę, próbując odgadnąć polecenia śledzenia gdb. Każda pomoc jest bardzo doceniana. Dzięki.

Odpowiedz

1

Dziękuję zarówno @derobert, jak i @peter! W końcu wróciłem do tego i to:

break main 
commands 
     watch somevar 
     commands 
       cont 
     end 
     cont 
end 
run 

załatwia sprawę. Działa to, gdy "somevar" ma charakter globalny lub lokalny do "głównego". Jeśli "somevar" jest lokalny w stosunku do innej funkcji, po prostu zastąp "main" tą nazwą funkcji powyżej.

umieścić te polecenia w pliku (na przykład „gdbscript”) i uruchomić gdb jak:

gdb -x gdbscript a.out 
6

Najpierw musisz się upewnić, że skompilowałeś program z symbolami debugowania i prawdopodobnie bez optymalizacji, aby uczynić gdb najbardziej użytecznym. W przypadku gcc będzie to -g -O0.

Po drugie, funkcja, której szukasz, nie śledzi, jej punktów obserwacyjnych.

(gdb) help watch 
Set a watchpoint for an expression. 
A watchpoint stops execution of your program whenever the value of 
an expression changes. 

więc, biorąc pod uwagę niektóre przykładowy kod:

int main() { 
    int a; 
    a = 1; 
    a = 2; 
    return 0; 
} 

można następnie uruchomić gdb na nim, oraz:

(gdb) b main 
Breakpoint 1 at 0x80483a5: file test.c, line 4. 
(gdb) run 
Starting program: /tmp/test 

Breakpoint 1, main() at test.c:4 
4    a = 1; 
(gdb) watch a 
Hardware watchpoint 2: a 
(gdb) c 
Continuing. 
Hardware watchpoint 2: a 

Old value = -1207552288 
New value = 2 
main() at test.c:8 
8    return 0; 

to działa nieco śmieszne ze względu na istotę na stosie, nie pamięci. A gdyby była włączona optymalizacja, działałaby jeszcze mniej: zoptymalizowano by ją.

+1

Spróbuj uznającą '' A' jako lotnego int', które mogą sprawić, że przykład działać lepiej. – caf

+0

Dzięki derobert. Z tego, co rozumiem na temat zegarków, wynika, że ​​powodują one, że wykonanie programu ustaje, dopóki użytkownik "nie kontynuuje". Na pewno mógłbym napisać skrypt, aby to zrobić, ale czy jest jakiś sposób, aby zrobić to automatycznie z poziomu gdb? – tvaughan

+0

@tvaughan: Nie wiem o automatycznym sposobie zrobienia tego w gdb. – derobert

3

Jak już powiedziano, musisz ustawić punkt obserwacyjny na swojej zmiennej.

użyć komendy „Polecenia”

(gdb) help commands 
Set commands to be executed when a breakpoint is hit. 
Give breakpoint number as argument after "commands". 
With no argument, the targeted breakpoint is the last one set. 
The commands themselves follow starting on the next line. 
Type a line containing "end" to indicate the end of them. 
Give "silent" as the first line to make the breakpoint silent; 
then no output is printed when it is hit, except what the commands print. 

więc znaleźć numer watchpoint z poleceniem zegarek, i zrobić to (zakładając, że zegarek jest druga przerwa)

(gdp) commands 2 
> print a 
> cont 
> end 

Zakładając a jest żądaną zmienną. Możesz pominąć linię drukowania, jeśli jesteś zadowolony z wyników uzyskanych przez gdb.

Możesz także użyć poleceń z oryginalnego punktu przerwania, aby ustawić punkt obserwacyjny i kontynuować.