Zwykle uruchamiam program jako:
./a.out arg1 arg2 <file
Chciałbym debugować go za pomocą gdb.
Jestem świadomy tej set argsfunkcjonalnoś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 argsfunkcjonalności, ale działa to tylko z wiersza polecenia gdb.
Odpowiedzi:
Przekaż argumenty do runpolecenia z poziomu gdb.
$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t
$ gdb ./a.outnastępnie (gdb) r < t arg1 arg2któ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 runw konsoli poleceń gdb, aby rozpocząć debugowanie.
--argsnie ma żadnych argumentów przekazywanych do pliku wykonywalnego, więc nie jest to dwuznaczne.
argv[0]jest to nazwa pliku wykonywalnego
gdbsamego wejścia do ofpliku i spowoduje, że gdb spróbuje wykonać z niego polecenia
Jeśli chcesz mieć nagie runpolecenie gdbdo 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 --argsparametrem, gdbzaciekle 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ć debugprzed jakimkolwiek poleceniem, aby móc je debugować gdbna 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, twoi threesą dowolne inne polecenia, które pochłaniają i dane produkty, które nie może zostać poszkodowana.
Następująca bashfunkcja wywołuje gdbprawie 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 debugz 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:
gdbnie 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ść argv0do programu tak jak w przypadku exec -a arg0 command args. Następujący powinien wykonać tę sztuczkę: Po exec-wrapperzmianie "execna "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>&1002na „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/ttysię "${DEBUGTTY:-/dev/tty}". W niektórych innych typach TTY, tty; sleep infa 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>&0przywraca pierwsze 3 FD wskazujące na twoją obecną TTY. Więc możesz kontrolować gdb./usr/bin/gdb -q -nx -nwuruchamia gdbwywołania gdbna 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?
rjest skrótemruni możesz podążać za nim z dowolnymi argumentami. Jak w tym pytaniu, byłoby to:r arg1 arg2 <filealbo mogłoby byćrun arg1 arg2 <file