python 扩展上的地址消毒剂

Ale*_*lex 8 python clang address-sanitizer

我正在尝试使用 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
Run Code Online (Sandbox Code Playgroud)

编译器调用是

clang -g -o _ext.so code.ll -fsanitize=address -lrt -lpthread -ldl -lstdc++ -lm -fPIC -shared
Run Code Online (Sandbox Code Playgroud)

因此,它不会从 asan 正确加载符号。我试过使用-static-libsan,但结果是一样的。

我已经看到有些人习惯LD_PRELOAD将 Asan 放入共享对象中,但是,似乎libasan.so我系统上的 Address Sanitizer 来自不同版本的 Address Sanitizer(从 Debian 的 libasan3 包安装,而我从 deb http://apt .llvm.org/stretch/ llvm-toolchain-stretch-8 主)。

那么,如何使 Address Sanitizer 与共享对象库一起使用?要么,我需要正确的版本libasan.so(它似乎不在 deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main 中,或者我需要一种方法来静态地获得 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
Run Code Online (Sandbox Code Playgroud)

yug*_*ugr 14

python使用 Clang清理单个库(不清理主可执行文件),您应该

  • 添加-shared-libasanLDFLAGS-static-libasan与 GCC 不同,Clang 默认为)
  • 运行LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)(它应该在标准 Clang 库的某个地方)

(请参阅AddressSanitizerAsDso wiki)。

另一种选择是使用 GCC,在这种情况下-shared-libasan不需要,LD_PRELOAD值变为libasan.so.NN取决于 GCC 版本,用于$(gcc -print-file-name=libasan.so)定位它)。

有关 GCC 和 Clang 之间在 shlib 清理方面的差异的更多详细信息,请参阅此答案

  • 对于 Mac 用户:使用“DYLD_INSERT_LIBRARIES”而不是“LD_PRELOAD” (3认同)