Bagaimana cara mencetak elemen vektor C ++ di GDB?

Jawaban:

79

Untuk melihat konten vektor std :: vektor myVector, cukup ketik GDB:

(gdb) print myVector

Ini akan menghasilkan output yang mirip dengan:

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

Untuk mencapai di atas, Anda harus memiliki gdb 7 (saya mengujinya di gdb 7.01) dan beberapa printer cantik python. Proses instalasi ini dijelaskan pada gdb wiki .

Terlebih lagi, setelah menginstal di atas, ini bekerja dengan baik dengan Eclipse C ++ debugger GUI (dan IDE lain yang menggunakan GDB, seperti yang saya kira).

Michał Oniszczuk
sumber
16
Ini berfungsi dengan baik selama elemen vektor langsung dapat ditafsirkan. Tetapi tidak membantu jika vektor berisi pointer ke item-item yang menarik.
wallyk
Terus terang saya tidak menemukan halaman wiki gdb sangat mudah dibaca, mungkin karena itu "sedikit" ketinggalan jaman sekarang? Misalnya, saya mendapat kesan bahwa konten yang disarankan $HOME/.gdbinititu diperlukan. Saat ini saya berakhir tanpa file seperti itu sama sekali dan gdbdengan benar menunjukkan konten std::vector. Namun, karena selama upaya "bertele-tele" saya baru saja menginstal dan kemudian unistalled cgdb, dan saya sudah libstdc++5menginstal, saya tidak tahu mengapa pencetakan cantik tidak bekerja sementara sekarang berfungsi.
Enrico Maria De Angelis
257

Dengan GCC 4.1.2, untuk mencetak seluruh std :: vector <int> yang disebut myVector, lakukan hal berikut:

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

Untuk hanya mencetak elemen N pertama, lakukan:

print *(myVector._M_impl._M_start)@N

Penjelasan

Ini mungkin sangat tergantung pada versi kompiler Anda, tetapi untuk GCC 4.1.2, pointer ke array internal adalah:

myVector._M_impl._M_start 

Dan perintah GDB untuk mencetak elemen N array mulai dari pointer P adalah:

print P@N

Atau, dalam bentuk singkat (untuk .gdbinit standar):

p P@N
John Carter
sumber
4
Hehe, itu adalah sesuatu yang menyadap saya sebelumnya, jadi saya baru saja mencarinya pagi ini dan menambahkannya sebagai memo pada diri saya (seperti yang disarankan Jeff sendiri).
John Carter
3
Juga jika Anda hanya menginginkan elemen vektor tertentu, myVector._M_impl._M_start + n (untuk elemen ke-n)
mariner
1
Tidak bekerja untukku. Cannot evaluate function -- may be inlined
wallyk
1
Untuk mencetak satu elemen, mis. Elemen 2: print (myVector._M_impl._M_start) [2]
jfritz42
2
Untuk menemukan nama khusus ( _M_impldll) untuk kompiler Anda di bawah GDB 7.0+, gunakanprint /r myVector
Eponim
14

STL 'Menonton' kontainer saat debugging agak menjadi masalah. Berikut adalah 3 solusi berbeda yang pernah saya gunakan di masa lalu, tidak ada satupun yang sempurna.

1) Gunakan skrip GDB dari http://clith.com/gdb_stl_utils/ Skrip ini memungkinkan Anda untuk mencetak konten hampir semua wadah STL. Masalahnya adalah ini tidak berfungsi untuk kontainer bersarang seperti set tumpukan.

2) Visual Studio 2005 memiliki dukungan fantastis untuk menonton wadah STL. Ini berfungsi untuk wadah bersarang tetapi ini hanya untuk penerapan STL dan tidak berfungsi jika Anda meletakkan wadah STL dalam wadah Peningkatan.

3) Tulis fungsi 'print' Anda sendiri (atau metode) untuk item spesifik yang ingin Anda cetak saat debugging dan gunakan 'panggilan' saat di GDB untuk mencetak item. Perhatikan bahwa jika fungsi cetak Anda tidak dipanggil di mana pun dalam kode g ++ akan melakukan penghapusan kode mati dan fungsi 'cetak' tidak akan ditemukan oleh GDB (Anda akan mendapatkan pesan yang mengatakan bahwa fungsi tersebut sebaris). Jadi kompilasi dengan -fkeep-inline-functions

Nikhil
sumber
11

tuliskan berikut ini di ~ / .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

Setelah memulai ulang gdb (atau sumber ~ / .gdbinit), perlihatkan bantuan terkait seperti ini

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

Contoh penggunaan:

(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
sumber
2
terima kasih untuk kodenya! Saya kira ada kesalahan ketik dan "print * ($ arg0._M_impl._M_start + $ elem) @ 1" harus "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? Saya menggunakan modifikasi berikut: define print_vector jika $ argc == 2 jika $ arg1> = $ arg0.size () - 1 printf "Kesalahan,% s.size () =% d, mencetak elemen terakhir: \ n", " $ arg0 ", $ arg0.size () - 1 akhir cetak * ($ arg0._M_impl._M_start + $ arg1) @ 1 else cetak * ($ arg0._M_impl._M_start) @ $ arg0.size () end end
user1541776
el magnifico! mochas gracias
truthadjustr
0

Sedikit terlambat ke pesta, jadi sebagian besar pengingat untuk saya lain kali saya melakukan pencarian ini!

Saya sudah bisa menggunakan:

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

untuk mencetak 4 elemen (sebagai hex) dari vecmulai dari vec[2].

Mike P
sumber