ฉันจะทราบได้อย่างไรว่าไลบรารีถูกคอมไพล์ด้วย -g?


103

ฉันมีไลบรารีที่คอมไพล์แล้วบน x86 Linux และฉันต้องการตรวจสอบอย่างรวดเร็วว่ามีการคอมไพล์ด้วยสัญลักษณ์การดีบักหรือไม่

คำตอบ:


85

หากคุณใช้งานบน Linux ให้ใช้objdump --debuggingไฟล์. ควรมีรายการสำหรับไฟล์อ็อบเจ็กต์แต่ละไฟล์ในไลบรารี สำหรับไฟล์ออบเจ็กต์ที่ไม่มีสัญลักษณ์การดีบักคุณจะเห็นสิ่งต่อไปนี้

objdump --debugging libvoidincr.a
In archive libvoidincr.a:

voidincr.o:     file format elf64-x86-64

หากมีสัญลักษณ์การดีบักเอาต์พุตจะมีรายละเอียดมากขึ้น


5
นอกจากนี้ยังมีobdjump -W libและreadelf -w lib. อันหลังสามารถกำหนดค่าได้มากขึ้นโปรดดูที่ manpage ของ readelf (1)
przemoc

3
สำหรับไบนารีใด ๆ (รวมถึงที่คอมไพล์ด้วย -g) objdump ทำให้ฉันได้รับคำตอบว่า "ไม่รู้จักข้อมูลการดีบัก" เว้นแต่ฉันจะรวบรวมด้วย -gstabs สิ่งนี้ดูเหมือนจะเป็นข้อบกพร่องที่ได้รับการยอมรับ
Dan Hook

Dan คุณลองใช้แพลตฟอร์มไหน
swegi

ใช้ภาษารัสเซีย: จาก man objdump (1) แฟล็ก --debugging "พยายามแยกวิเคราะห์ข้อมูลรูปแบบการดีบัก STABS และ IEEE ที่เก็บไว้ในไฟล์และพิมพ์ออกมาโดยใช้ไวยากรณ์ C เช่นหากไม่พบรูปแบบเหล่านี้ตัวเลือกนี้จะกลับมา บนตัวเลือก -W เพื่อพิมพ์ข้อมูล DWARF ในไฟล์ "
Matt McClellan

5
objdump -gไม่มีอะไรให้ฉันสำหรับการทดสอบง่ายๆรวบรวมทั้งแบบมีและไม่มีgทำให้ไม่มีประโยชน์อย่างมีประสิทธิภาพ Ubuntu 12.04, gcc 4.6.3, GNU objdump 2.22 nm -aดูเหมือนจะมีประโยชน์มากกว่า
jw013

89

คำสั่งที่แนะนำ

objdump --debugging libinspected.a
objdump --debugging libinspected.so

ทำให้ฉันได้ผลลัพธ์เดียวกันเสมออย่างน้อยบน Ubuntu / Linaro 4.5.2:

libinspected.a:     file format elf64-x86-64
libinspected.so:     file format elf64-x86-64

ไม่ว่าไลบรารีที่เก็บถาวร / แชร์จะสร้างขึ้นโดยมีหรือไม่มี-gตัวเลือกก็ตาม

จริงๆสิ่งที่ช่วยให้ฉันเพื่อตรวจสอบว่า-gถูกใช้เป็นreadelfเครื่องมือ:

readelf --debug-dump=decodedline libinspected.so

หรือ

readelf --debug-dump=line libinspected.so

สิ่งนี้จะพิมพ์ชุดบรรทัดที่ประกอบด้วยชื่อไฟล์ต้นทางหมายเลขบรรทัดและที่อยู่หากข้อมูลการแก้ไขข้อบกพร่องดังกล่าวรวมอยู่ในไลบรารีมิฉะนั้นจะไม่พิมพ์อะไรเลย

คุณอาจจะผ่านสิ่งที่คุ้มค่าที่คุณจะพบสิ่งที่จำเป็นสำหรับตัวเลือกแทน--debug-dumpdecodedline


1
ทำงานได้อย่างสมบูรณ์ ฉันลองใช้คำสั่งนี้กับไฟล์ปฏิบัติการของฉันด้วย CMAKE_BUILD_TYPE RELEASE แรกและคำสั่งกลับว่างเปล่า จากนั้นฉันก็ลองใช้ CMAKE_BUILD_TYPE DEBUG แล้วมีผลลัพธ์ค่อนข้างมาก
infoclogged

32

สิ่งที่ช่วยได้คือ:

gdb mylib.so

มันพิมพ์เมื่อไม่พบสัญลักษณ์การดีบัก:

Reading symbols from mylib.so...(no debugging symbols found)...done.

หรือเมื่อพบ:

Reading symbols from mylib.so...done.

ไม่มีคำตอบก่อนหน้านี้ที่ให้ผลลัพธ์ที่มีความหมายสำหรับฉัน: libs ที่ไม่มีสัญลักษณ์ดีบักให้เอาต์พุตจำนวนมาก ฯลฯ


ขอบคุณ! สิ่งนี้ใช้ได้ผลสำหรับฉันโดยใช้ clang compiler ใน Android กับ cmake :)
Pär Nils Amsen

สุดยอดมากสำหรับการตรวจสอบอย่างรวดเร็ว! ยังทำงานบนไฟล์อ็อบเจ็กต์ * .o
Stephane Rolland

28

nm -a <lib> จะพิมพ์สัญลักษณ์ทั้งหมดจากไลบรารีรวมถึงสัญลักษณ์การดีบัก

ดังนั้นคุณสามารถเปรียบเทียบผลลัพธ์ของnm <lib>และnm -a <lib>- หากแตกต่างกัน lib ของคุณจะมีสัญลักษณ์ดีบักบางอย่าง


3
@ จ้างรัสเซียช่วยอธิบายให้ละเอียดหน่อยได้ไหม? ทำไมถึงคิดว่าเป็นเครื่องมือที่ผิด มันทำงานและทำงานบน Linux ด้วย
qrdl

แม้แต่ลินุกซ์ในตัวที่ใช้เคอร์เนล 2.6.35, xxx-objdump, xxx-nm ก็ใช้ได้ดี
agfe2

nm -aมีนามแฝงnm --debug-symsที่อธิบายตัวเอง :-)
pevik

3
เพียงพิมพ์diff <(nm <lib>) <(nm -a <lib>)เพื่อรับความแตกต่างอย่างง่าย
Aᴄʜᴇʀᴏɴғᴀɪʟ

17

บน OSX คุณสามารถใช้dsymutil -sและdwarfdump.

การใช้dsymutil -s <lib_file> | moreคุณจะเห็นเส้นทางไฟล์ต้นทางในไฟล์ที่มีสัญลักษณ์การดีบัก แต่จะมีเพียงชื่อฟังก์ชันเท่านั้น


11
คุณสามารถให้รายละเอียดเกี่ยวกับสิ่งที่ต้องค้นหาในผลลัพธ์ของตัวอย่างเช่นdsymutil -s? การมีอยู่ของเอาต์พุตหมายความว่าสร้างขึ้นด้วยสัญลักษณ์การดีบักหรือควรเป็น grepped?
Mitch

12

คุณสามารถใช้objdumpสำหรับสิ่งนี้

แก้ไข: จากหน้าคน:

-W
--dwarf
Displays  the  contents of the DWARF debug sections in the file, if
any are present.

6

คำตอบที่แนะนำการใช้objdump --debuggingหรือreadelf --debug-dump=...ไม่ทำงานในกรณีที่ข้อมูลการดีบักถูกเก็บไว้ในไฟล์ที่แยกจากไบนารีกล่าวคือไบนารีมีส่วนลิงก์ดีบัก readelfบางทีหนึ่งจะเรียกว่าข้อผิดพลาดใน

รหัสต่อไปนี้ควรจัดการสิ่งนี้อย่างถูกต้อง:

# Test whether debug information is available for a given binary
has_debug_info() {
  readelf -S "$1" | grep -q " \(.debug_info\)\|\(.gnu_debuglink\) "
}

ดูแยกไฟล์ดีบักในคู่มือ GDB สำหรับข้อมูลเพิ่มเติม

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