Настроить проект автоинструментов с помощью дезинфицирующих средств Clang в конфигурации статической библиотеки?

РЕДАКТИРОВАНИЕ: если это TLDR, просто пропустите его вниз. Здесь я спрашиваю: Как мне настроить проект autotools для использования статической библиотеки?

Я работаю с парой библиотек с открытым исходным кодом и пытаюсь запустить их набор тестов под дезинфицирующими средствами Clang. Чтобы работать под дезинфицирующими средствами Clang, нам нужно (1) указать некоторые параметры и (2) при необходимости связать статические библиотеки из Clang Compiler-RT. Примечание: динамических библиотек или общих объектов нет.

Установить параметры легко:

export DYLD_FALLBACK_LIBRARY_PATH=/usr/local/lib/clang/3.3/lib/darwin/
export CC=/usr/local/bin/clang
export CXX=/usr/local/bin/clang++
export CFLAGS="-g3 -fsanitize=address -fsanitize=undefined"
export CXXFLAGS="-g3 -fsanitize=address -fsanitize=undefined -fno-sanitize=vptr"

./configure

Однако при этом будут генерироваться некоторые предупреждения архива (при запуске AR) и ошибки связи (при запуске LD) с неопределенными символами. Сообщение будет похоже на:

libjpeg.a(jmemmgr.o): In function `do_sarray_io':
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to
`__ubsan_handle_type_mismatch'
/home/jwalton/jpeg-6b/jmemmgr.c:695: undefined reference to
`__ubsan_handle_type_mismatch'
/home/jwalton/jpeg-6b/jmemmgr.c:696: undefined reference to
`__ubsan_handle_type_mismatch'

Я знаю библиотеки, которые нужно слинковать. Для дезинфицирующих средств, которые я использую, это libclang_rt.asan_osx.a и libclang_rt.ubsan_osx.a (или libclang_rt.full-x86_64.a и libclang_rt.ubsan-x86_64.a в Linux).

Чтобы предоставить библиотеки, я экспортирую следующее. Примечание: это LIBS, а не LDLIBS, как ожидается большинством других инструментов, связанных с make.

export LIBS="/usr/local/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx.a \
             /usr/local/lib/clang/3.3/lib/darwin/libclang_rt.ubsan_osx.a"

Это приводит к configure проблеме:

configure: error: cannot run C compiled programs.
If you meant to cross compile, use `--host'.
...

Глядя на config.log, похоже, возникают две проблемы. Во-первых, путь сокращается путем изменения /usr/local/... на /Users/jwalton/.... И во-вторых, имя файла забивается путем изменения статической библиотеки на динамическую:

configure:3346: ./conftest
dyld: Library not loaded: /Users/jwalton/clang-llvm/llvm-3.3.src/Release+Asserts/lib/clang/3.3/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
  Referenced from: /Users/jwalton/libpng-1.6.7/./conftest
Reason: image not found

В другой попытке я попытался использовать LDFLAGS:

export LDFLAGS="-L/usr/local/lib/clang/3.3/lib/darwin/"
export LIBS="libclang_rt.asan_osx.a libclang_rt.ubsan_osx.a"

Это приводит к аналогичной ошибке:

configure: error: in `/Users/jwalton/libpng-1.6.7':
configure: error: C compiler cannot create executables

И config.log:

configure:3209: /usr/local/bin/clang -g3 -fsanitize=address -fsanitize=undefined  -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c libclang_rt.asan_osx.a libclang_rt.ubsan_osx.a >&5
clang: error: no such file or directory: 'libclang_rt.asan_osx.a'
clang: error: no such file or directory: 'libclang_rt.ubsan_osx.a'

И удаление префикса lib и суффикса .a из LIBS приводит к:

configure:3209: /usr/local/bin/clang -g3 -fsanitize=address -fsanitize=undefined  -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c clang_rt.asan_osx clang_rt.ubsan_osx >&5
clang: error: no such file or directory: 'clang_rt.asan_osx'
clang: error: no such file or directory: 'clang_rt.ubsan_osx'

И добавление -l к LIBS приводит к:

configure:3335: /usr/local/bin/clang -o conftest -g3 -fsanitize=address -fsanitize=undefined  
    -L/usr/local/lib/clang/3.3/lib/darwin/ conftest.c -lclang_rt.asan_osx -lclang_rt.ubsan_osx >&5
configure:3339: $? = 0
configure:3346: ./conftest
dyld: could not load inserted library: /Users/jwalton/libpng-1.6.7/./conftest

./configure: line 3348: 38224 Trace/BPT trap: 5       ./conftest$ac_cv_exeext

Наконец, допустим аргумент -L:

$ ls /usr/local/lib/clang/3.3/lib/darwin/
libclang_rt.10.4.a          libclang_rt.ios.a
libclang_rt.asan_osx.a          libclang_rt.osx.a
libclang_rt.asan_osx_dynamic.dylib  libclang_rt.profile_ios.a
libclang_rt.cc_kext.a           libclang_rt.profile_osx.a
libclang_rt.cc_kext_ios5.a      libclang_rt.ubsan_osx.a
libclang_rt.eprintf.a

После всей предыстории: как настроить проект autotools для использования статической библиотеки?

Бонусные баллы: почему что-то настолько простое стало таким сложным?


person jww    schedule 22.11.2013    source источник


Ответы (3)


Поставляемые версии GNU libtool не передают аргументы -fsanitize=... компоновщику. Вам потребуется обновить libtool с помощью патча с http://savannah.gnu.org/patch/?8775 В частности:

diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
index 0c40da0..b99b0cd 100644
--- a/build-aux/ltmain.in
+++ b/build-aux/ltmain.in
@@ -5362,10 +5362,11 @@ func_mode_link ()
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
+      # -fsanitize=*         Clang memory and address sanitizer
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
       -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
-      -specs=*)
+      -specs=*|-fsanitize=*)
         func_quote_for_eval "$arg"
    arg=$func_quote_for_eval_result
         func_append compile_command " $arg"

Что касается того, чтобы заставить libtool принимать статическую библиотеку, вы должны иметь возможность просто указать полный путь к статической библиотеке в командной строке или использовать такие параметры, как -L/usr/local/lib/clang/3.3/lib/darwin/ -lclang_rt.ubsan_osx. Тем не менее, cfe должен позаботиться о магии библиотек за вас, как только libtool скажет использовать -fsanitize=... для компоновки.

person Jeremy Huddleston Sequoia    schedule 19.10.2015
comment
Ах, идеально. Спасибо большое. Я не буду вносить эти изменения, но это ясно показывает, что это проблема Autotools и решение для дезинфицирующих средств. Вероятно, они также должны проверить отсутствие дезинфицирующего средства. Например, для CXXFLAGS я использую следующее: -fsanitize=undefined -fno-sanitize=vptr. - person jww; 19.10.2015
comment
Если вы используете MacPorts, вы можете просто установить порт libtool. У него уже есть патч. Вам нужно будет перезапустить autoreconf или glibtoolize в зависимости от ситуации в вашем проекте, чтобы получить более новую версию, но это должно помочь. - person Jeremy Huddleston Sequoia; 19.10.2015

Вам также необходимо добавить флаги -fsanitize в LDFLAGS.

person BenPope    schedule 19.12.2013
comment
Небольшое замечание: когда я это делал, «либубсан» линковался динамически, хотя я явно указывал на статическую линковку. Решением было не использовать -fsanitize в LDFLAGS, а добавить туда полный путь к статической библиотеке libubsan.a. - person Hi-Angel; 19.05.2015
comment
@Hi-Angel Для GCC каноническим решением является использование -static-libubsan. - person yugr; 13.01.2017

Что касается проблемы с неопределенными символами, если вы связываете объекты C++, вы должны использовать clang++ вместо clang. В противном случае вы можете получить ошибку, например:

/bin/bash libtool --tag=CC --mode=link clang-3.6 ... -fsanitize=undefined -o freeswitch ...
libtool: link: clang-3.6 ... -fsanitize=undefined -o .libs/freeswitch ./.libs/libfreeswitch.so ...
./.libs/libfreeswitch.so: undefined reference to `__ubsan_vptr_type_cache'
./.libs/libfreeswitch.so: undefined reference to `__ubsan_handle_dynamic_type_cache_miss'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

В приведенном выше случае злобный libtool использовал clang вместо clang++, потому что automake думал, что вы хотите связать набор объектов C (он не понимает, что связывание архива libtool (libfreeswitch.la) с помощью C++ означает, что необходим компоновщик C++ (примечание см. также https://lists.debian.org/debian-mentors/2003/06/msg00004.html.

Чтобы обойти эту проблему, следуйте инструкциям на странице https://www.gnu.org/software/automake/manual/html_node/Libtool-Convenience-Libraries.html и добавьте (фиктивный/настоящий) исходный код C++ в свои исходники в Makefile.am:

SUBDIRS = sub1 sub2 …
lib_LTLIBRARIES = libtop.la
libtop_la_SOURCES =
# Dummy C++ source to cause C++ linking.
nodist_EXTRA_libtop_la_SOURCES = dummy.cxx
libtop_la_LIBADD = \
  sub1/libsub1.la \
  sub2/libsub2.la \
  …
person Lekensteyn    schedule 22.07.2015