python 分机上的地址消毒器
Address Sanitizer on a python extension
我正在尝试使用 Address Sanitizer 编译 python 扩展。当我加载扩展时,我得到
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 得到了 clang)。
那么,如何使 Address Sanitizer 与共享对象库一起工作?
要么,我需要 libasan.so
的正确版本(它似乎不在 deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main 中,或者我需要一种方法让 clang link静态)。
我的 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
可执行文件),您应该
- 将
-shared-libasan
添加到 LDFLAGS
(Clang 默认为 -static-libasan
,与 GCC 不同)
- 运行 和
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)
(它应该在标准 Clang 库的某个地方)
(参见 AddressSanitizerAsDso wiki)。
另一种选择是使用 GCC,在这种情况下不需要 -shared-libasan
,LD_PRELOAD
值变为 libasan.so.N
(N
取决于 GCC 版本,使用 $(gcc -print-file-name=libasan.so)
找到它)。
有关 GCC 和 Clang 在清理 shlib 方面的差异的更多详细信息,请参阅 。
我正在尝试使用 Address Sanitizer 编译 python 扩展。当我加载扩展时,我得到
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 得到了 clang)。
那么,如何使 Address Sanitizer 与共享对象库一起工作?
要么,我需要 libasan.so
的正确版本(它似乎不在 deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main 中,或者我需要一种方法让 clang link静态)。
我的 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
可执行文件),您应该
- 将
-shared-libasan
添加到LDFLAGS
(Clang 默认为-static-libasan
,与 GCC 不同) - 运行 和
LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)
(它应该在标准 Clang 库的某个地方)
(参见 AddressSanitizerAsDso wiki)。
另一种选择是使用 GCC,在这种情况下不需要 -shared-libasan
,LD_PRELOAD
值变为 libasan.so.N
(N
取决于 GCC 版本,使用 $(gcc -print-file-name=libasan.so)
找到它)。
有关 GCC 和 Clang 在清理 shlib 方面的差异的更多详细信息,请参阅