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.