공유 라이브러리가 다른 공유 라이브러리에 의존하는 경우 동적 링커가 참조를 확인할 수 없는 이유는 무엇입니까?

공유 라이브러리가 다른 공유 라이브러리에 의존하는 경우 동적 링커가 참조를 확인할 수 없는 이유는 무엇입니까?

암호:

//a.c   I don't use header files as this is just for demo purpose.
extern void function_b(int num);
void function_a(int num) {
   function_b(num)
}
//b.c
void function_b(int num) {
   ...
}
//dll.c 
#include <dlfcn.h>
int main() {
   void *handle_a;
   void *handle_b;
   void (*pfunc_a)(int);
   ...
   handle_a = dlopen("./a.so", RTLD_LAZY);
   ...
   pfunc_a = dlsym(handle_a, "function_a");
   ...
   handle_b = dlopen("./b.so", RTLD_GLOBAL);
   ...
   pfunc_a(2020);
   ...
   return 0;
}

dll.c런타임에 공유 라이브러리를 로드하려고 시도하는 것을 볼 수 있으며 모듈 a에는 참조가 있고 function_b모듈 b에는 정의가 있습니다 function_b. 공유 라이브러리를 생성하여 프로그램이 실행되기 전에 디스크에 존재하지만 프로그램을 실행하면 기호 조회 오류가 발생한다고 가정 a.so합니다 b.so.

./a.so:undefined symbol: function_b

handle_a = dlopen("./a.so", RTLD_LAZY); 하지만 여기서 사용하고 있는 이 코드 줄을 사용하면 RTLD_LAZY런타임 링커가 기호를 확인하려고 시도하지 않으며 이전에 호출할 function_b기회를 얻습니다 . 이런 식으로 동적 링커는 b.so의 정의를 사용하여 참조를 수정 합니다.dlopen("b.so", RTLD_GLOBAL)function_aa.sofunction_b

내 질문은 다음과 같습니다

  • 내 이해가 맞습니까? 동적 링커는 섹션에 있는 function_b의 명령 주소 에 연결/재배치할 수 있도록 .got또는 .got.plt섹션을 수정해야 합니다 .a.so.textb.so

  • function_b내 이해가 맞다면 이 경우 동적 링커가 여전히 해결되지 않는 이유는 무엇입니까?

답변1

문제는 동적 링커가 를 확인할 수 없다는 것이 function_b아니라 두 번째 호출이 dlopen올바르지 않다는 것입니다.필요포함 RTLD_LAZY하거나RTLD_NOW, 다른 플래그는 이 두 플래그를 보완합니다.

다음 두 값 중 하나를 포함해야 합니다.배너:

b.so부하를 다음으로 변경하세요.

handle_b = dlopen("./b.so", RTLD_NOW | RTLD_GLOBAL);

작업 프로그램을 생성합니다.

각 호출은 로드된 마지막 라이브러리이기 때문에 와 ; 사이에서 선택 dlopen해야 합니다 . 위에서 지정했지만(지연 로딩에서는 아무 것도 얻지 못함) 이 경우에도 잘 작동합니다. 이 외에도 다른 플래그를 추가할 수 있습니다. 실행 시 찾을 수 있도록 기호를 전역적으로 사용할 수 있어야 하기 때문입니다 .RTLD_LAZYRTLD_NOWb.soNOWLAZYRTLD_GLOBALb.sofunction_afunction_b

바라보다의 예dlopen(3)수행해야 할 오류 처리 dlopen등에 대한 세부 정보를 통해 문제를 밝힙니다.

관련 정보