ค้นหาตำแหน่งที่เป็นสัญลักษณ์ไลบรารีแบบแบ่งใช้ที่กำหนดบนระบบสด / รายการสัญลักษณ์ทั้งหมดที่เอ็กซ์พอร์ตบนระบบ


21

โดยทั่วไปนี่เป็นคำถามสองข้อในคำถามเดียวเพราะถ้าฉันสามารถแสดงรายการสัญลักษณ์ทั้งหมดที่ส่งออกภายในระบบพร้อมกับเส้นทางไลบรารีที่ใช้ร่วมกันของพวกเขาฉันก็สามารถแสดงgrepผลลัพธ์นั้นได้

สำหรับสัญลักษณ์เคอร์เนลฉันคิดว่ามันค่อนข้างง่าย - เพราะเราสามารถcat /proc/kallsymsรับรายการสัญลักษณ์ทั้งหมดของโมดูลเหล่านั้นที่โหลดในหน่วยความจำ จากนั้นsudo cat /proc/modulesจะให้รายการของโมดูลที่โหลดพร้อมที่อยู่ แต่ไม่ใช่เส้นทางที่มีการโหลดโมดูลจาก (หากพวกเขาถูกสร้างเป็นวัตถุที่แยกออกจากกันเป็นต้นไม้. ko)

ตัวอย่างเช่นฉันพยายามติดตามโปรแกรมkstโดยใช้ltrace:

$ ltrace kst2
...
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0, 0xbfe631a8, 0x823652b, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
_ZNK13QGraphicsItem10parentItemEv(0xa1ccdb4, 0x839ff00, 0x8306b80, 84, 0xbfe63298) = 0xa1ce854
__dynamic_cast(0xa1ce854, 0x839ff00, 0x8306b80, 84, 0xbfe63298)     = 0xa1ce800
...

... และฉันต้องการทราบว่าที่_ZNK13QGraphicsItem10parentItemEvอยู่นี้

ดังนั้นจะทำอย่างไรกับสัญลักษณ์ไลบรารีที่แชร์ การอ่านผ่าน[gcc-help] Re: การค้นหาไลบรารีที่มีการกำหนดสัญลักษณ์ ; ฉันลองทำสิ่งนี้:

$ find /usr/lib -name '*.so*' -exec nm --print-file-name --defined-only --dynamic {} \; | grep "QGraphicsItem"
...
/usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
/usr/lib/libQtGui.so.4.7.2:00766aa0 T _Zls6QDebugN13QGraphicsItem18GraphicsItemChangeE
/usr/lib/libQtGui.so.4.7.2:00767e80 T _Zls6QDebugP13QGraphicsItem
...

... แต่นั่นทำให้ฉันมีปัญหาเพิ่มเติม: ฉันไม่รู้เส้นทางทั้งหมดที่ถูกสแกนเพื่อแชร์ไลบรารีในระบบของฉันดังนั้นเมื่อฉันลองครั้งแรกfind /lib ...มันไม่พบอะไรเลย ฉันคิดว่านี่เป็นไดเรกทอรีที่น่ารำคาญเช่นเดียวกับทางเลือกอื่น: สแกนระบบไฟล์รูททั้งหมดด้วยfind... และฉันก็ดูเหมือนจะโดน * .so ซึ่งไม่สามารถเปิดได้nm(อาจเป็นเพราะ symlink?) ซึ่ง แสดงข้อความข้อผิดพลาดเล็กน้อย (ซึ่งฉันไม่ชอบ)

สิ่งคือ - ldd(หรือld?) อาจทำการค้นหาสัญลักษณ์บางอย่าง แต่ฉันลองใช้ manpages ที่เกี่ยวข้องและฉันไม่เห็นวิธี "สัญลักษณ์" ใด ๆ จากบรรทัดคำสั่งโดยไม่ให้ไฟล์ปฏิบัติการที่เป็นไฟล์ ข้อโต้แย้ง. คำถามด้าน - มีวิธีใช้เครื่องมือเหล่านี้เพื่อสิ่งนั้นหรือไม่?

ดังนั้นสิ่งที่ฉันกำลังมองหาเครื่องมือบรรทัดคำสั่งซึ่งจะทำตัวเหมือน (pseudocode):

$ ./findsymbol '_Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE'
symbol found in:
    /usr/lib/libQtGui.so.4.7.2:00766d70 T _Zls6QDebugN13QGraphicsItem16GraphicsItemFlagE
...

... ที่ฉันไม่ได้ระบุไดเรกทอรีใด ๆ เพื่อค้นหา - แต่จะจัดการเช่นLD_PRELOADหรือLD_LIBRARY_PATH; พูดถ้าฉันทำ:

$ LD_PRELOAD="/path/to/mylib.so" ./findsymbol '*mylib_print*'

... จากนั้นฉันจะได้/path/to/mylib.soรับสัญลักษณ์ที่กำหนดไว้ (เนื่องจากสัญลักษณ์ดังกล่าวจะไม่มีอยู่ในไลบรารีมาตรฐาน) - และจะแสดงผลลัพธ์เป็น "ไม่พบ" เป็นอย่างอื่น และ./findsymbol --dumpallสามารถสร้างรายการของสัญลักษณ์ที่มีอยู่ทั้งหมดและตำแหน่งของมันที่เห็นได้จากสภาพแวดล้อมที่กำหนด (เช่นbashเชลล์เฉพาะ)

มีเครื่องมือเช่นนี้สำหรับ Linux หรือไม่?

คำตอบ:


16

พา ธ ที่จะค้นหาไลบรารี่ในนั้นจะถูกระบุไว้ในไฟล์/etc/ld.so.confตัวแปรสภาพแวดล้อมLD_LIBRARY_PATHและ RPATH ใด ๆ ที่เข้ารหัสไว้ในเอลฟ์ไบนารี โปรแกรมlddจะบอกให้คุณทราบว่าไลบรารีใดที่แอปพลิเคชันเฉพาะจะโหลด

เมื่อคุณมีสัญลักษณ์ที่คุณอยากรู้เกี่ยวกับคุณสามารถใช้โปรแกรมnmเพื่อถ่ายโอนสัญลักษณ์.oและ.aไฟล์และreadelfเพื่อถ่ายโอนสัญลักษณ์จาก.soปฏิบัติการที่เอลฟ์หรือ

ตัวอย่าง:

nm -g /usr/lib/blah.a
readelf -Ws /usr/lib/blah.so

และท้ายที่สุดด้วยภูมิหลังนั้นนี่คือจอกศักดิ์สิทธิ์ของคุณ:

ได้รับสัญลักษณ์_ZN6Kopete6Global10PropertiesC2Evอยู่ที่ไหนนี่?

scanelf -l -s _ZN6Kopete6Global10PropertiesC2Ev | grep _ZN6Kopete6Global10PropertiesC2Ev

ซึ่งให้:

ET_DYN _ZN6Kopete6Global10PropertiesC2Ev /usr/lib64/libkopete.so.4.11.4

-lธงกล่าวว่าในการค้นหา dirs ใน/etc/ld.so.confและ-sระบุสัญลักษณ์เพื่อค้นหา


สิ่งนี้ไม่สมบูรณ์: บางโปรแกรมโหลดไลบรารีจากไดเรกทอรีเฉพาะแอปพลิเคชัน
Gilles 'หยุดความชั่วร้าย'

2
@Gilles scanelfช่วยให้คุณสามารถระบุไดเรกทอรีเฉพาะเพื่อค้นหาและสนับสนุนการค้นหาแบบวนซ้ำด้วยซ้ำ-rเพื่อให้คุณสามารถปรับแต่งเส้นทางการค้นหาหรือค้นหาระบบทั้งหมดของคุณโดยไม่มีปัญหามากเกินไป ตัวอย่างเช่นscanelf -r -s SYMBOL /lib/* /usr/* /opt/*จะพบว่าไลบรารีส่วนใหญ่ของสถานที่ซ่อนอยู่
casey

7

บนระบบ GNU (เมื่อใช้ GNU libc dynamic linker) คุณสามารถเรียกใช้โปรแกรมเป็น:

LD_DEBUG=bindings kst2

เพื่อค้นหาสัญลักษณ์ที่แก้ไข


0

ฉันใช้ไปหลายครั้งพยายามพอร์ตโค้ดจากระบบ Linux หนึ่งไปยังอีกระบบหนึ่ง ฉันมักจะจบ grep'ing ไดเรกทอรีมาตรฐานทั้งหมด ฉันหา googling ไม่เจอ ดังนั้นนี่คือสคริปต์ด่วน:

edt11x / findinsharedlibs

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