Я пытаюсь скомпилировать расширение Python с помощью Address Sanitizer. Когда я загружаю расширение, я получаю
Traceback (most recent call last):
File "test.py", line 2, in <module>
from extension import package
File "/tmp/python_test/extension/package.py", line 28, in <module>
from extension._ext import *
ImportError: /tmp/python_test/extension/_ext.so: undefined symbol: __asan_version_mismatch_check_v8
Вызов компилятора
clang -g -o _ext.so code.ll -fsanitize=address -lrt -lpthread -ldl -lstdc++ -lm -fPIC -shared
Значит, он не загружает символы из asan правильно. Я пробовал использовать-static-libsan
, но результат был таким же.
Я видел, что некоторые люди используютLD_PRELOAD
чтобы получить Asan в общих объектах, однако кажется, чтоlibasan.so
в моей системе используется другая версия Address Sanitizer (установленная из пакета Debian libasan3, в то время как я получил лязг от deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main).
Итак, как я могу заставить Address Sanitizer работать с библиотекой общих объектов? Либо мне нужна правильная версияlibasan.so
(который, похоже, не находится в deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main, или мне нужен способ статической ссылки clang).
Моя версия clang:
$ clang -v
clang version 8.0.0-svn356034-1~exp1~20190313094216.53 (branches/release_80)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.3.0
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/6.3.0
Candidate multilib: .;@m64
Selected multilib: .;@m64
Чтобы очистить отдельную библиотеку (без очистки основнойpython
исполняемый файл) с помощью Clang вы должны
-shared-libasan
кLDFLAGS
(Clang по умолчанию-static-libasan
, в отличие от GCC)LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)
(он должен быть где-то со стандартными библиотеками Clang)(см. вики AddressSanitizerAsDso ).
Другой вариант - использовать GCC, и в этом случае-shared-libasan
не нужен иLD_PRELOAD
значение становитсяlibasan.so.N
(N
зависит от версии GCC, используйте$(gcc -print-file-name=libasan.so)
чтобы найти его).
Дополнительные сведения о различиях между GCC и Clang в отношении очистки шлибов см. В этом ответе .
DYLD_INSERT_LIBRARIES
вместоLD_PRELOAD
Stuart Berg