Jak wydrukować elementy wektora C ++ w GDB?


Odpowiedzi:


79

Aby wyświetlić zawartość wektor std :: vector myVector, po prostu wpisz GDB:

(gdb) print myVector

To da wynik podobny do:

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

Aby osiągnąć powyższe, musisz mieć gdb 7 (przetestowałem go na gdb 7.01) i trochę ładnej drukarki w Pythonie. Proces ich instalacji opisano na gdb wiki .

Co więcej, po instalacji powyżej działa to dobrze z graficznym interfejsem debugera Eclipse C ++ (i każdym innym IDE używającym GDB, jak myślę).


16
Działa to dobrze, o ile elementy wektorowe są bezpośrednio interpretowalne. Ale to nie pomaga, jeśli wektor zawiera wskaźniki do interesujących przedmiotów.
wallyk

Szczerze mówiąc, uważam, że strona wiki gdb nie jest szczególnie czytelna, może dlatego, że jest teraz „nieco” przestarzała? Na przykład miałem wrażenie, że sugerowana treść $HOME/.gdbinitbyła konieczna. W tej chwili nie mam w ogóle takiego pliku i gdbpoprawnie pokazuję zawartość std::vector. Ponieważ jednak podczas moich prób „włóczenia się” właśnie zainstalowałem, a następnie zainstalowałem cgdb, a już libstdc++5zainstalowałem, nie mam pojęcia, dlaczego ładny druk nie działał, a teraz działa.
Enrico Maria De Angelis

257

W GCC 4.1.2, aby wydrukować cały plik std :: vector <int> o nazwie myVector, wykonaj następujące czynności:

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

Aby wydrukować tylko pierwsze N ​​elementów, wykonaj:

print *(myVector._M_impl._M_start)@N

Wyjaśnienie

Jest to prawdopodobnie silnie zależne od wersji kompilatora, ale w przypadku GCC 4.1.2 wskaźnik do tablicy wewnętrznej to:

myVector._M_impl._M_start 

A polecenie GDB do wydrukowania N elementów tablicy zaczynających się od wskaźnika P to:

print P@N

Lub, w krótkiej formie (dla standardowego .gdbinit):

p P@N

4
Hehe, to coś mnie wcześniej wkurzyło, więc po prostu sprawdziłem to dziś rano i dodałem do siebie jako notatkę (jak zalecił sam Jeff).
John Carter

3
Również jeśli chcesz tylko konkretnego elementu wektorowego, myVector._M_impl._M_start + n (dla n-tego elementu)
mariner

1
Nie działa dla mnie. Cannot evaluate function -- may be inlined
wallyk

1
Aby wydrukować pojedynczy element, np. Drugi element: print (myVector._M_impl._M_start) [2]
jfritz42

2
Aby znaleźć specjalne nazwy ( _M_implitp.) Kompilatora w GDB 7.0+, użyjprint /r myVector
Eponim

14

„Obserwowanie” kontenerów STL podczas debugowania stanowi pewien problem. Oto 3 różne rozwiązania, z których korzystałem w przeszłości, żadne z nich nie jest idealne.

1) Użyj skryptów GDB ze strony http://clith.com/gdb_stl_utils/. Skrypty te umożliwiają drukowanie zawartości prawie wszystkich kontenerów STL. Problem polega na tym, że nie działa to w przypadku zagnieżdżonych kontenerów, takich jak stos zestawów.

2) Visual Studio 2005 ma fantastyczną obsługę oglądania kontenerów STL. Działa to w przypadku zagnieżdżonych kontenerów, ale służy to ich implementacji tylko dla STL i nie działa, jeśli umieszczasz kontener STL w kontenerze Boost.

3) Napisz własną funkcję (lub metodę) „drukowania” dla określonego elementu, który chcesz wydrukować podczas debugowania, i użyj „wywołania” w GDB, aby wydrukować element. Zauważ, że jeśli twoja funkcja drukowania nie jest wywoływana nigdzie w kodzie, g ++ dokona eliminacji martwego kodu, a GDB nie znajdzie funkcji „drukowania” (pojawi się komunikat, że funkcja jest wstawiona). Więc skompiluj z funkcjami -fkeep-inline


11

umieść następujące w ~ / .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

Po ponownym uruchomieniu gdb (lub sourcing ~ / .gdbinit), pokaż powiązaną pomoc w ten sposób

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

Przykładowe użycie:

(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
dziękuję za kod! Wydaje mi się, że jest literówka i „print * ($ arg0._M_impl._M_start + $ elem) @ 1” powinno być „print * ($ arg0._M_impl._M_start + $ arg1) @ 1”? Używam następującej modyfikacji: zdefiniuj wektor_wydruku, jeśli $ argc == 2, jeśli $ arg1> = $ arg0.size () - 1 printf "Błąd,% s.size () =% d, wypisywanie ostatniego elementu: \ n", " $ arg0 ", $ arg0.size () - 1 koniec wydruku * ($ arg0._M_impl._M_start + $ arg1) @ 1 inny wydruk * ($ arg0._M_impl._M_start) @ $ arg0.size () koniec
użytkownik1541776

el magnifico! mochas gracias
truthadjustr

0

Trochę późno na imprezę, więc przede wszystkim przypominam mi o następnym poszukiwaniu!

Byłem w stanie użyć:

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

aby wydrukować 4 elementy (szesnastkowe) od vecpoczątku vec[2].

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.