Jakie są najlepsze sposoby automatyzacji sesji debugowania GDB?
Czy GDB ma wbudowany mechanizm skryptowy, czy mam zakodować skrypt expect, czy jest jeszcze lepsze rozwiązanie?
Za każdym razem będę wysyłał tę samą sekwencję poleceń i będę zapisywał wyjście każdego polecenia do pliku(najprawdopodobniej używając wbudowanego mechanizmu logowania GDB, chyba że ktoś ma lepszy pomysł).
3 answers
gdb
wykonuje plik .gdbinit
Po uruchomieniu.
Możesz więc dodać swoje polecenia do tego pliku i sprawdzić, czy jest to dla Ciebie OK.
Jest to przykład .gdbinit
w celu wydrukowania backtrace dla wszystkich wywołań f()
:
set pagination off
set logging file gdb.txt
set logging on
file a.out
b f
commands
bt
continue
end
info breakpoints
r
set logging off
quit
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-25 05:13:45
Właśnie przechodziłam przez coś podobnego i wymyśliłam podstawowy przykład - i wiedząc, że wkrótce o tym zapomnę, pomyślałam, że lepiej to wrzucę :)
więc wrzucę to tutaj, ponieważ wygląda na związane z pytaniem.
Zasadniczo, w tym przykładzie chciałem uzyskać pewne wartości zmiennych w poszczególnych miejscach kodu; i mieć je wyjściowe, dopóki program się nie zawiesi. Więc tutaj jest najpierw mały program, który jest gwarantowane awarii w kilku krokach, test.c
:
#include <stdio.h>
#include <stdlib.h>
int icount = 1; // default value
main(int argc, char *argv[])
{
int i;
if (argc == 2) {
icount = atoi(argv[1]);
}
i = icount;
while (i > -1) {
int b = 5 / i;
printf(" 5 / %d = %d \n", i, b );
i = i - 1;
}
printf("Finished\n");
return 0;
}
Jedynym powodem, dla którego program akceptuje argumenty linii poleceń, jest możliwość wyboru liczby kroków przed awarią-i pokazania, że gdb
ignoruje --args
w trybie wsadowym. To kompiluję z:
gcc -g test.c -o test.exe
Następnie przygotowuję następujący skrypt - główną sztuczką jest przypisanie command
do każdego breakpoint
, co ostatecznie continue
(patrz również Automatyzacja gdb: show backtrace przy każdym wywołaniu funkcji puts ). Ten skrypt nazywam test.gdb
:
# http://sourceware.org/gdb/wiki/FAQ: to disable the
# "---Type <return> to continue, or q <return> to quit---"
# in batch mode:
set width 0
set height 0
set verbose off
# at entry point - cmd1
b main
commands 1
print argc
continue
end
# printf line - cmd2
b test.c:17
commands 2
p i
p b
continue
end
# int b = line - cmd3
b test.c:16
commands 3
p i
p b
continue
end
# show arguments for program
show args
printf "Note, however: in batch mode, arguments will be ignored!\n"
# note: even if arguments are shown;
# must specify cmdline arg for "run"
# when running in batch mode! (then they are ignored)
# below, we specify command line argument "2":
run 2 # run
#start # alternative to run: runs to main, and stops
#continue
Zauważ, że jeśli zamierzasz używać go w trybie wsadowym, musisz "uruchomić" skrypt na końcu, za pomocą run
lub start
lub czegoś podobnego.
Z tym skryptem w miejscu, mogę wywołać gdb
w trybie wsadowym-który wygeneruje następujące wyjście w terminalu:
$ gdb --batch --command=test.gdb --args ./test.exe 5
Breakpoint 1 at 0x804844d: file test.c, line 10.
Breakpoint 2 at 0x8048485: file test.c, line 17.
Breakpoint 3 at 0x8048473: file test.c, line 16.
Argument list to give program being debugged when it is started is "5".
Note, however: in batch mode, arguments will be ignored!
Breakpoint 1, main (argc=2, argv=0xbffff424) at test.c:10
10 if (argc == 2) {
$1 = 2
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$2 = 2
$3 = 134513899
Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17 printf(" 5 / %d = %d \n", i, b );
$4 = 2
$5 = 2
5 / 2 = 2
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$6 = 1
$7 = 2
Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17 printf(" 5 / %d = %d \n", i, b );
$8 = 1
$9 = 5
5 / 1 = 5
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$10 = 0
$11 = 5
Program received signal SIGFPE, Arithmetic exception.
0x0804847d in main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
Zauważ, że podczas gdy podajemy argument linii poleceń 5, pętla nadal obraca się tylko dwa razy( tak jak jest specyfikacja run
w skrypcie gdb
); jeśli run
nie miał żadnych argumenty, obraca się tylko raz (domyślna wartość programu) potwierdzając, że --args ./test.exe 5
jest ignorowany.
Jednak, ponieważ teraz jest to wyjście w jednym wywołaniu i bez żadnej interakcji użytkownika, wyjście wiersza poleceń może być łatwo przechwycone w pliku tekstowym za pomocą przekierowania
]}gdb --batch --command=test.gdb --args ./test.exe 5 > out.txt
Jest też przykład użycia Pythona do automatyzacji gdb w c-GDB auto stepping - automatyczny Wydruk linii, podczas wolnego biegu?
Hope this pomaga,
Zdrowie!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:46
Jeśli a-x z plikiem jest dla Ciebie za dużo, po prostu użyj opcji multiple-ex. jest to przykład do śledzenia uruchomionego programu pokazującego (i zapisującego) backtrace w przypadku awarii
sudo gdb -p $(pidof my-app) -batch \
-ex "set logging on" \
-ex continue \
-ex "bt full" \
-ex quit
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-21 20:38:40