라이브 시스템에 정의된 공유 라이브러리 기호의 위치 찾기/시스템에 내보낸 모든 기호 나열

라이브 시스템에 정의된 공유 라이브러리 기호의 위치 찾기/시스템에 내보낸 모든 기호 나열

기본적으로 두 가지 문제가 하나로 합쳐져 있습니다. 시스템에 내보낸 모든 기호와 해당 공유 라이브러리 경로를 나열할 수 있으면 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 ...이 쌍을 찾지 못했습니다. 짜증나는 대안도 있습니다. News를 사용하여 find전체 루트 파일 시스템을 스캔합니다 nm(나도 좋아하지 않습니다).

문제는 - ldd(또는 ld?) 일부 기호 조회를 수행할 수 있지만 해당 맨페이지를 시도했지만 일종의 실행 파일을 인수로 제공하지 않고 명령줄에서 기호를 "찾는" 방법을 볼 수 없다는 것입니다. 부가 질문 - 이러한 도구를 사용하여 이를 달성할 수 있는 방법이 있습니까?

그래서 저는 (의사 코드)처럼 작동하는 명령줄 도구를 찾고 있습니다.

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

...검색할 디렉터리를 지정하지 않았지만 처리할 수도 있습니다. 예 를 들어 다음 LD_PRELOADLD_LIBRARY_PATH같습니다.

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

/path/to/mylib.so...그런 다음 주어진 기호가 정의된 위치를 얻습니다 (표준 라이브러리에 해당 기호가 없다고 가정). 그렇지 않으면 "찾을 수 없음"이 출력됩니다. 그렇지 않으면, ./findsymbol --dumpall사용 가능한 모든 기호 목록과 주어진 환경(예: 특정 셸)에서 본 위치를 생성할 수 있습니다 bash.

Linux에 그런 도구가 있나요?

답변1

라이브러리를 찾는 경로는 파일 /etc/ld.so.conf, 환경 변수 LD_LIBRARY_PATH및 ELF 바이너리로 인코딩된 모든 RPATH에 나열됩니다. 이 프로그램은 ldd특정 응용 프로그램이 어떤 라이브러리를 로드할지 알려줍니다.

관심 있는 기호가 있으면 프로그램을 사용하여 기호를 nm덤프 .o및 파일링하고 .a하나 또는 임의의 elf 실행 파일에서 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플래그는 디렉토리가 검색됨을 나타내고 /etc/ld.so.conf찾을 -s기호를 지정합니다.

답변2

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

LD_DEBUG=bindings kst2

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

답변3

한 Linux 시스템에서 다른 Linux 시스템으로 코드를 이식하려고 할 때 이런 상황이 여러 번 발생했습니다. 일반적으로 나는 모든 표준 디렉토리를 greping하게 됩니다. Google에서 아무것도 찾을 수 없습니다. 다음은 빠른 스크립트입니다.

edt11x/findinsharedlibs

관련 정보