web-gelistirme-sc.com

GDL'deki STL kapları nasıl güzel basılır

STL kaplarını görüntülemek için güzel python yazıcıları yüklemek için GDB wiki'de talimatlarını izledim. Benim ~/.gdbinit şimdi şöyle görünüyor:

python 
import sys 
sys.path.insert(0, '/opt/gdb_prettyprint/python') 
from libstdcxx.v6.printers import register_libstdcxx_printers 
register_libstdcxx_printers (None) 
end 

Ancak, GDB'yi çalıştırdığımda ve bir STL türü yazdırmayı denediğimde aşağıdakileri alıyorum:

print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.: 
$3 = 

Birisi buna ışık tutabilir mi? GDB 7.4 ile gelen Ubuntu 12.04'ü kullanıyorum.

40
Nick Hutchinson

STL kapsayıcı türleri verilerini ve hatta veri üyelerini yazdırmak için aşağıdaki GDB makrosu (~/.gdbinit dosyasına ekleyin) deneyebilirsiniz: https://Gist.github.com/ 3978082

9
Fei

Gcc versiyonunuzu kontrol edin. 4.7'den küçükse, başka bir printer.py dosyası kullanmanız gerekir. Dosyayı http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/ adresinden alın.

4
Bingfeng

Sadece Ubuntu'da çalışıyor 17.04

Debian nihayet işleri düzgün bir şekilde bütünleştirmiş görünüyor:

#include <map>
#include <utility>
#include <vector>

int main() {
    std::vector<int> v;
    v.Push_back(0);
    v.Push_back(1);
    v.Push_back(2);
    std::map<int,int> m;
    m.insert(std::make_pair(0, 0));
    m.insert(std::make_pair(1, -1));
    m.insert(std::make_pair(2, -2));
}

Derleme:

g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp

Sonuç:

(gdb) p v
$1 = std::vector of length 3, capacity 4 = {0, 1, 2}
(gdb) p m
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2}

Güzel yazıcının yüklendiğini görebiliriz:

info pretty-printer

Satırları içeren:

global pretty-printers:
  objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
  libstdc++-v6
    std::map
    std::vector

Yazıcılar dosya tarafından provoke edilir:

/usr/share/gcc-7/python/libstdcxx/v6/printers.py

ana C++ kitaplık paketi libstdc++6 ile birlikte gelir ve GCC kaynak kodunda libstdc++-v3/python/libstdcxx altında bulunur: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-reas/libstdc%2B%2B v3/python/libstdcxx/v6/printers.py # L244

TODO: GDB bu dosyanın son misteri olduğunu nasıl buldu, Python yolumda değil: python -c "import sys; print('\n'.join(sys.path))" yani bir yere kodlanmış olmalı?

Python istisnasından sonra info type _Rep yazarsanız, gdb size _Rep ile eşleşen sınıfları bildirir. Bu liste python'un neden std::string class'nuzu bulamadığını bulmanıza yardımcı olabilir.

Senin sorununla daha yeni karşılaştım ve benim durumumda oldukça baskıyı kıran intel c compiler icc. Özellikle, std::string için nitelenmemiş icc adı şöyle sonuçlanır:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep;

ancak güzel yazıcı nitelenmemiş gcc adını arıyordu:

std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;

Sorunumu çözmek için yaptığım şey, printers.py içindeki StdStringPrinter sınıfını değiştirmek ve dizgenin nitelenmemiş adını gdb'ye bakmak için typename eklemek oldu. Satırı değiştirme:

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()

bununla:

reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()

info type adresinden alınan listeyle, güzel yazıcılarınızı çalışması için düzeltebilirsiniz.

2
Manuel Núñez

Bu sorunu çözdüm ve anlamaya çalışırken bu sayfaya çarptım. Sonunda düzelttim ve deneyimimi paylaşmaya değeceğini düşündüm.

Gcc-5.2 kullanıyorum, bu yüzden güzel yazıcının gcc-5-dal sürümünü svn deposundan indirdim. Ancak, bu iki mod yapmak zorunda kaldım:

1) .gitinit dosyasını düzenlerken, önerilen ekleme

python
import sys
sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

Bununla birlikte, register_libstdcxx_printers (None) satırını yorumlamak zorunda kaldım, çünkü libstdcxx_printers'ın zaten kayıtlı olduğunu söylerken bir hatayla karşılaştım. Görünüşe göre ithalat aşamasında kayıt yaptırıyorlar.

2) std::set ve std::map için printers.py dosyasını düzenlemek zorunda kaldım. _Rep_type tipi her ikisinde de özel olduğundan. Özellikle, svn deposundaki gcc-4_6-dal versiyonundaki güzel yazıcı sürümünde std::map ve std::set rutin children rutini değiştirdim. O zamandan beri hiçbir hata yapmadım ve işler şu anda güzel bir şekilde basılıyor.

Bu yardımcı olur umarım.

2
bartgol

Dediğiniz linkte listelenen yöntemler yerine, here betiğini deneyebilirsiniz, 

Aşağıdaki gibi yapın:

1) Betiği /your/path 'a indirin. Örneğin, bazı adlara isim verin. your_name.conf.

2) Eğer yoksa, bir dizine bir ~/.gdbinit dosyası ekleyin.

3) source /your/path/your_name.conf'nuza bir satır ~/.gdbinit ekleyin.

4) gdb'yi yeniden başlatın. pvector öğesini deneyin

Yardım bilgilerini help pvector gibi komutlarla bulabilirsiniz.

Örneğin.

pvector vec 5      # Prints element[5] in vec
pvector vec 5 10   # Prints elements in range [5, 10] in vec. (5, 6, 7, 8, 9, 10)

FYI, script , fonksiyonu STL öğelerini basmak olan gdb'ye birkaç komut (pvector, plist, pmap vb.) Ekler. Ayrıca, bu şekilde Nice formatı vererek, print pretty ekler:

enter image description here

Ayrıca, STL öğelerinin tam olarak gdb'de nasıl erişildiğini öğrenmek istiyorsanız komutların kodunu okuyunuz. Kodda sır yok. ^ _ ^

Örneğin. vektörlere ._M_impl._M_start tarafından erişilir

p vec._M_impl._M_start + 4 # prints vec[4]

1
Scott Yang

GNU olmayan bir STL kütüphanesi kullanıyorsunuz ya da çok eski bir GCC libstdc++ kullanıyorsunuz. Derleyicimdeki normal bir STL dizesinin türü: std::basic_string<char, std::char_traits<char>, std::allocator<char> >. Bunun std::basic_string<char> olmadığını unutmayın.

Python kodu içinde:

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()

Bu, temel dizge türünün gerçekte ne olduğu gibi bir yuvalanmış tip ::Rep arar. Hata mesajı, kullandığınız garip kütüphanenin string sınıfının aslında ::Rep iç içe tipine sahip olmadığını gösterir.

1
Omnifarious

Yukarıda gönderdiğiniz gibi hatalar genellikle program LLVM-build (clang tarafından derlenir) olduğunda görünür ve gdb (gCC-build programları için kullanılması gerekir) ile hata ayıklamaya çalışırsınız. gdb tarafından hata ayıklanır ve bunun tersi de geçerlidir. Ancak, yukarıda belirtilen gibi sorunlardan kaçınmak için lldb kullanıyorsanız clang kullanmalı ve g++ kullanıyorsanız gdb kullanmalısınız.

0
Ans