라이브 시스템에서 정의 된 공유 라이브러리 심볼이있는 위치를 찾고 시스템에서 내 보낸 모든 심볼을 나열합니다.


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(심지어 링크 때문일 수 있습니다). 꽤 약간의 오류 메시지를 출력합니다 (나도 마음에 들지 않습니다).

문제는- ldd(또는 ld?)는 아마도이 기호 검색 중 일부를 수행하지만 각 맨 페이지를 시도했지만 일종의 실행 파일을 논의. 부가 질문-이 도구를 사용하는 방법이 있습니까?

그래서 내가 찾고있는 명령 줄 도구는 (의사 코드)와 같이 작동합니다.

$ ./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및 ELF 바이너리로 인코딩 된 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 'SO- 악의를 그만두십시오

2
@Gilles를 scanelf사용하면 검색 할 특정 디렉토리를 지정하고 재귀 적 시칭을 지원할 수 -r있으므로 검색 경로를 조정하거나 너무 많은 문제없이 전체 시스템을 검색 할 수 있습니다. 예를 들어 scanelf -r -s SYMBOL /lib/* /usr/* /opt/*대부분의 장소 라이브러리가 숨겨져 있습니다.
케이시

7

GNU 시스템 (GNU libc 동적 링커를 사용하는 경우)에서 다음과 같이 프로그램을 실행할 수 있습니다.

LD_DEBUG=bindings kst2

기호가 해결되는 위치를 찾습니다.


0

한 번의 Linux 시스템에서 다른 Linux 시스템으로 코드를 포팅하려고 시도하면서 여러 번 실행했습니다. 일반적으로 모든 표준 디렉토리를 grep '합니다. 인터넷 검색을 찾을 수 없습니다. 다음은 간단한 스크립트입니다.

edt11x / findinsharedlibs

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.