2008-11-26 7 views
38

Chciałbym napisać skrypt, który (pod pewnymi warunkami) wykona gdb i automatycznie uruchomi jakiś program X z pewnym zbiorem argumentów Y. Po zakończeniu programu użytkownik powinien pozostać przy monitorze gdb, dopóki s/on nie wyjdzie z niego wyraźnie.Wywołuj gdb, aby automatycznie przekazywał argumenty do debugowanego programu

Jednym ze sposobów, aby to zrobić byłoby mieć wysłanie danych polecenia run plusa argumenty Y do jakiegoś pliku F, a następnie mieć gdb skryptu invoke takiego:

gdb X < F 

Ale czy istnieje sposób, aby zrobić to bez wprowadzenia pliku tymczasowego?

Dzięki.

Odpowiedz

26

Jeśli chcesz uruchomić kilka poleceń poprzez GDB a następnie go zamknąć lub uruchomić do końca, po prostu zrób

echo commands | gdb X 

Jeśli chcesz zostawić je w wierszu polecenia po uruchomieniu tych poleceń, można to zrobić

(echo commands; cat) | gdb X 

wynika to w echo poleceń do GDB, a następnie wpisać w procesie cat, który kopiuje jego standardowego wejścia na standardowe wyjście, które jest potokiem do GDB.

+1

(echo "uruchom params"; cat) | gdb X; # pracował uczta, wielkie dzięki! –

+2

Pamiętaj, że jeśli to zrobisz, stracisz interaktywność powłoki (wszystkie funkcje edycji, historii itp.). – ijw

+0

Po prostu zauważyłem, że góra/dół nie działa. Nie jest to dopuszczalne rozwiązanie :( – Nils

0

cat F | gdb X powinny być identyczne. Więc możesz użyć wszystkiego, co produkuje wyjście i potok, który do gdb zamiast polecenia cat tutaj.

Zakładam, że masz rację i gdb czyta ze standardowego wejścia.

85

Najłatwiej to zrobić biorąc pod uwagę program X i listę parametrów a b c:

X a b c 

Czy używać gdb „s --args opcja, jak następuje:

gdb --args X a b c 

gdb --help ma to powiedzieć o --args:

--args Arguments after executable-file are passed to inferior

co oznacza, że ​​pierwszy argument po --args jest wykonywalny do debugowania, a wszystkie argumenty, które są przekazywane po jak do tego pliku wykonywalnego.

+0

Miałem jeden przypadek użycia, w którym powiedzmy, że funkcja foo (a , b, c) (dowolny typ danych), to ma wywołanie powiedzmy main(), teraz chcę wprowadzić te argumenty jeszcze zanim zacznę wykonywać program.Czy możemy to osiągnąć? – KedarX

+0

@Kedar: Nie w ten sposób. Metoda określa argumenty przekazywane do 'main()' .To zależy od ciebie, aby przenieść je poprawnie do 'foo'. –

+0

OK, które sprawiają, że moja wątpliwość jest jasna, że ​​nie ma możliwości, abyśmy mogli podawać argumenty do dowolnej wewnętrznej metody wewnątrz głównej (chyba że zrobione niektóre przez przeniesienie)! Dzięki @Nathan Fellman – KedarX

1
gdb target -e "my-automation-commands" 

my-automatyki-komendy zawierające cokolwiek byś normalnie chcesz uruchomić,

break 0x123 
set args "foo" bar 2 
r 

Nie ściśle plik temp, jeśli masz kilka standardowych skryptów startowych;)

8

istnieje opcja -x, np.

gdb -x gdb_commands exe_file 

gdzie gdb_commands może być na przykład (w przypadku android emulator):

target remote :5039 
+2

Zwróć też uwagę, że jeśli chcesz uniknąć używania pliku tymczasowego, możesz użyć podstawienia procesu: 'gdb -x <(komendy echo) exe_file' –

+1

Po prostu użyj 'gdb -ex 'foo' -ex 'bar'', aby uruchomić gdb za pomocą poleceń' foo', a następnie 'bar'. – zopieux

1

Cóż, to tylko komentarz, naprawdę nie odpowiedź - po prostu chciałem to trochę kodu snippets. Jestem na bash/Ubuntu Lucid - i dla mnie miałem takie same problemy jak w: "GDB has problems with getting commands piped to STDIN - Unix Linux Forum - Fixunix.com".

Zasadniczo chciałbym osiągnąć takie same, jak w poniższym przykładzie:

$ gdb 
GNU gdb (GDB) 7.1-ubuntu 
Copyright (C) 2010 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "i486-linux-gnu". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
(gdb) pwd 
Working directory /media/work/dir. 
(gdb) 

... z wyjątkiem, chciałbym komenda „rura” pwd jakoś, a potem trzymać otwarte gdb (jak w powyższym przykładzie).

Próbowałem niektóre z propozycji tutaj, a jedyną rzeczą, pracuje dla mnie jest składnia (echo commands; cat) | gdb - a także (nieco roboczy) Here Strings - oto moje wyniki:

$ echo "pwd" | gdb 
(gdb) Hangup detected on fd 0 
error detected on stdin 


$ echo "pwd" | gdb -x /dev/stdin 
GNU gdb (GDB) 7.1-ubuntu 
... 
/dev/stdin: Invalid argument. 
(gdb) Hangup detected on fd 0 
error detected on stdin 


$ gdb -x <(echo "pwd") 
GNU gdb (GDB) 7.1-ubuntu 
... 
/dev/fd/63: No such file or directory. 
(gdb) q 


$ gdb -e "pwd" 
GNU gdb (GDB) 7.1-ubuntu 
... 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>. 
(gdb) q # nothing happens 


$ gdb <<<"pwd" 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) quit # OK, but autoexits 


$ gdb <<<"pwd 
> " 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) Working directory /media/work/dir. 
(gdb) quit # with a line break at end, it execs twice, then exits 


# the only one OK for my needs - 
# except locks after quit, and needs Ctrl-C 
$ (echo "pwd"; cat) | gdb 
GNU gdb (GDB) 7.1-ubuntu 
... 
(gdb) Working directory /media/work/dir. 
(gdb) q 
^C 

Cóż, nadzieja to pomaga komuś,
Pozdrawiam!

 
Edit: Teraz przynajmniej wiem, dlaczego podstawienie proces nie zadziała - będzie korzystał tymczasowy deskryptor pliku, który nie może być uznany jako plik przez ls (zatem gdb pewno nie można go odczytać; dodatkowo, odniesienie znika niemal natychmiast, chyba że proces jest w jakiś sposób zablokowany, ponieważ z cat) - zobacz terminala fragment dziennika:

$ echo -e "***\n" <(echo "pwd") "\n***\n`cat <(ls -C /dev/fd ; echo; for ix in /dev/fd/*; do irl=$(readlink -f $ix); echo $ix -\> $irl; ls -la $ix 2>&1; ls -la $irl 2>&1; echo '______'; done ; ls -C /dev/fd)`" 

*** 
/dev/fd/63 
*** 
0 1 2 3 63 

/dev/fd/0 -> /dev/pts/0 
lrwx------ 1 user user 64 2010-11-07 21:18 /dev/fd/0 -> /dev/pts/0 
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0 
______ 
/dev/fd/1 -> /proc/10713/fd/pipe:[236191] 
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/1 -> pipe:[236151] 
ls: cannot access /proc/10713/fd/pipe:[236191]: No such file or directory 
______ 
/dev/fd/2 -> /dev/pts/0 
l-wx------ 1 user user 64 2010-11-07 21:18 /dev/fd/2 -> pipe:[236151] 
crw--w---- 1 user tty 136, 0 2010-11-07 21:18 /dev/pts/0 
______ 
/dev/fd/255 -> /proc/10721/fd/255 
ls: cannot access /dev/fd/255: No such file or directory 
ls: cannot access /proc/10721/fd/255: No such file or directory 
______ 
/dev/fd/3 -> /proc/10725/fd/3 
ls: cannot access /dev/fd/3: No such file or directory 
ls: cannot access /proc/10725/fd/3: No such file or directory 
______ 
0 1 2 3 

także góra/dół klucze nie działają z (echo commands; cat) | gdb, bo to jest jak kot zachowuje; jeśli po prostu uruchomić cat więc kopiuje stdin stdout, otrzymujemy:

$ cat # or `cat -`: and start pressing up/down keys - and get: 
^[[A^[[B^[[A^[[B^[[A^[[B^C 

Możesz spróbować włączyć tryb postaci surowej (lub wyłączyć buforowany/tryb gotowane) z stty -cooked, a następnie cat będzie zarówno napisz znaki jako ^[[A i przesuń kursor - niestety, w tym trybie Ctrl-C już nie działa, więc nie będzie można zamknąć w ten sposób cat ...

1

Z bash możesz stworzyć skrypt, który daje użytkownikowi podobne dane wejściowe do dowolnego wykonywalnego pliku wykonywalnego:

#!/bin/sh 
gdb X <<GDB_INPUT 
pwd 
run X a b c 
quit 
GDB_INPUT 
+1

Jak mogę sprawić, aby gdb działał dalej po tym, zamiast zamknąć? .. Tak więc: gdb -ex run --args prog arg ... wydaje się być lepszym podejściem – Alex

+0

Wystarczy usunąć polecenie "quit". – selalerer

4

Po wypróbowaniu wszystkich odpowiedzi tutaj,

  1. Echo/cat hack, podczas gdy mądry, łamie sporo ważnych cech gdb. Przede wszystkim wszystkie monity użytkowników są odbierane automatycznie (więc nie masz szansy na potwierdzenie potencjalnie niebezpiecznych operacji), a Ctrl + C (w celu zatrzymania procesu, który debugujesz) kończy zabijanie kota, więc nie możesz pogadaj z gdb po tym.
  2. Opcja -x powinna działać, ale nie mogłem jej uruchomić z moją wersją gdb i wymaga ona pliku tymczasowego.

Jednak okazuje się, można po prostu użyć -ex, tak:

gdb -ex "target remote localhost:1234" 

Można również określić -EX wiele razy, aby uruchomić wiele poleceń!

Powiązane problemy