공유 라이브러리 기호 충돌을 찾을 수 있는 도구가 있습니까?

공유 라이브러리 기호 충돌을 찾을 수 있는 도구가 있습니까?

제가 작성하고 있는 일부 소프트웨어가 충돌을 일으키고 있는데, 두 개의 서로 다른 공유 라이브러리 사이의 기호 충돌로 인해 발생한 것으로 의심됩니다(공유 라이브러리 중 하나를 비활성화하면 다른 하나가 작동하기 시작합니다).

프로그램에 의해 로드된 라이브러리를 보고 둘 이상의 라이브러리에 정의된 기호가 있는지 알려주는 데 사용할 수 있는 도구가 있습니까?

답변1

문제를 해결하기 위해 쉘 스크립트에 사용할 수 있는 몇 가지 일반적인 유틸리티가 있습니다(비록 문제를 해결하기 위해 이들을 결합한 스크립트를 본 기억은 없지만). 이것nm개체 파일이나 실행 파일에서 기호를 찾는 유틸리티입니다. 대부분의 시스템에서는ldd( otoolmacOS의 경우) 실행 파일에서 사용하는 공유 라이브러리를 표시합니다. 예를 들어 전자의 경우 스크립트(listused.sh)는 ncurses에 라이브러리의 모든 기호와 해당 라이브러리를 사용하는 프로그램에서 이러한 기호를 테스트할 수 있는지 여부를 나열합니다(참조보고서존재하다test/README).

-C옵션은 유용하지만(C++ 라이브러리에 관심이 있는 경우) 이러한 라이브러리는벗겨진(디버깅 정보가 누락되었습니다.) 하지만,-D옵션("최근" 시스템, 즉 지난 10~15년 동안 업데이트된 거의 모든 시스템에서 사용 가능)은 다음 기호를 제공합니다.동적도서관:

일반 기호 대신 동적 기호를 표시합니다. 이는 특정 유형의 공유 라이브러리와 같은 동적 개체에만 적합합니다.

동적 기호만 표시됩니다. 이 옵션은 공유 라이브러리에만 적합합니다.

기호 정보를 표시합니다 SHT_DYNSYM. 이것은 ld.so.1에서 사용되는 기호 테이블이며 제거된 동적 실행 파일에도 존재합니다. 만약에–D지정되지 않은 경우 기본 동작은 SHT_SYMTAB기호 정보를 표시하는 것입니다.

적어도 해당 문서에 따르면 이는 최신 시스템의 기능이 아닙니다.

(누군가는 이 기능 도입 일정을 즉시 알 수 있습니다.)

나는 다음과 같은 일부 스크립트에서 이 기능을 사용했습니다.analyze-curses-symbols.

추가 자료:

-quickstart_info 옵션을 사용하면 충돌이 발생하면 ld가 이를 알려줍니다. 또한 충돌을 찾으려면 -Dc 옵션과 함께 elfdump를 실행하라는 메시지도 표시됩니다. elfdump에서 생성된 출력을 읽는 방법에 대한 자세한 내용은 elfdump(1) 매뉴얼 페이지를 참조하십시오.

  • 그러나 elfdump는 표준화되지 않았습니다(심지어nm예) 그리고-Dc다른 구현에서는 찾을 수 없습니다.이것, 솔라리스의 경우. (가지다관련된Solaris용 프로그램).

답변2

nm -C library.so | grep -i symbol

당신이 찾고있는 것일 수도 있습니다. 그러나 제거된 라이브러리에서는 작동하지 않을 수 있습니다.

답변3

Linux 동적 링커는 이러한 문제를 디버깅하기 위한 몇 가지 방법도 제공합니다. 예를 들어 export LD_DEBUG=bindings모든 기호 바인딩에 대한 많은 정보를 얻을 수 있습니다 . 이 모든 출력을 하나의 파일에 수집하고 다양한 시나리오의 출력을 비교하면 일부 기호가 다른 파일에 연결되어 있음을 알 수 있습니다. 보다ld.so 문서더 많은 선택을 위해.

예를 들어 TensorFlow를 바이너리에 연결하고 일부 내장된 Python을 사용할 때 충돌을 추적하고 있습니다. 사고를 import hashlib. TensorFlow를 연결하지 않아도 충돌이 발생하지 않습니다. (이것도 보고된 것을 발견했습니다.여기그리고여기.)

TF를 연결하면 다음과 같은 출력을 얻습니다.

2306643:     binding file /u/zeyer/.linuxbrew/Cellar/[email protected]/3.11.2_1/lib/python3.11/lib-dynload/_hashlib.cpython-311-x86_64-linux-gnu.so [0] to /u/zeyer/.local/lib/python3.11/site-packages/tensorflow/libtensorflow_framework.so.2 [0]: normal symbol `EVP_MD_size' [OPENSSL_1_1_0]

그냥 실행하면 python -c "import hashlib"다음과 같은 결과가 나타납니다.

   2307740:     binding file /u/zeyer/.linuxbrew/Cellar/[email protected]/3.11.2_1/lib/python3.11/lib-dynload/_hashlib.cpython-311-x86_64-linux-gnu.so [0] to /work/tools/users/zeyer/linuxbrew/lib/libcrypto.so.1.1 [0]: normal symbol `EVP_MD_size' [OPENSSL_1_1_0]

보시다시피, TF를 사용하는 경우 OpenSSL 관련 기호를 에서 찾고 , 다른 경우에는 (해야 하는 대로) libtensorflow_framework.so.2에서 해당 기호를 찾습니다 .libcrypto.so.1.1

우리의 해결책은 -L/work/tools/users/zeyer/linuxbrew/lib -Wl,-rpath,/work/tools/users/zeyer/linuxbrew/lib -Wl,-no-as-needed -lcryptoTF 라이브러리를 연결하기 전에 링커 플래그를 추가하는 것이었습니다. 그래서 libcrypto.so.1.1먼저 강제로 로드합니다. 이것으로 문제가 해결됩니다. 바라보다여기내 컴파일 스크립트를 위해.

관련 정보