공유 라이브러리에서 해결되지 않은 기호를 쉽게 확인 하시겠습니까?

StackOverflow https://stackoverflow.com/questions/1617286

  •  06-07-2019
  •  | 
  •  

문제

상당히 큰 C ++ 공유 객체 라이브러리를 작성하고 있으며 디버깅을 통증으로 만드는 작은 문제를 해결했습니다.

헤더 파일에서 함수/메소드를 정의하고 (개발 중에) 스터브를 작성하는 것을 잊어 버린 경우, 실행 파일이 아닌 공유 객체 라이브러리로 빌드하고 있기 때문에 컴파일 타임에 오류가 나타나지 않기 때문입니다. 그 기능을 구현하는 것을 잊었습니다. 내가 무언가 잘못되었다는 것을 알게 된 유일한 방법은 런타임에있는 것입니다. 결국이 라이브러리에 링크하는 응용 프로그램이 '정의되지 않은 기호'오류로 넘어갑니다.

컴파일 시간에 필요한 모든 기호가 있는지 확인하는 쉬운 방법을 찾고 있습니다.

내가 생각한 한 가지 해결책은 컴파일 된 라이브러리를 통해 nm -C -U 정의되지 않은 모든 참조 목록을 얻으려면. 문제는 이것이 GLIBC와 같은 다른 라이브러리에있는 모든 참조 목록을 제시한다는 것입니다. 물론 최종 응용 프로그램이 구성 될 때이 라이브러리와 함께 연결됩니다. 출력을 사용하는 것이 가능합니다 nm 에게 grep 내 모든 헤더 파일을 통해 이름이 해당하는지 확인하십시오. 그러나 이것은 미쳤습니다. 확실히 이것은 드문 문제가 아니며 그것을 해결하는 더 좋은 방법이 있습니까?

도움이 되었습니까?

해결책

링커 옵션을 확인하십시오 -z defs / --no-undefined. 공유 객체를 만들 때 해결되지 않은 기호가 있으면 링크가 실패하게됩니다.

GCC를 사용하여 링커를 호출하는 경우 컴파일러를 사용합니다. -Wl 옵션을 링커로 전달하는 옵션 :

gcc -shared ... -Wl,-z,defs

예를 들어 다음 파일을 고려하십시오.

#include <stdio.h>

void forgot_to_define(FILE *fp);

void doit(const char *filename)
{
    FILE *fp = fopen(filename, "r");
    if (fp != NULL)
    {
        forgot_to_define(fp);
        fclose(fp);
    }
}

이제 공유 객체로 만들면 성공할 것입니다.

> gcc -shared -fPIC -o libsilly.so silly.c && echo succeeded || echo failed
succeeded

하지만 추가하면 -z defs, 링크가 실패하고 누락 된 기호에 대해 알려줍니다.

> gcc -shared -fPIC -o libsilly.so silly.c -Wl,-z,defs && echo succeeded || echo failed
/tmp/cccIwwbn.o: In function `doit':
silly.c:(.text+0x2c): undefined reference to `forgot_to_define'
collect2: ld returned 1 exit status
failed

다른 팁

Linux에서 (사용중인 것 같습니다) ldd -r a.out 당신이 찾고있는 답변을 정확히 주어야합니다.

업데이트 : 사소한 만드는 방법 a.out 확인하기 위해 :

 echo "int main() { return 0; }" | g++ -xc++ - ./libMySharedLib.so
 ldd -r ./a.out

테스트 수양은 어떻습니까? 필요한 기호에 연결되는 모의 실행 파일을 만듭니다. 링크가 실패하면 라이브러리 인터페이스가 불완전하다는 것을 의미합니다.

한 번도 같은 문제가있었습니다. C ++에서 구성 요소 모델을 개발하고 있었으며 물론 런타임에 동적으로 구성 요소를로드해야합니다. 세 가지 솔루션이 떠 오릅니다.

  1. 시간을내어 정적으로 컴파일 할 수있는 빌드 시스템을 정의하십시오. 엔지니어링 시간을 잃을 수 있지만 성가신 런타임 오류를 잡는 데 많은 시간을 절약 할 수 있습니다.
  2. 잘 알려진 잘 알려진 섹션으로 기능을 그룹화하여 함수/스터브를 그룹화하여 각 해당 기능에 스터브가 있는지 확인할 수 있습니다. 문서를 잘 문서화하는 데 시간이 걸리면 정의를 확인하는 스크립트 (예 : Doxygen 주석을 통해)를 작성하고 해당 .CPP 파일을 확인할 수 있습니다.
  3. 동일한 라이브러리 세트를로드하고 rtld_now 플래그를 dlopen ( *nix 아래에있는 경우)에 지정하는 여러 테스트 실행 파일을 수행하십시오. 그들은 누락 된 기호를 신호합니다.

도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top