C

거믄마루 2013. 1. 14. 17:45

LINUX 에서 DNS 에서 MX 레코드를 알아오려고 resolv 라이브러리를 링크시켜서 잘 돌아가는 것 확인하고

실행파일을 원격의 서버에 복사하고 실행했더니...


/lib64/libresolv.so.2: version `GLIBC_2.9' not found


이러고 있다. ㅡ.ㅡ; 알고보니 glibc 버전이 낮아서 발생하는 문제, 즉, DNS MX 레코드를 쿼리하는 resolv 라이브러리 함수에서 다시 동적 라이브러리 GLIBC 의 함수를 사용하는데 이런 경우 GLIBC 링크시 높은 곳에서 빌드하게 되면 버전이 낮은 곳에서는 실행시 이를 동적으로 링크할 수 없게 되어 프로그램을 실행할 수 없게되는 것이다. 


이건 빌드하는 쪽의 GLIBC 버전 확인

$ rpm -qa | grep glibc
glibc-devel-2.12-1.80.el6_3.6.x86_64
glibc-2.12-1.80.el6_3.6.x86_64
glibc-common-2.12-1.80.el6_3.6.x86_64
glibc-2.12-1.80.el6_3.6.i686
glibc-headers-2.12-1.80.el6_3.6.x86_64
glibc-static-2.12-1.80.el6_3.6.x86_64

이건 타깃 쪽의 GLIBC 버전 확인

$ rpm -qa | grep glibc
glibc-2.5-81
compat-glibc-2.3.4-2.26
glibc-2.5-81
glibc-devel-2.5-81
glibc-common-2.5-81
glibc-headers-2.5-81
compat-glibc-2.3.4-2.26
glibc-devel-2.5-81
compat-glibc-headers-2.3.4-2.26


위에서 보는 바와 같이 타깃쪽이 버전이 더 낮다.  그렇다고 타깃의 버전을 무작정 올릴 수는 없다. 혼자 쓰는 피씨도 아니고 맘대로 라이브러리 버전 올리는 것은 꿈도 못꾼다고 보면 된다. 보통 경험이 없는 경우에는 패닉에 빠지게 되지만 당황하지 말고 resolv 라이브러리가 GLIBC 를 우회하도록 resolv 라이브러리를 정적으로 링크하도록 다시 빌드하면 된다.


실제 방법은 다음과 같다. -Wl,-Bstatic 과 -Wl,-Bdynamic 옵션사이에 정적으로 링크해야할 라이브러리 링크 옵션을 집어넣고 링크하면 된다.


cc -L /usr/lib -L /usr/local/lib -g -O0  \
        무슨무슨파일.o 그런그런파일.o 이런이런파일.o 저런저런파일.o  \
        -l pthread \
        -Wl,-Bstatic -l resolv -Wl,-Bdynamic \
        -o 실행파일명

모처럼의 삽질에 즐거운 오후...