Como imprimo os elementos de um vetor C ++ no GDB?

Respostas:

79

Para visualizar o conteúdo do vetor std :: vector myVector, basta digitar GDB:

(gdb) print myVector

Isso produzirá uma saída semelhante a:

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

Para conseguir acima, você precisa do gdb 7 (eu testei no gdb 7.01) e alguma impressora bonita em python. O processo de instalação destes está descrito no wiki do gdb .

Além disso, após a instalação acima, isso funciona bem com a GUI do depurador Eclipse C ++ (e qualquer outro IDE usando GDB, como eu acho).

Michał Oniszczuk
fonte
16
Isso funciona bem, desde que os elementos vetoriais sejam diretamente interpretáveis. Mas não ajuda se o vetor contiver indicadores para os itens de interesse.
wallyk
Francamente, não acho a página wiki do gdb particularmente legível, talvez porque esteja "um pouco" desatualizada agora? Por exemplo, tive a impressão de que o conteúdo sugerido $HOME/.gdbinitera necessário. No momento, acabo sem esse arquivo e gdbmostrando corretamente o conteúdo de std::vector. No entanto, como durante as minhas tentativas de "divagar", acabei de instalar e, em seguida cgdb, desinstalei , e já o libstdc++5instalei, não tenho idéia do motivo pelo qual a bonita impressão não funcionou enquanto agora funciona.
Enrico Maria De Angelis
257

Com o GCC 4.1.2, para imprimir o conjunto de um std :: vector <int> chamado myVector, faça o seguinte:

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

Para imprimir apenas os primeiros N elementos, faça:

print *(myVector._M_impl._M_start)@N

Explicação

Provavelmente, isso depende muito da sua versão do compilador, mas para o GCC 4.1.2, o ponteiro para a matriz interna é:

myVector._M_impl._M_start 

E o comando GDB para imprimir N elementos de uma matriz começando no ponteiro P é:

print P@N

Ou, de forma abreviada (para um arquivo .gdbinit padrão):

p P@N
John Carter
fonte
4
Hehe, é algo que me incomodou antes, então eu procurei esta manhã e a adicionei como um memorando para mim (como o próprio Jeff recomendou).
John Carter
3
Além disso, se você quer apenas um elemento do vetor particular, myVector._M_impl._M_start + n (para o enésimo elemento)
Mariner
1
Não está trabalhando para mim. Cannot evaluate function -- may be inlined
wallyk
1
Para imprimir um único elemento, por exemplo, o 2º elemento: print (myVector._M_impl._M_start) [2]
jfritz42 31/08/2015
2
Para encontrar os nomes especiais ( _M_impletc) para o seu compilador no GDB 7.0+, useprint /r myVector
Eponymous
14

'Observar' os contêineres STL durante a depuração é um problema. Aqui estão três soluções diferentes que eu usei no passado, nenhuma delas é perfeita.

1) Use scripts GDB em http://clith.com/gdb_stl_utils/ Esses scripts permitem imprimir o conteúdo de quase todos os contêineres STL. O problema é que isso não funciona para contêineres aninhados como uma pilha de conjuntos.

2) O Visual Studio 2005 tem um suporte fantástico para assistir contêineres STL. Isso funciona para contêineres aninhados, mas é para sua implementação apenas para STL e não funciona se você estiver colocando um contêiner STL em um contêiner Boost.

3) Escreva sua própria função 'print' (ou método) para o item específico que você deseja imprimir durante a depuração e use 'call' enquanto estiver no GDB para imprimir o item. Observe que, se sua função de impressão não estiver sendo chamada em nenhum lugar do código, o g ++ eliminará o código morto e a função 'print' não será encontrada pelo GDB (você receberá uma mensagem informando que a função está embutida). Então compile com -fkeep-inline-functions

Nikhil
fonte
11

coloque o seguinte em ~ / .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

Após reiniciar o gdb (ou sourcing ~ / .gdbinit), mostre a ajuda associada como esta

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

Exemplo 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
fonte
2
obrigado pelo código! Eu acho que existe um erro de digitação e "print * ($ arg0._M_impl._M_start + $ elem) @ 1" deve ser "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Eu uso a seguinte modificação: defina print_vector se $ argc == 2 se $ arg1> = $ arg0.size () - 1 printf "Erro,% s.size () =% d, imprimindo o último elemento: \ n", " $ arg0 ", $ arg0.size () - 1 impressão final * ($ arg0._M_impl._M_start + $ arg1) @ 1 impressão adicional * ($ arg0._M_impl._M_start) @ $ arg0.size () fim final
user1541776
el magnifico! mochas gracias
truthadjustr 20/10/19
0

Um pouco atrasado para a festa, então principalmente um lembrete para mim na próxima vez que fizer essa pesquisa!

Consegui usar:

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

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

Mike P
fonte