Nasıl argümanlar geçmek ve stdin bir dosyadan gdb çalıştırmak programına yönlendirmek için?


Yanıtlar:


136

Bağımsız değişkenleri runkomuta gdb içinden iletin.

$ gdb ./a.out
(gdb) r < t
Starting program: /dir/a.out < t

3
rkısa runve herhangi bir argüman ile takip edebilirsiniz. Bu soruda olduğu gibi, şöyle olabilir: r arg1 arg2 <fileya da olabilirrun arg1 arg2 <file
phyatt

Benim için işe yaramıyor. Sonra denedim $ gdb ./a.outo zaman benim (gdb) r < t arg1 arg2için iyi çalışıyor. Benim durumumda a.out = nft arg1 = import arg2 = json vet = file containing json rules
mystictot

410

Bunu yapabilirsiniz:

gdb --args path/to/executable -every -arg you can=think < of

Sihirli bit olmak --args .

runHata ayıklamayı başlatmak için gdb komut konsolunu yazmanız yeterlidir.


24
İlk başta bunu yanlış okuduğumu sanıyordum; garip --args çalıştırılabilir dosyadan önce gelir. Ama öyle!
Kaolin Fire

8
@Kaolin --args çalıştırılabilir dosyadan önce gelmelidir çünkü gdb için bir anahtardır. Sonra geldiyse, gdb hata ayıkladığınız yürütülebilir dosyaya aktarmak istediğiniz bir argümandan nasıl ayırt eder?
codehippo

9
@codehippo: Eh, belirtmedi eğer --argso zaman değil pek belirsiz yüzden yürütülebilir geçirilen herhangi argümanlar.
Orbit'te Hafiflik Yarışları

14
Geleneksel argv[0]olarak çalıştırılabilir dosyanın adı olduğu için tahmin ediyorum
Claudiu

3
bu, girişin gdbkendisini ofdosyaya yönlendirir ve gdb'nin komutları çalıştırmaya çalışmasına neden olur
unkulunkulu

4

Programınızı yeniden yönlendirme ve bağımsız değişkenlerle yürütmek için çıplak runkomut almak istiyorsanız gdb, şunları kullanabilirsiniz set args:

% gdb ./a.out
(gdb) set args arg1 arg2 <file
(gdb) run

Ben --argsparametre ile aynı davranışı elde gdbedemedim , şiddetle yönlendirmeler kaçar, yani

% 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
...

Bu aslında gdb'nin girdisini yönlendiriyor, burada gerçekten istediğimiz şeyi değil

% gdb --args echo 1 2 <file
zsh: no such file or directory: file

1

GDB'yi projenizde başlatın.

  1. Proje yürütülebilir dosyasını zaten derlediğiniz proje dizinine gidin. Gdb komutunu ve yürütülebilir dosyanın adını aşağıdaki gibi verin:

    gdb projectAraştırıcıadı

Bu, gdb'yi başlatır, aşağıdakileri yazdırır: GNU gdb (Ubuntu 7.11.1-0ubuntu1 ~ 16.04) 7.11.1 Telif Hakkı (C) 2016 Free Software Foundation, Inc. ............... .................................. "word" ile ilgili komutları aramak için "apropos word" yazın. ProjectExecutablename'den semboller okunuyor ... bitti. (Gdb)

  1. Programınızı çalıştırmadan önce kesme noktalarını ayarlamak istersiniz. Break komutu bunu yapmanızı sağlar. Main adlı işlevin başında bir kesme noktası ayarlamak için:

    (gdb) b ana

  2. (Gdb) istemine sahip olduğunuzda, run komutu çalıştırılabilir çalıştırmayı başlatır. Hata ayıkladığınız program herhangi bir komut satırı bağımsız değişkeni gerektiriyorsa, bunları run komutuna belirtirsiniz. Programımı "xfiles" dosyasında (proje dizinindeki "mulder" klasöründe) çalıştırmak istiyorsanız, aşağıdakileri yaparsınız:

    (gdb) r mulder / xfiles

Bu yardımcı olur umarım.

Yasal Uyarı: Bu çözüm benim değil, https://web.stanford.edu/class/cs107/guide_gdb.html adresinden uyarlanmıştır. Büyük olasılıkla gdb için kısa bir kılavuz Stanford Üniversitesi'nde geliştirilmiştir.


0

debugHata ayıklamak için herhangi bir komutun önüne yazmak iyi olmaz mıydıgdbKabuk düzeyinde ?

Altında bu fonksiyon. Hatta aşağıdakilerle çalışır:

"$program" "$@" < <(in) 1> >(out) 2> >(two) 3> >(three)

Bu, hiçbir şeyi kontrol edemediğiniz, her şeyin değişken olduğu, boşluklar, satır beslemeleri ve kabuk metakarakterleri içerebileceği bir çağrıdır. Bu örnekte, in, out, two, vethree zarar olmamalıdır rasgele diğer tüketen komutlar veya ürünün verileridir.

Aşağıdaki bashişlev gdbböyle bir ortamda neredeyse temiz bir şekilde çalışır [ 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 "$@";
}

Bunun nasıl uygulanacağına ilişkin örnek: Sadece yazın debug Önden yeterlidir:

Önce:

p=($'\n' $'I\'am\'evil' "  yay  ")
"b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

Sonra:

p=($'\n' $'I\'am\'evil' "  yay  ")
debug "b u g" "${p[@]}" < <(in) 1> >(out) 2> >(two) 3> >(three)

Bu kadar. Şimdi hata ayıklamak için mutlak bir beyinsiz gdb. Birkaç ayrıntı veya daha fazlası hariç:

  • gdbotomatik olarak kapanmaz ve bu nedenle siz çıkana kadar IO yönlendirmesini açık tutar gdb. Ama buna özellik diyorum.

  • İle kolayca argv0programa geçemezsiniz exec -a arg0 command args. Sonra: Bu hile yapmak gerekir takiben exec-wrapperdeğişime "execkarşı "exec -a \"\${DEBUG_ARG0:-\$1}\".

  • Normalde kapalı olan 1000'in üzerinde açık FD vardır. Bu bir sorunsa, 0<&1000 1>&1001 2>&1002okumak için değiştirin0<&1000 1>&1001 2>&1002 1000<&- 1001>&- 1002>&-

  • Paralel olarak iki hata ayıklayıcı çalıştıramazsınız. Başka bir komut tüketildiğinde /dev/tty(veya STDIN) sorunlar da olabilir . Bunu gidermek için değiştirin /dev/ttyile "${DEBUGTTY:-/dev/tty}". Diğer bazı TTY türlerinde tty; sleep infve sonra /dev/pts/60olduğu gibi hata ayıklamak için basılı TTY'yi (i. E. ) kullanın DEBUGTTY=/dev/pts/60 debug command arg... Shell'in Gücü, buna alış!

Fonksiyon açıklaması:

  • 1000<&0 1001>&1 1002>&2 ilk 3 FD'yi uzaklaştırır
    • Bu, 1000, 1001 ve 1002 FD'lerinin ücretsiz olduğunu varsayar.
  • 0</dev/tty 1>/dev/tty 2>&0geçerli TTY'nizi gösterecek şekilde ilk 3 FD'yi geri yükler. Böylece kontrol edebilirsiniz gdb.
  • /usr/bin/gdb -q -nx -nwkabuk üzerinde gdbçağırır çalışırgdb
  • -ex 'set exec-wrapper /bin/bash -c "exec 0<&1000 1>&1001 2>&1002 \"\$@\"" 1000 ve üstüne kaydedilmiş ilk 3 FD'yi geri yükleyen bir başlangıç ​​sarmalayıcısı oluşturur
  • -ex r kullanarak programı başlatır exec-wrapper
  • --args "$@" argümanları verilen şekilde geçirir

Kolay değil miydi?

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.