2008-10-31 25 views
185

Chcę sprawdzić zawartość std::vector w GDB, jak to zrobić? Powiedzmy, że jest to std::vector<int> ze względu na prostotę.Jak wydrukować elementy wektora C++ w GDB?

+3

Podobne pytanie: http: // stackoverflow .pl/questions/427589/inspecting-standard-container-stdmap-contents-with-gdb (link w odpowiedzi jest bardzo interesujący). –

+0

Nowy, lepszy sposób to zrobić w tym pytaniu: http://stackoverflow.com/questions/2492020/how-to-view-contents-of-stl-containers-using-gdb-7-x/2492341# 2492341 – dshepherd

+0

Specyfikacja inna niż dla grafiki wektorowej: https://stackoverflow.com/questions/427589/inspecting-standard-container-stdmap-contents-with-gdb –

Odpowiedz

68

Aby zobaczyć zawartość wektor std :: vector myvector, wystarczy wpisać w GDB:

(gdb) print myVector 

To będzie produkować moc podobną do:

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

Aby to osiągnąć, musisz mieć gdb 7 (testowałem go na gdb 7.01) i trochę pythonowej drukarki. Proces instalacji tych jest opisany na gdb wiki.

Co więcej, po zainstalowaniu powyżej, działa to dobrze z Eclipse GUI debuggera C++ (i każdego innego IDE używającego GDB, jak myślę).

+8

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

230

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

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

Aby wydrukować tylko pierwszych elementów n, zrobić:

print *(myVector._M_impl._M_start)@N 

Wyjaśnienie

prawdopodobnie jest silnie uzależniona od wersji kompilatora , Ale dla GCC 4.1.2, wskaźnik do tablicy wewnętrznej jest:

myVector._M_impl._M_start 

a polecenie GDB do druku N elementów tablicy począwszy od wskaźnika P jest:

print [email protected] 

Lub, krótki formularz (dla standardowego .gdbinit):

p [email protected] 
+3

Hehe, to jest coś, co mnie wcześniej oszukiwało, więc właśnie sprawdziłem to dziś rano i dodałem to jako notatkę dla siebie (jak sam Jeff zalecał). –

+2

Również jeśli chcesz tylko konkretny element wektorowy, myVector._M_impl._M_start + n (dla n-tego elementu) – mariner

+1

Nie działa dla mnie. "Nie można ocenić funkcji - można ją wstawić" – wallyk

13

"Oglądanie" kontenerów STL podczas debugowania stanowi pewien problem. Oto 3 różne rozwiązania, z których korzystałem w przeszłości, żaden z nich nie jest doskonały.

1) Użyj skryptów GDB z http://clith.com/gdb_stl_utils/ Te skrypty umożliwiają wydrukowanie 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 fantastyczne wsparcie dla oglądania kontenerów STL. Działa to w przypadku kontenerów zagnieżdżonych, ale ma to na celu ich implementację tylko dla STL i nie działa, jeśli umieszczasz kontener STL w kontenerze Boost.

3) Napisz własną funkcję drukowania (lub metodę) dla konkretnego przedmiotu, który chcesz wydrukować podczas debugowania i użyj "połączenia", gdy jesteś w GDB, aby wydrukować element. Zauważ, że jeśli twoja funkcja drukowania nie jest nigdzie wywoływana w kodzie, g ++ wykona eliminację martwego kodu, a funkcja "print" nie zostanie znaleziona przez GDB (otrzymasz komunikat informujący, że funkcja jest wbudowana). Więc skompilować z -fkeep-inline-funkcji

+6

To łącze jest 404. – kristopolous

+1

http://clith.com/gdb_stl_utils/ – swalog

6

umieść 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 zaopatrzenia ~/.gdbinit), pokazać jak ten związany pomocy

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ład użycia:

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

dziękuję za kod! Domyślam się, że jest literówka i "print * ($ arg0._M_impl._M_start + $ elem) @ 1" powinno brzmieć "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Używam następującej modyfikacji: zdefiniować print_vector jeśli $ argc == 2 jeśli $ arg1> = $ arg0.size() - 1 printf "Błąd,% s.size() =% d, drukowanie ostatniego elementu: \ n "," $ arg0 ", $ arg0.size() - 1 koniec wydrukuj * ($ arg0._M_impl._M_start + $ arg1) @ 1 else wydrukuj *($arg0._M_impl._M_start)@$ arg0.size() koniec koniec – user1541776