2008-10-23 2 views
15

libfoo.so.1 (즉, SONAME)을 (다른 공유 라이브러리를 통해) 종속성 중 하나로로드하는 실행 파일이 Linux에 있습니다. 또한 다른 시스템 라이브러리에 연결되어 시스템 버전 libfoo.so.2에 연결됩니다. 결과적으로 libfoo.so.1libfoo.so.2이 실행 중에로드되고 버전 1의 라이브러리에서 함수를 호출해야하는 코드는 일부 심볼이 남아 있기 때문에 버전 2 인 최신 시스템 라이브러리에서 (바이너리 호환되지 않는) 함수를 호출합니다. 똑같다. 결과는 일반적으로 스택 스매싱과 후속 segfault입니다.다른 버전의 여러 공유 라이브러리로드 중

이전 버전의 라이브러리는 닫힌 소스 타사 라이브러리이므로 컴파일 할 때 libfoo 버전을 제어 할 수 없습니다. 그 외에 다른 옵션은 현재 libfoo.so.2과 연결된 시스템 라이브러리를 재구성하여 libfoo.so.1과 연결하는 것입니다.

이전 링크 libfoo과 연결된 로컬 복사본이있는 시스템 라이브러리를 바꾸는 방법이 있습니까? 두 라이브러리를 모두로드하고 올바른 버전의 심볼을 호출하는 코드를 가질 수 있습니까? 그래서 특별한 심볼 레벨 버전 관리가 필요합니까?

+0

Alex : 어떻게 문제를 해결 했습니까? 그걸 우리와 나누어 주시겠습니까? – Nawaz

+0

@ Nawaz 정확히 기억하지 못한다. 9 년 전이었다. 포기하고 그것을 만들었으므로 라이브러리의 한 버전 만로드되었습니다. –

+0

Alex [이 기사] (https://blog.habets.se/2012/05/Shared-libraries-diamond-problem.html)에서는이 문제에 대해 이야기하고 해결책을 제안했습니다. 나는 아직 그것을 시도하지 않았다. 그러나 알고/탐색하는 것은 흥미 롭습니다. – Nawaz

답변

0

나는 단지 문제를 해결할 수 있습니다. 어떤 정적으로 당신이 사용하는 "시스템 라이브러리"의 버전을 연결하는 것입니다. 정적 빌드의 경우 타사 라이브러리와 동일한 이전 버전과 링크 할 수 있습니다. 새로운 버전에 의존하지 않는다는 것을 감안할 때 ...

아마도 타사 라이브러리에 일반적인 방식으로 연결하지 않으면 이러한 문제를 피할 수 있습니다. 대신 프로그램이 실행 시간에로드 할 수 있습니다. 아마 그때 그것은 나머지에 대한 그림자 수 있습니다. 그러나 나는 그것에 대해 많이 모른다.

7

당신은 어떤 버전의 스크립트 트릭을 할 수 있습니다

http://sunsite.ualberta.ca/Documentation/Gnu/binutils-2.9.1/html_node/ld_26.html

명시 적 및 마스크 일부 기호를 수출 libfoo.so.1.0에에 끌어 당신의 lib 디렉토리의 래퍼를 작성하는 것이이 필요할 수 있습니다 다른 모든 사람들은 지역의 사람들입니다. 예 :

MYSYMS { 글로벌 : foo1; foo2; 로컬 : *; };

하고 래퍼 같은 것을 연결할 때이 사용

GCC는 -Wl, -shared - 버전 스크립트, mysyms.map -o MYLIB wrapper.o -lfoo -L/경로 /에/foo는. so.1

이것은 libfoo.so.1의 심볼을 래퍼에 국한시키고 주 EXE에는 사용할 수 없게해야합니다.