ฉันจะพิมพ์องค์ประกอบของเวกเตอร์ C ++ ใน GDB ได้อย่างไร


210

ฉันต้องการตรวจสอบเนื้อหาของ a std::vectorใน GDB ฉันจะทำอย่างไร สมมติว่ามันเป็นstd::vector<int>เรื่องของความเรียบง่าย


3
คำถามที่คล้ายกัน: stackoverflow.com/questions/427589/… (ลิงก์ในคำตอบน่าสนใจมาก)
เปาโล Tedesco

ใหม่วิธีที่ดีกว่าในการทำเช่นนี้คือในคำถามนี้: stackoverflow.com/questions/2492020//
dshepherd

คำตอบ:


79

หากต้องการดู vector std :: vector myVector เนื้อหาเพียงพิมพ์ใน GDB:

(gdb) print myVector

สิ่งนี้จะสร้างผลลัพธ์คล้ายกับ:

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

เพื่อให้บรรลุเป้าหมายข้างต้นคุณต้องมี gdb 7 (ฉันทดสอบใน gdb 7.01) และ python pretty-printer กระบวนการติดตั้งของสิ่งเหล่านี้อธิบายไว้ในgdb wikiวิกิพีเดีย

มีอะไรเพิ่มเติมหลังจากติดตั้งข้างต้นมันใช้งานได้ดีกับEclipse C ++ debugger GUI (และ IDE อื่น ๆ ที่ใช้ GDB อย่างที่ฉันคิด)


16
มันทำงานได้ดีตราบใดที่องค์ประกอบเวกเตอร์สามารถตีความได้โดยตรง แต่มันไม่ได้ช่วยถ้าเวกเตอร์มีตัวชี้ไปยังรายการที่น่าสนใจ
wallyk

ฉันไม่พบหน้าgdb wiki ที่สามารถอ่านได้โดยเฉพาะอาจเป็นเพราะตอนนี้ "เล็กน้อย" ล้าสมัยแล้วหรือ ตัวอย่างเช่นฉันมีความรู้สึกว่าเนื้อหาที่แนะนำของ$HOME/.gdbinitจำเป็น ในขณะที่ฉันจบลงด้วยไม่มีไฟล์ดังกล่าวที่ทุกคนและถูกต้องแสดงเนื้อหาของgdb std::vectorอย่างไรก็ตามเนื่องจากในระหว่างการพยายาม "rambling" ของฉันฉันเพิ่งติดตั้งและ unistalled แล้วcgdbและฉันได้libstdc++5ติดตั้งแล้วฉันไม่ทราบว่าทำไมการพิมพ์สวยไม่ทำงานในขณะนี้ทำงาน
Enrico Maria De Angelis

257

ด้วย GCC 4.1.2 หากต้องการพิมพ์ std :: vector <int> ทั้งหมดที่เรียกว่า myVector ให้ทำดังนี้:

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

หากต้องการพิมพ์เฉพาะองค์ประกอบ N แรกให้ทำ:

print *(myVector._M_impl._M_start)@N

คำอธิบาย

นี่อาจขึ้นอยู่กับเวอร์ชันคอมไพเลอร์เป็นอย่างมาก แต่สำหรับ GCC 4.1.2 ตัวชี้ไปยังอาร์เรย์ภายในคือ:

myVector._M_impl._M_start 

และคำสั่ง GDB เพื่อพิมพ์องค์ประกอบ N ของอาร์เรย์เริ่มต้นที่ตัวชี้ P คือ:

print P@N

หรือในรูปแบบย่อ (สำหรับ. gdbinit มาตรฐาน):

p P@N

4
เฮ่มันเป็นอะไรบางอย่างที่บั๊กฉันมาก่อนดังนั้นฉันจึงค้นหามันเมื่อเช้านี้และเพิ่มมันเพื่อเป็นบันทึกให้ตัวเอง (ตามที่เจฟฟ์แนะนำเอง)
John Carter

3
นอกจากนี้หากคุณต้องการเพียงองค์ประกอบเวกเตอร์เฉพาะ myVector._M_impl._M_start + n (สำหรับองค์ประกอบที่ n)
mariner

1
ไม่ทำงานสำหรับฉัน Cannot evaluate function -- may be inlined
wallyk

1
หากต้องการพิมพ์องค์ประกอบเดียวเช่นองค์ประกอบที่ 2: print (myVector._M_impl._M_start) [2]
jfritz42

2
ในการค้นหาชื่อพิเศษ ( _M_implฯลฯ ) สำหรับคอมไพเลอร์ของคุณภายใต้ GDB 7.0+ ให้ใช้print /r myVector
Eponymous

14

'การดู' คอนเทนเนอร์ STL ในขณะที่การดีบักค่อนข้างเป็นปัญหา นี่คือโซลูชั่นที่แตกต่างกัน 3 แบบที่ฉันเคยใช้ในอดีตไม่มีวิธีแก้ปัญหาใดที่สมบูรณ์แบบ

1) ใช้สคริปต์ GDB จากhttp://clith.com/gdb_stl_utils/สคริปต์เหล่านี้อนุญาตให้คุณพิมพ์เนื้อหาของคอนเทนเนอร์ STL เกือบทั้งหมด ปัญหาคือว่าสิ่งนี้ไม่ได้ผลสำหรับภาชนะซ้อนกันเช่นกองซ้อนของชุด

2) Visual Studio 2005 มีการสนับสนุนที่ยอดเยี่ยมสำหรับการดูคอนเทนเนอร์ STL ใช้งานได้กับคอนเทนเนอร์ที่ซ้อนอยู่ แต่ใช้สำหรับการใช้งาน STL เท่านั้นและไม่ทำงานหากคุณวางคอนเทนเนอร์ STL ในคอนเทนเนอร์ Boost

3) เขียนฟังก์ชั่น 'print' ของคุณเอง (หรือวิธีการ) สำหรับรายการเฉพาะที่คุณต้องการพิมพ์ขณะทำการดีบั๊กและใช้ 'call' ในขณะที่อยู่ใน GDB เพื่อพิมพ์รายการ โปรดทราบว่าหากฟังก์ชั่นการพิมพ์ของคุณไม่ได้ถูกเรียกที่ใดในรหัส g ++ จะทำการกำจัดโค้ดที่ตายแล้วและฟังก์ชัน 'พิมพ์' จะไม่ถูกค้นพบโดย GDB (คุณจะได้รับข้อความแจ้งว่าฟังก์ชั่นอินไลน์) ดังนั้นคอมไพล์ด้วย -fkeep-inline-functions


11

ใส่ต่อไปนี้ใน ~ / .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

หลังจากรีสตาร์ท gdb (หรือการจัดหา ~ / .gdbinit) ให้แสดงความช่วยเหลือที่เกี่ยวข้องเช่นนี้

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

ตัวอย่างการใช้งาน:

(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
ขอบคุณสำหรับรหัส! ฉันเดาว่ามีการพิมพ์ผิดและ "print * ($ arg0._M_impl._M_start + $ elem) @ 1" ควรเป็น "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? ฉันใช้การปรับเปลี่ยนต่อไปนี้: กำหนด print_vector ถ้า $ argc == 2 ถ้า $ arg1> = $ arg0.size () - 1 printf "Error,% s.size () =% d, การพิมพ์องค์ประกอบสุดท้าย: \ n", " $ arg0 ", $ arg0.size () - 1 end print * ($ arg0._M_impl._M_start + $ arg1) @ 1 อื่นพิมพ์ * ($ arg0._M_impl._M_start) @ $ arg0.size () ท้าย end
user1541776

el magnifico! mochas gracias
trueadjustr

0

สายไปงานเลี้ยงเล็กน้อยดังนั้นส่วนใหญ่เตือนให้ฉันในครั้งต่อไปที่ฉันทำการค้นหานี้!

ฉันสามารถใช้:

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

พิมพ์ 4 องค์ประกอบ (เป็นฐานสิบหก) จากราคาเริ่มต้นที่vecvec[2]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.