¿Cómo imprimo los elementos de un vector C ++ en GDB?

Respuestas:

79

Para ver el contenido de vector std :: vector myVector, simplemente escriba GDB:

(gdb) print myVector

Esto producirá una salida similar a:

$1 = std::vector of length 3, capacity 4 = {10, 20, 30}

Para lograr lo anterior, debe tener gdb 7 (lo probé en gdb 7.01) y alguna impresora bonita de Python. El proceso de instalación de estos se describe en gdb wiki .

Además, después de la instalación anterior, esto funciona bien con la GUI del depurador Eclipse C ++ (y cualquier otro IDE que use GDB, como creo).

Michał Oniszczuk
fuente
16
Esto funciona bien siempre que los elementos vectoriales sean directamente interpretables. Pero no ayuda si el vector contiene punteros a los elementos de interés.
wallyk
Francamente, no encuentro la página de gdb wiki particularmente legible, ¿tal vez porque está "un poco" desactualizada ahora? Por ejemplo, tuve la impresión de que el contenido sugerido de la $HOME/.gdbinitera necesaria. En este momento termino sin tal archivo y gdbmostrando correctamente el contenido de std::vector. Sin embargo, dado que durante mis intentos de "divagación" acabo de instalar y luego desinstalar cgdb, y ya lo había libstdc++5instalado, no tengo idea de por qué la impresión bonita no funcionó mientras que ahora funciona.
Enrico Maria De Angelis
257

Con GCC 4.1.2, para imprimir el conjunto de un std :: vector <int> llamado myVector, haga lo siguiente:

print *(myVector._M_impl._M_start)@myVector.size()

Para imprimir solo los primeros N elementos, haga:

print *(myVector._M_impl._M_start)@N

Explicación

Esto probablemente depende en gran medida de la versión de su compilador, pero para GCC 4.1.2, el puntero a la matriz interna es:

myVector._M_impl._M_start 

Y el comando GDB para imprimir N elementos de una matriz que comienza en el puntero P es:

print P@N

O, en una forma corta (para un .gdbinit estándar):

p P@N
John Carter
fuente
44
Jeje, es algo que me ha molestado antes, así que lo busqué esta mañana y lo agregué como una nota para mí (como recomendó el propio Jeff).
John Carter
3
Además, si solo desea un elemento vectorial en particular, myVector._M_impl._M_start + n (para el enésimo elemento)
mariner
1
No funciona para mi Cannot evaluate function -- may be inlined
wallyk
1
Para imprimir un solo elemento, por ejemplo, el segundo elemento: print (myVector._M_impl._M_start) [2]
jfritz42
2
Para encontrar los nombres especiales ( _M_impletc.) para su compilador en GDB 7.0+, useprint /r myVector
Eponymous
14

'Mirar' los contenedores STL durante la depuración es un problema. Aquí hay 3 soluciones diferentes que he usado en el pasado, ninguna de ellas es perfecta.

1) Use scripts GDB de http://clith.com/gdb_stl_utils/ Estos scripts le permiten imprimir el contenido de casi todos los contenedores STL. El problema es que esto no funciona para contenedores anidados como una pila de conjuntos.

2) Visual Studio 2005 tiene un soporte fantástico para ver contenedores STL. Esto funciona para contenedores anidados pero es solo para su implementación para STL y no funciona si está colocando un contenedor STL en un contenedor Boost.

3) Escriba su propia función (o método) de 'impresión' para el elemento específico que desea imprimir durante la depuración y use 'llamar' mientras está en GDB para imprimir el elemento. Tenga en cuenta que si no se llama a su función de impresión en ninguna parte del código, g ++ eliminará el código muerto y GDB no encontrará la función de 'impresión' (recibirá un mensaje que dice que la función está en línea). Así que compila con -fkeep-inline-functions

Nikhil
fuente
11

ponga lo siguiente en ~ / .gdbinit

define print_vector
    if $argc == 2
        set $elem = $arg0.size()
        if $arg1 >= $arg0.size()
            printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size()
            set $elem = $arg1 -1
        end
        print *($arg0._M_impl._M_start + $elem)@1
    else
        print *($arg0._M_impl._M_start)@$arg0.size()
    end
end

document print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display
end

Después de reiniciar gdb (o buscar ~ / .gdbinit), muestre la ayuda asociada de esta manera

gdb) help print_vector
Display vector contents
Usage: print_vector VECTOR_NAME INDEX
VECTOR_NAME is the name of the vector
INDEX is an optional argument specifying the element to display

Ejemplo de uso:

(gdb) print_vector videoconfig_.entries 0
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0,     payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}}
badeip
fuente
2
¡Gracias por el codigo! Supongo que hay un error tipográfico y "print * ($ arg0._M_impl._M_start + $ elem) @ 1" debería ser "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Utilizo la siguiente modificación: definir print_vector if $ argc == 2 if $ arg1> = $ arg0.size () - 1 printf "Error,% s.size () =% d, imprimiendo el último elemento: \ n", " $ arg0 ", $ arg0.size () - 1 final print * ($ arg0._M_impl._M_start + $ arg1) @ 1 else print * ($ arg0._M_impl._M_start) @ $ arg0.size () end end
usuario1541776
el magnifico! mochas gracias
truthadjustr
0

Un poco tarde para la fiesta, ¡así que sobre todo un recordatorio para mí la próxima vez que haga esta búsqueda!

He podido usar:

p/x *(&vec[2])@4

para imprimir 4 elementos (como hexadecimal) a vecpartir de vec[2].

Mike P
fuente