2012-07-23 24 views
38

He seguido las instrucciones on the GDB wiki para instalar las lindas impresoras python para ver los contenedores STL. Mi ~/.gdbinit ahora se ve así:Cómo imprimir bastante los contenedores STL en GDB?

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

Sin embargo, cuando corro BGF e intentar imprimir un tipo STL, me sale el siguiente:

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

¿Alguien puede arrojar algo de luz sobre esto? Estoy ejecutando Ubuntu 12.04, que viene con GDB 7.4.

+5

Podría ser simplemente que la biblioteca C++ ha cambiado sus tipos internos y variables de miembros, y el módulo de Python no se ha mantenido al día. –

+0

¿Podría pegar más información, como la fuente C++, las opciones del compilador, etc.? Acabo de probar esto en Ubuntu 12.04 y funciona para mí. – user1202136

+0

Funciona para mí con Fedora 17. – Omnifarious

Respuesta

1

Creo que está utilizando una biblioteca STL no GNU, o posiblemente una GCC libstdc++ muy antigua. El tipo de cadena de STL normal en mi compilador es: std::basic_string<char, std::char_traits<char>, std::allocator<char> >. Tenga en cuenta que esto no es std::basic_string<char>.

código Python tiene esto en él:

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

Esta Busque un tipo anidado ::Rep de cualquiera que sea el tipo de cadena de base que realmente es. El mensaje de error indica que la clase de cadena de cualquier biblioteca extraña que esté utilizando en realidad no tiene un tipo anidado ::Rep.

7

Usted puede tratar con más adelante BGF macro (añadirla a su archivo ~ /.gdbinit) para imprimir los tipos de datos STL containter e incluso sus miembros de datos: https://gist.github.com/3978082

2

Si escribe info type _Rep después de que el pitón excepción, gdb le informará sobre las clases cargadas que coinciden con _Rep. Esa lista podría ayudarlo a encontrar por qué python no puede encontrar su std::string class.

Acabo de enfrentar su problema y en mi caso fue Intel c compiler, icc, quien rompió la impresión bonita. En particular, el nombre de la CPI no calificado para std::string resultados en:

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

pero bastante impresora buscaba sin reservas nombre gcc:

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

Lo que hice para resolver mi problema estaba modificando la clase StdStringPrinter en printers.py , agregando el nombre no calificado de la cadena al nombre de tipo para buscar en gdb. Sustitución de la línea:

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

con esto:

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

Con la lista obtenida de info type se podía arreglar sus impresoras bonitas para hacer que funcionen.

0

Corrí este problema y golpeé esta página mientras trataba de resolverlo. Finalmente lo arreglé y pensé que valdría la pena compartir mi experiencia.

Estoy usando gcc-5.2, así que descargué la versión de gcc-5-branch de la impresora bonita desde el repositorio svn.Sin embargo, he tenido que hacer estas dos modificaciones:

1) al editar el archivo .gitinit, la adición sugerida es

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 

Sin embargo, tuve que comentar la línea register_libstdcxx_printers (None), ya que seguí recibiendo un error diciendome que los libstdcxx_printers ya estaban registrados. Aparentemente se registran durante la fase de importación.

2) Tuve que editar el archivo impresoras.py para std::set y std::map. Dado que el tipo _Rep_type es privado en ambos. En particular, reemplazo la rutina children en std::map y std::set con la correspondiente en la versión de la impresora bonita de la versión gcc-4_6-branch en svn repo. No tengo ningún error desde entonces, y las cosas se imprimen muy bien ahora.

Espero que esto ayude.

0

Simplemente funciona en Ubuntu 17,04

Debian parece tener las cosas finalmente integrados adecuadamente ahora:

#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)); 
} 

de compilación:

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

Resultado:

(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} 

podemos ver que la impresora prácticamente se instala con:

info pretty-printer 

que contiene las líneas:

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

Las impresoras están provieded por el archivo:

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

que viene con el paquete de biblioteca principal de C++ libstdc++6 y se encuentra debajo de libstdc++-v3/python/libstdcxx en el código fuente de GCC: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

TODO: ¿cómo GDB encuentra que el archivo es el misterio final, no está en mi ruta de Python: python -c "import sys; print('\n'.join(sys.path))" por lo que debe estar codificado en alguna parte?

0

errores como usted post anterior suele aparecer cuando el programa es LLVM-build (compilado por clang), y que tratan de depurar por gdb (que debe ser usado para los programas de GCC-build). En teoría, el programa de compilación LLVM se puede depurar por gdb, y viceversa. Pero para evitar problemas como los publicados anteriormente, debe usar lldb si usa clang, y debe usar gdb si usa g++.

Cuestiones relacionadas