问题描述
我正在尝试使用Address Sanitizer编译python扩展。加载扩展程序时,我得到
I am trying to compile a python extension with Address Sanitizer. When I load the extension, I get
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
,但结果是相同的。
So, it does not load symbols from asan correctly. I've tried using -static-libsan
, but the result was the same.
我已经看到有些人使用 LD_PRELOAD
来使Asan进入共享对象,但是,似乎我系统上的 libasan.so
来自不同版本的Address Sanitizer(是从Debian的libasan3软件包安装的,而我从deb llvm-toolchain-stretch-8 main)。
I've seen that some people use LD_PRELOAD
to get Asan into shared objects, however, it seems that the libasan.so
on my system is from a different version of Address Sanitizer (Installed from Debian's libasan3 package, while I got clang from deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main).
那么,如何使Address Sanitizer与共享库一起工作?
要么,我需要 libasan.so
的正确版本(似乎不在deb llvm-toolchain-stretch-8 main,或者我需要一种方法来静态地建立clang链接)。
So, how can I make Address Sanitizer work with a shared object library?Either, I need the correct version of libasan.so
(which does not seem to be in deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main, or I need a way to have clang link that statically).
我的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
推荐答案
要消毒单个您应该使用Clang库(不对主要的 python
可执行文件进行消毒)
To sanitize a single library (without sanitizing main python
executable) with Clang you should
- 添加
-shared-libasan
到LDFLAGS
(Clang默认为-static-libasan
,与GCC不同) - 运行
LD_PRELOAD = $(clang -print-file-name = libclang_rt.asan-x86_64.so)
(应该
- add
-shared-libasan
toLDFLAGS
(Clang defaults to-static-libasan
, unlike GCC) - run with
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)
(it should be somewhere with standard Clang libs)
(请参见)。
另一种方法是使用GCC,在这种情况下共享-libasan
不需要,并且 LD_PRELOAD
的值变为 libasan.so.N
( N
取决于GCC版本,请使用 $(gcc -print-file-name = libasan.so)
查找)。
Another option is using GCC, in which case -shared-libasan
is not needed and LD_PRELOAD
value becomes libasan.so.N
(N
depends on GCC version, use $(gcc -print-file-name=libasan.so)
to locate it).
有关GCC和Clang在shlibs消毒方面的区别的更多详细信息,请参见。
For more details on differences between GCC and Clang with respect to sanitization of shlibs see this answer.
这篇关于在python扩展上解决Sanitizer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!