Standart kapsayıcı (std :: harita) içeriğini gdb ile inceleme


93

Bunun gibi bir şeye sahip olduğunu varsayarsak:

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

Programı çalıştıran haritanın içeriğini gdb'den inceleyebilmek istiyorum.
Alt simge operatörünü kullanmayı denersem şunu elde ederim:

(gdb) p m[1]
Attempt to take address of value not located in memory.

Bul yöntemini kullanmak daha iyi sonuçlar vermez:

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

Bunu başarmanın bir yolu var mı?


Büyük haritaları kesmeden tüm öğeleri yazdırmak için: stackoverflow.com/questions/47743215/… Daha fazla "İşlev değerlendirilemiyor, satır içi olabilir" odaklı: stackoverflow.com/questions/40633787/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Yanıtlar:


35

Bence yok, en azından kaynağınız optimize edilmişse vs. Ancak, sizin için STL kaplarını inceleyebilecek gdb için bazı makrolar vardır:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

Ancak bunu kullanmıyorum, bu yüzden YMMV


1
Bağlantı için teşekkürler; tek şey, makroların kaçınmayı tercih ettiğim stl kitaplıkları sürümüne bağlı olmasıdır. +1
Paolo Tedesco

"Plist foo std :: string" gibi komutların sözdizimi hataları vermesi de biraz sinir bozucu. Görünüşe göre değer_türü herhangi bir noktalama işareti içeremez.
Bklyn

2
Denemedim, ancak bu GDB'nin geri kalanıyla aynı şekilde çalışıyorsa, adı tek tırnak içinde noktalanmış bir adla kapatmak bunu yapmalıdır.
jpalecek

2
Not: Bu komut dosyalarındaki std :: map işlevi 32 bitlik işaretçi türlerini varsayar. 64 bit makineler için, dosyanın her yerinde "+ 4" ü "+ 8" olarak değiştirin.
Kyle Simek

pvector gdb'mde tanımlı değil (sürüm 7.5.91.20130417-cvs-ubuntu).
Jeff

92

Bu soruya verilen mevcut cevaplar çok güncel değil. Yeni bir GCC ve GDB ile , GDB 7.x'te yerleşik Python desteği ve GCC ile birlikte gelen libstdc ++ güzel yazıcılar sayesinde it Just Works TM .

OP örneği için şunu alıyorum:

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

Otomatik olarak çalışmazsa , GDB wiki'sinin STL Desteği sayfasında ilk madde işaretini görürsünüz .

Kendi türleriniz için Python güzel yazıcılar da yazabilirsiniz , GDB kılavuzundaki Pretty Printing bölümüne bakın .


2
Evet, ancak diğer sorular yinelenen sorular olarak kapanıyor, bu yüzden son bilgilere sahip olmasını istedim.
Jonathan Wakely

1
GDB 7.2 kullanıyorum ve yukarıdaki işler ... küçük bir koleksiyonunuz varsa. STL uygulamasının dahili yapılarını kullanmaktan başka, bir 4K vektöründen öğe 1543'ü basmanın bir yolunu hala bulamadım.
2013

5
Evet, GDB 7.2 ve icpc derleyicisinde hatayı alıyorum Could not find operator[].
2013

11
Ne yazık ki tüm dağıtımlarda "Sadece Çalışıyor" değil. Varsayılan olarak Ubuntu
13.10'da kurulu

1
@razeh, Fedora, RHEL (ve RHEL klonları). Yazıcıların
GDB'nin

25

Her zaman bariz olan vardır: Kendi test işlevinizi tanımlayın ... Bunu gdb'den arayın. Örneğin:

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

Ve:

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb) 

16
işlem devam ettiği sürece. çekirdek dökümler için pek kullanışlı değil.
sean riley

2
Bu, yalnızca STL ile değil, genel olarak GDB'de hata ayıklama için yararlı bir tavsiyedir. Geri getirilmesi zor birçok veri için gdb yardımcı işlevlerinin bütün bir kitaplığını tutuyorum, örneğin write_cuda_array_as_image (). Bazı derleyicilerin çağrılmayan tüm işlevleri çıkaracağına dikkat edin, bu nedenle ana işlevimin "return 0;" dan sonra her yardımcı işlevi çağırırım. Ayrıca onları extern "C" ile bildirmek onları gdb'den çağırmayı kolaylaştırır.
Kyle Simek

21

stl-views.gdbAma artık yoktu iyi cevabı olurdu.

Bu GDBhenüz ana hatta entegre edilmedi, ancak işte 'okçu-tromey-piton' dalını kullanarak elde ettiğiniz şey :

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit


1

Yukarıdaki cevaplar işe yarıyor ve iyi. Stl-views.gdb kullanıyorsanız, buradaki haritaları ve içindeki unsurları görüntülemenin doğru yolu. Haritanız aşağıdaki gibi olsun: std::map<char, int> myMap;

(gdb) pmap myMap char int

yani pmap <variable_name> <left_element_type> <right_element_type>haritadaki öğeleri görmek için.

Umarım yardımcı olur.


0

İkinci problemi ( Cannot evaluate function -- may be inlined), programınızı derlerken derleyicinizin DWARF-2 (veya 3 veya 4) hata ayıklama bilgilerini kullandığından emin olarak aşabilirsiniz. DWARF-2 satır içi bilgi içerir, bu nedenle std::mapkapsayıcınızın öğelerine erişmek için tanımladığınız yöntemlerden birini kullanabilmelisiniz .

DWARF-2 hata ayıklama bilgisiyle -gdwarf-2derlemek için derleme komutunuza bayrağı ekleyin .


1
Um, bir fonksiyonun nerede satır içinde olduğunu bilmek, GDB'nin o fonksiyona yapılan çağrıları değerlendirmesini mümkün kılmaz; GDB'nin işlevin satır dışı bir kopyasına gerçekten erişmesi gerekiyor!
SamB
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.