Come posso stampare gli elementi di un vettore C ++ in GDB?


Risposte:


79

Per visualizzare i contenuti di vector std :: vector myVector, basta digitare GDB:

(gdb) print myVector

Ciò produrrà un output simile a:

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

Per ottenere sopra, è necessario disporre di gdb 7 (l'ho testato su gdb 7.01) e di una bella stampante Python. Il processo di installazione di questi è descritto sul wiki di gdb .

Inoltre, dopo l'installazione sopra, funziona bene con la GUI del debugger di Eclipse C ++ (e qualsiasi altro IDE che utilizza GDB, come penso).


16
Funziona bene fintanto che gli elementi vettoriali sono direttamente interpretabili. Ma non aiuta se il vettore contiene puntatori agli elementi di interesse.
Wallyk,

Sinceramente non trovo la pagina della wiki di gdb particolarmente leggibile, forse perché è "leggermente" obsoleta ora? Ad esempio, ho avuto l'impressione che il contenuto suggerito del $HOME/.gdbinitfosse necessario. Al momento finisco con nessun file del genere e gdbmostrando correttamente il contenuto di std::vector. Tuttavia, dato che durante i miei tentativi "sconclusionati" ho appena installato e quindi non installato cgdb, e avevo già libstdc++5installato, non ho idea del perché la bella stampa non funzionasse mentre ora funziona.
Enrico Maria De Angelis,

257

Con GCC 4.1.2, per stampare l'intero di uno std :: vector <int> chiamato myVector, procedere come segue:

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

Per stampare solo i primi N elementi, procedere come segue:

print *(myVector._M_impl._M_start)@N

Spiegazione

Questo probabilmente dipende fortemente dalla versione del compilatore, ma per GCC 4.1.2, il puntatore all'array interno è:

myVector._M_impl._M_start 

E il comando GDB per stampare N elementi di un array a partire dal puntatore P è:

print P@N

Oppure, in forma abbreviata (per un .gdbinit standard):

p P@N

4
Hehe, è qualcosa che mi ha infastidito prima, quindi ho appena cercato questa mattina e l'ho aggiunto come promemoria a me stesso (come Jeff stesso ha raccomandato).
John Carter,

3
Inoltre, se vuoi solo un particolare elemento vettoriale, myVector._M_impl._M_start + n (per l'ennesimo elemento)
marinaio

1
Non funziona per me. Cannot evaluate function -- may be inlined
Wallyk,

1
Per stampare un singolo elemento, ad esempio il secondo elemento: print (myVector._M_impl._M_start) [2]
jfritz42

2
Per trovare i nomi speciali ( _M_implecc.) Per il tuo compilatore in GDB 7.0+, usaprint /r myVector
Eponymous

14

Il "monitoraggio" dei contenitori STL durante il debug è un po 'un problema. Ecco 3 diverse soluzioni che ho usato in passato, nessuna di queste è perfetta.

1) Utilizzare gli script GDB da http://clith.com/gdb_stl_utils/ Questi script consentono di stampare il contenuto di quasi tutti i contenitori STL. Il problema è che questo non funziona per i contenitori nidificati come una pila di set.

2) Visual Studio 2005 ha un supporto fantastico per guardare i contenitori STL. Funziona con i contenitori nidificati ma è solo per la loro implementazione per STL e non funziona se si inserisce un contenitore STL in un contenitore Boost.

3) Scrivi la tua funzione (o metodo) 'stampa' per l'elemento specifico che desideri stampare durante il debug e usa 'call' mentre sei in GDB per stampare l'elemento. Nota che se la tua funzione di stampa non viene chiamata da nessuna parte nel codice g ++ eliminerà il codice morto e la funzione 'stampa' non verrà trovata da GDB (riceverai un messaggio che dice che la funzione è incorporata). Quindi compilare con le funzioni -fkeep-inline


11

inserisci quanto segue in ~ / .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

Dopo aver riavviato gdb (o sourcing ~ / .gdbinit), mostra l'aiuto associato come questo

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

Esempio di utilizzo:

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

2
grazie per il codice! Suppongo che ci sia un refuso e "print * ($ arg0._M_impl._M_start + $ elem) @ 1" dovrebbe essere "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Uso la seguente modifica: definisco print_vector se $ argc == 2 se $ arg1> = $ arg0.size () - 1 printf "Errore,% s.size () =% d, stampa ultimo elemento: \ n", " $ arg0 ", $ arg0.size () - 1 end print * ($ arg0._M_impl._M_start + $ arg1) @ 1 else print * ($ arg0._M_impl._M_start) @ $ arg0.size () end end
user1541776

el magnifico! mochas gracias
truthadjustr,

0

Un po 'in ritardo alla festa, quindi per lo più un promemoria per me la prossima volta che faccio questa ricerca!

Sono stato in grado di usare:

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

per stampare 4 elementi (come esadecimale) a vecpartire da vec[2].

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.