2017-03-23 9 views
1

나는 실행 파일과 동적으로 링크 된 라이브러리로 구성된 임베디드 리눅스 C++ 응용 프로그램에 문제가 있습니다. 실행 파일은 라이브러리의 진입 점 중 하나 인 함수를 호출하지만 그 함수는 오동작합니다. gdb를 사용하여 조사한 결과 라이브러리 내의 다른 함수 xyz()를 호출해야하는 라이브러리 함수가 실제로 실행 파일 내에서 동일한 이름 xyz()의 함수를 호출한다는 것을 알았습니다.리눅스 라이브러리는 실행 파일에서 모호하게 이름 지정된 함수를 호출합니다 - 이것이 가능합니까?

나는 이것이 일어날 수있어서 매우 놀랍다. 어쩌면 나는 어리석은 짓을하고있다. 실행 파일을 참조하지 않고 라이브러리 자체에 링크되어 있지 않습니까? 실행 파일이 실행 파일에서 abc() 대신 라이브러리에서 abc()를 호출하면 라이브러리와 적어도 연결되어 있기 때문에 약간 더 이해할 수 있습니다.이 경우 링커는 이중 정의를 나타냅니다 ? 또는 로컬 기능의 우선 순위를 결정 하시겠습니까?

내 함수의 이름을 바꿀 수있어 이름이 일치하지 않지만 어떤 일이 벌어지고 있는지 이해하고 싶습니다. 나는이 영역이나 gcc 도구에 대해 많은 경험이 없다. 첫째, 위 시나리오에서 가능한 일이라고 생각합니까?

실행 파일과 라이브러리 모두 다른 라이브러리를 호출합니다. 사용중인 라이브러리의 link 명령은 다음과 같습니다.

powerpc-unknown-linux-gnuspe-g ++ - 4.9.3 aaa.o bbb.o [etc] -shared -o libmylibary.so -L ../otherlibpath -Wl, -rpath-link, ../otherlibpath -lotherlibname

+0

실행 파일에 대한 연결 명령은 어떻게됩니까? '-rdynamic'을 사용합니까? –

+0

@ WumpusQ.Wumbley : -rdynamic을 사용하지 않습니다. -Wl, -rpath-link, ../otherlibpath -lotherlibname -Wl, -Bstatic -lxxx -Wl, -Bdynamic -lmylibrary 여기서 lxxx는 정적으로 연결된 라이브러리이고 otherlib는 둘 다 연결된 동적 라이브러리입니다. 위에서 언급 한 것입니다. 귀하의 질문에 감사드립니다. – Spalteer

답변

1

동적 링커가 작동하는 방식입니다. 실행 가능한 기호는 동적 라이브러리의 기호보다 우선 순위가 높습니다. 동적 라이브러리 디자이너는이를 알고 있어야합니다. 그녀는 불필요한 기호 불일치를 피하기위한 조치를 취해야합니다. 대부분의 라이브러리는 다음을 사용합니다 :

  • C++의 경우 네임 스페이스를 사용합니다. 라이브러리에서 내 보낸 모든 심볼은 라이브러리 네임 스페이스에 있어야합니다.
  • C의 경우 내 보낸 모든 기호에 이름 접두사 또는 접미사를 사용합니다. 예를 들어 OpenSSL 라이브러리는 접두어 SSL_을 사용하고 공용 함수는 SSL_set_mode()과 같은 이름을 가지므로 원하지 않는 심볼 충돌이 방지됩니다.
  • 라이브러리에서 비공개로 간주되는 기호를 내 보내지 마십시오. 심볼이 라이브러리에서 내보내지지 않으면 동적 링커는 라이브러리의 로컬 심볼을 사용합니다. #pragma visibility 님은 친구입니다. 중복 기호 라이브러리가 제 3 자 라이브러리이며, 저자는 함수의 이름을 바꾸거나 아마도 라이브러리 업데이트를 저자에게 물어 다음 위의 권장 사항을 준수하지 않는 경우 https://gcc.gnu.org/wiki/Visibility

를 참조하십시오. 위의 링크에서

void exported_function1(int); 
void exported_function2(int); 
#pragma GCC visibility push(hidden) 
void private_function1(int); 
void private_function2(int); 
#pragma GCC visibility pop 

세부 사항 :

편집

수출/수출 #pragma visibility 지침 (GCC 특정 확장자)에 의해 제어 될 수 없습니다.

+0

실행 파일을 내보내는 실행 파일을 어떻게 금지합니까?그것은 (nm -D 또는 readelf --dyn-syms로 보이는) 모두를 내보내는 것처럼 보이지만 실행 파일이 일반적으로 어떤 것을 내보내려고하지 않을 것이라고 생각했을 것입니다. – Spalteer

+0

더 많은 것을 실험 했으므로 함수 이름은 다음과 같습니다. 실행 파일에 의해 익스포트되는 것은 링크되는 동적 라이브러리의 함수 이름과 정확히 일치하는 것입니다. 그것을 막으려면 컴파일에 -fvisibility = hidden을 추가하고 실행 파일에 대한 링크 명령을 추가했습니다. 그래서 문제가 해결되었습니다. 이제 라이브러리는 자체 버전의 함수를 호출합니다. – Spalteer

+1

라이브러리는'-fvisibility = hidden'으로 실행 파일을 컴파일 할 때 라이브러리가 심볼을 실행 파일에서 볼 수 없기 때문에 작동합니다. 그러나 여전히 라이브러리 사이의 기호 불일치 가능성이 있습니다. 라이브러리 기호 가시성을 제한하는 것이 좋습니다. 편집을 참조하십시오. –