기본적으로 두 가지 문제가 하나로 합쳐져 있습니다. 시스템에 내보낸 모든 기호와 해당 공유 라이브러리 경로를 나열할 수 있으면 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_PRELOAD
과 LD_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에서 아무것도 찾을 수 없습니다. 다음은 빠른 스크립트입니다.