Zwykle uruchamiam program jako:
./a.out arg1 arg2 <file
Chciałbym debugować go za pomocą gdb.
Jestem świadomy tej set args
funkcjonalności, ale działa to tylko z wiersza polecenia gdb.
Zwykle uruchamiam program jako:
./a.out arg1 arg2 <file
Chciałbym debugować go za pomocą gdb.
Jestem świadomy tej set args
funkcjonalności, ale działa to tylko z wiersza polecenia gdb.
Odpowiedzi:
Przekaż argumenty do run
polecenia z poziomu gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.out
następnie (gdb) r < t arg1 arg2
który działa dobrze dla mnie. W moim przypadku a.out = nft
arg1 = import
arg2 = json
it = file containing json rules
Możesz to zrobić:
gdb --args path/to/executable -every -arg you can=think < of
Magiczna istota --args
.
Po prostu wpisz run
w konsoli poleceń gdb, aby rozpocząć debugowanie.
--args
nie ma żadnych argumentów przekazywanych do pliku wykonywalnego, więc nie jest to dwuznaczne.
argv[0]
jest to nazwa pliku wykonywalnego
gdb
samego wejścia do of
pliku i spowoduje, że gdb spróbuje wykonać z niego polecenia
Jeśli chcesz mieć nagie run
polecenie gdb
do wykonania programu z przekierowaniami i argumentami, możesz użyć set args
:
% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run
Nie byłem w stanie osiągnąć tego samego zachowania z --args
parametrem, gdb
zaciekle ucieka przed przekierowaniami, tj
% gdb --args echo 1 2 "<file"
(gdb) show args
Argument list to give program being debugged when it is started is "1 2 \<file".
(gdb) run
...
1 2 <file
...
Ten faktycznie przekierowuje wejście samego gdb, a nie to, czego naprawdę chcemy tutaj
% gdb --args echo 1 2 <file
zsh: no such file or directory: file
Uruchom GDB w swoim projekcie.
Przejdź do katalogu projektu, w którym skompilowałeś już plik wykonywalny projektu. Wydaj polecenie gdb i nazwę pliku wykonywalnego, jak poniżej:
gdb projectExecutablename
Uruchamia to gdb, drukuje następujące: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Copyright (C) 2016 Free Software Foundation, Inc. ............... .................................. Wpisz „apropos word”, aby wyszukać polecenia związane z „word” .. Odczytywanie symboli z projektuExecutablename ... gotowe. (gdb)
Przed uruchomieniem programu należy skonfigurować punkty przerwania. Polecenie break pozwala ci to zrobić. Aby ustawić punkt przerwania na początku funkcji o nazwie main:
(gdb) b główny
Po wyświetleniu monitu (gdb) polecenie Uruchom uruchamia plik wykonywalny. Jeśli program, który debugujesz, wymaga argumentów wiersza polecenia, podajesz je w poleceniu uruchomienia. Jeśli chcesz uruchomić mój program na pliku „xfiles” (który znajduje się w folderze „mulder” w katalogu projektu), wykonaj następujące czynności:
(gdb) r mulder / xfiles
Mam nadzieję że to pomoże.
Oświadczenie: To rozwiązanie nie jest moje, zostało zaadaptowane z https://web.stanford.edu/class/cs107/guide_gdb.html Ten krótki przewodnik po gdb został najprawdopodobniej opracowany na Uniwersytecie Stanforda.
Czy nie byłoby miło napisać debug
przed jakimkolwiek poleceniem, aby móc je debugować gdb
na poziomie powłoki?
Poniżej tej funkcji. Działa nawet z następującymi:
"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)
Jest to wywołanie, w którym nie można nic kontrolować, wszystko jest zmienne, może zawierać spacje, linie i metaznaki powłoki. W tym przykładzie in
, out
, two
i three
są dowolne inne polecenia, które pochłaniają i dane produkty, które nie może zostać poszkodowana.
Następująca bash
funkcja wywołuje gdb
prawie czysto w takim środowisku [ Gist ]:
debug()
{
1000<&0 1001>&1 1002>&2 \
0</dev/tty 1>/dev/tty 2>&0 \
/usr/bin/gdb -q -nx -nw \
-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" exec' \
-ex r \
--args "$@";
}
Przykład zastosowania: Po prostu wpisz debug
z przodu:
Przed:
p=($'\n' $'I\'am\'evil' " yay ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Po:
p=($'\n' $'I\'am\'evil' " yay ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)
Otóż to. Teraz debugowanie jest absolutnie oczywiste gdb
. Z wyjątkiem kilku szczegółów lub więcej:
gdb
nie kończy się automatycznie, a zatem utrzymuje przekierowanie we / wy otwarte do momentu wyjścia gdb
. Ale nazywam to funkcją.
Nie możesz łatwo przejść argv0
do programu tak jak w przypadku exec -a arg0 command args
. Następujący powinien wykonać tę sztuczkę: Po exec-wrapper
zmianie "exec
na "exec -a \"\${DEBUG_ARG0:-\$1}\"
.
Istnieją FD powyżej 1000 otwarte, które są normalnie zamknięte. Jeśli to jest problem, zmień 0<&1000 1>&1001 2>&1002
na „czytaj”0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-
Nie można uruchomić dwóch debuggerów równolegle. Mogą również występować problemy, jeśli jakieś inne polecenie zużywa /dev/tty
(lub STDIN). Aby to naprawić, wymienić /dev/tty
się "${DEBUGTTY:-/dev/tty}"
. W niektórych innych typach TTY, tty; sleep inf
a następnie użyj drukowanego TTY (i. E. /dev/pts/60
) do debugowania, jak w DEBUGTTY=/dev/pts/60 debug command arg..
. To jest Moc Powłoki, przyzwyczaj się do tego!
Funkcja wyjaśniona:
1000<&0 1001>&1 1002>&2
odsuwa pierwsze 3 FD
0</dev/tty 1>/dev/tty 2>&0
przywraca pierwsze 3 FD wskazujące na twoją obecną TTY. Więc możesz kontrolować gdb
./usr/bin/gdb -q -nx -nw
uruchamia gdb
wywołania gdb
na powłoce-ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\""
tworzy opakowanie startowe, które przywraca pierwsze 3 FD, które zostały zapisane do 1000 i więcej-ex r
uruchamia program za pomocą exec-wrapper
--args "$@"
przekazuje argumenty jak podanoCzy to nie było łatwe?
r
jest skrótemrun
i możesz podążać za nim z dowolnymi argumentami. Jak w tym pytaniu, byłoby to:r arg1 arg2 <file
albo mogłoby byćrun arg1 arg2 <file