ShlibvisibilityChecker는 공유 라이브러리에서 불필요하게 내보내는 내부 기호를 찾는 작은 도구입니다. 그러한 기호는 원인이기 때문에 바람직하지 않습니다
--gc-sections 의 효과적인 회전) ShlibvisibilityChecker는 공유 라이브러리에서 수출 된 API에 대해 공개 헤더에서 선언 한 API를 비교하고 불일치에 대한 경고를 비교합니다. 대부분의 경우 이러한 기호는 숨겨져야하는 내부 라이브러리 기호입니다 (드문 경우에는 동일한 패키지의 다른 라이브러리 또는 실행 파일이 사용하는 내부 기호이며 shlibvischeck-debian 그러한 경우를보고하지 않기를 어렵습니다).
그런 다음 이러한 불일치는 -fvisibility=hidden 으로 패키지를 다시 컴파일하여 고정해야합니다 (자세한 내용은 여기 참조). 일반적인 AutoConf 프로젝트의 일반적인 수정 사항은 여기에서 찾을 수 있습니다.
ShlibvisibilityChecker는 100% 정확 하지 않고 가시성 주석으로부터 가장 혜택을 줄 수있는 패키지를 찾는 데 도움을 제공합니다 (현대 배포판에서 가시성이있는 상황이 얼마나 나쁜지 이해하기 위해).
원시 패키지를 확인하려면 많은 헤더 및 공유 Libs가 소스 및 이진 인터페이스를 수집하여 비교합니다.
$ bin/read_header_api --only-args /usr/include/xcb/* > api.txt
$ ./read_binary_api --permissive /usr/lib/x86_64-linux-gnu/libxcb*.so > abi.txt
$ vimdiff api.txt abi.txt # Or `comm -13 api.txt abi.txt'
또 다른 유용한 시나리오는 데비안 패키지의 공유 라이브러리에서 내보내지 만 헤더에서 선언되지 않은 기호를 찾는 것입니다. 이것의 주요 도구는 shlibvischeck-debian 스크립트입니다.
패키지에 적용하려면 실행하십시오
$ shlibvischeck-debian libacl1
The following exported symbols in package 'libacl1' are private:
__acl_extended_file
__acl_from_xattr
__acl_to_xattr
__bss_start
_edata
_end
_fini
_init
closed
head
high_water_alloc
next_line
num_dir_handles
walk_tree
_init 또는 _edata 와 같은 자율 기호 (LD 링커 스크립트 및 LIBGCC 스타트 업 파일로 인해)를 건너 --permissive .
임의의 헤더 및 라이브러리 세트에서 가시성 문제를 확인할 수도 있습니다.
$ shlibvischeck-common --permissive --cflags="-I/usr/include -I$AUDIT_INSTALL/include -I/usr/lib/llvm-5.0/lib/clang/5.0.0/include" $AUDIT_INSTALL/include/*.h $AUDIT_INSTALL/lib/*.so*
빌드 타임 전제 조건은 python3 ( setuptools 모듈), clang , llvm , libclang-dev , g++ 및 make 입니다. 런타임 종속성은 python3 ( python-magic Module), pkg-config 및 aptitude 입니다. 우분투에 모든 것을 설치하려면 실행하십시오
$ sudo apt-get install python3 clang llvm libclang-dev g++ make pkg-config aptitude
$ sudo python3 -mensurepip
$ sudo pip3 install setuptools python-magic
(스크립트 scripts/install-deps.sh 사용할 수도 있습니다).
또한 Ubuntu 소스 패키지에 액세스 할 수 있어야합니다.
$ sudo sed -Ei 's/^# *deb-src /deb-src /' /etc/apt/sources.list
$ sudo apt-get update
파이썬 및 이진 구성 요소는 별도로 구축됩니다.
$ make clean all && make install
$ ./setup.py build && pip3 install .
분석 중에 shlibvischeck-debian 새로운 데비안 패키지를 설치하므로 Chroot 또는 VM에서 실행하는 것이 좋습니다. Chroot 설정에 대한 많은 지침이 있습니다.
분석용 패키지 목록은 데비안 등급에서 얻을 수 있습니다.
$ curl https://popcon.debian.org/by_vote | awk '/^[0-9]+ +lib/{print $2}' > by_vote
$ shlibvischeck-debian $(head -500 by_vote | tr 'n' ' ')
문제가있는 패키지를 찾은 후에는 내부 기호의 가시성을 제한하여이를 고칠 수 있습니다. 패키지의 기호 가시성을 제어하는 가장 좋은 방법은
Makefile.in 또는 CMakeLists.txt )에서 -fvisibility=hidden CFLAGS 에 숨겨져 기본적으로 모든 기호를 숨기십시오.__attribute__((visibility("default"))) 과 함께 공개적으로 가시 함수를 명시 적으로 주석예를 들어 Libcaca의 수정을 참조하십시오.
현재 도구는 데비안 기반 시스템 (예 : 우분투)에서만 작동합니다. 빌드 스크립트는 모든 배포판에서 동일하므로 우분투의 문제를 감지하면 다른 모든 사람들에게도 도움이 될 것입니다.
중요한 설계 문제는이 도구가 API를 통해가 아니라 dlsym 또는 소스 파일의 명시 적 제외 프로토 타입 선언을 통해 간접적으로 사용되는 기호를 감지 할 수 없다는 것입니다. 이것은 같은 프로젝트 내에서 플러그인 또는 단단히 상호 연결된 shlibs에서 발생합니다. 그러한 경우는 희망적으로 드물어야합니다.
shlibvisibilitychecker는 휴리스틱 도구이므로 모든 패키지를 분석 할 수는 없습니다. 현재 성공률은 약 60%입니다. 오류의 주요 이유입니다
libatasmart stddef.h 포함하지 못하고 tdb sys/types.h 포함하지 못함).lzma/container.h )dpkg/macros.h 필요 LIBDPKG_VOLATILE_API 필요합니다)libverto-dev glib 헤더를 사용하지만 이것을 선언하지는 않습니다)기타 문제 :
이 도구는 가시성 주석이 부족한 수많은 패키지를 발견했습니다 (실제로 두 번째 패키지에는 가짜 수출이 있습니다). 다음은 내가 고치려고했던 것입니다.
더 많은 관점 패키지 (Debian Top-100) : Libpopt1, Libgpg-error0, libxml2, libwrap0, libpcre3, libkeyutils1, libedit2, liblcms2-2.