Gdb'de uzun bir dizenin tam değerini nasıl yazdırabilirim?


376

GDB'de bir C-string'in tam uzunluğunu yazdırmak istiyorum. Varsayılan olarak kısaltılır, GDB'yi tüm dizeyi yazdırmaya nasıl zorlayabilirim?

Yanıtlar:


504
set print elements 0

GDB kılavuzundan :

set print elements number-of-elements
GDB dizisinin kaç öğesinin yazdırılacağı konusunda bir sınır belirleyin. GDB büyük bir dizi yazdırıyorsa, set print elementskomut tarafından ayarlanan sayıda öğe yazdırdıktan sonra yazdırmayı durdurur . Bu sınır dizelerin görüntülenmesi için de geçerlidir. GDB başladığında, bu sınırı 200 olarak ayarlanır Ayar numarası-of-the elemanları baskı sınırsız olduğunu sıfır araçlarına .

4
Günümüzde ayrıca "baskı tekrarlarını 0 ayarla" seçeneğine de ihtiyacınız olabilir, aksi takdirde GDB dizenin / dizinin tekrarlanan öğelerini atlayacaktır.
John Lindgren

bu durum aynı zamanda dizi türleri için de geçerlidir
Trevor Boyd Smith

1
Ayrıca "maks. Değer-boyutu sınırsız" ayarlamanız gerekebilir.
ams

100

Programınız aklı başında olduğu sürece, call (void)puts(your_string)stdout'a da yazdırabilirsiniz. Aynı ilke, hata ayıklayıcı tarafından kullanılabilen tüm işlevler için de geçerlidir.


2
Bu cevap, "benim için" yazdırma öğelerini 0 olarak ayarla "dan daha iyidir, çünkü satır başı yerine satırsonu / satırbaşı karakterlerine saygı duyar.
mhenry1384

6
İyi bir çözüm, ancak çekirdek dökümü dosyasını analiz etmeye çalışırken çalışmıyor
Elalfer

Parlak öneri duskwuff, keşke ben kaçtı çıktı almak için bir printf çağrı içine kopyalayıp yapıştırmadan önce okumuştu ..: D
nevelis

4
Not: Bu seçenek yalnızca canlı bir programda hata ayıklarsanız çalışır. Bir çekirdek dosyada hata ayıklarken GDB'nin "çağrı" komutunu kullanamazsınız.
Solomon Slow

1
ayrıca gdb'nin aklı başında olmasını gerektirir, ki bu giderek artan bir şekilde DEĞİLDİR (Mac OS X makinemde "Hiçbir sembol" mevcut bağlamda "koymuyor")
Michael

39

Üçüncü bir seçenek daha vardır: Genel bir ayarı değiştirmek yerine belirli komut için farklı bir sınır belirlemenize izin veren x komutu. Bir dizenin ilk 300 karakterini yazdırmak için kullanabilirsiniz x/300s your_string. Çıktıyı okumak biraz daha zor olabilir. Örneğin, bir SQL sorgusu yazdırıldığında şunlar ortaya çıkar:

(gdb) x / 300sb stmt.c_str ()
0x9cd948: "SELECT article.r" ...
0x9cd958: "mahalleden borçlu" ...
..

3
"X / 300sb" nin ne anlama geldiğini merak ediyordum. Bu hile sayfasının (pdf) yardımıyla, "x / 300sb cstr" i "null sonlandırılmış dize (S) olarak yorumlanan" cstr adresindeki eXamine 300 birim (Bayt) bellek olarak tercüme ettim. " Dizenizin uzunluğu 100 ise, çok fazla çöp görürsünüz, çünkü mantıklı olsun veya olmasın 300 baytın tamamı yazdırılır. Yine de +1 beni tanıştırdığı için x!
Rob W

39

printfKomut tam dizeleri yazacaktır:

(gdb) printf "%s\n", string

2
üzgünüm ama bu doğru değil
UmNyobe

11
Bu, set print elements nnnsınıra uyuyor gibi görünüyor ve siz bunu yapmadığınız sürece dizenin tamamını yazdırmayacak set print elements 0.
Mark Lakata

3
Bunu denediğimde sadece şunu alırım: "Değer tamsayıya dönüştürülemez."
Philipp Ludwig

2
std :: string için "Değer tamsayıya dönüştürülemez" hatasını önlemek için string.c_str () gereklidir
Paul Childs

21

Sadece tamamlamak için:

(gdb) p (char[10]) *($ebx)
$87 =   "asdfasdfe\n"

Bir uzunluk vermelisiniz, ancak bu dizenin temsilini değiştirebilirsiniz:

(gdb) p/x (char[10]) *($ebx)
$90 =   {0x61,
  0x73,
  0x64,
  0x66,
  0x61,
  0x73,
  0x64,
  0x66,
  0x65,
  0xa}

Değerlerine göre hata ayıklamak istiyorsanız bu yararlı olabilir


1

Kullanmak set elements ...her zaman en iyi yol değildir. Farklı olsaydı faydalı olurdu set string-elements ....

Bu nedenle, .gdbinit içinde bu işlevleri kullanın:

define pstr
  ptype $arg0._M_dataplus._M_p
  printf "[%d] = %s\n", $arg0._M_string_length, $arg0._M_dataplus._M_p
end

define pcstr
  ptype $arg0
  printf "[%d] = %s\n", strlen($arg0), $arg0
end

Uyarılar:

  • Birincisi, std :: string üyelerine eriştiği için c ++ lib bağımlıdır, ancak kolayca ayarlanabilir.
  • İkincisi yalnızca strlen adını verdiği için çalışan bir programda kullanılabilir.
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.