我正在尝试使用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-获得了 clang ) toolchain-stretch-8 main)。

因此,如何使Address Sanitizer与共享库一起工作?
或者,我需要正确的libasan.so版本(似乎不在deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch-8 main中,或者我需要一种静态地具有clang链接的方法)。

我的c版本:
$ 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(与GCC不同,Clang默认为-static-libasan)
  • 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在清理shlibs方面的区别的更多详细信息,请参见this answer

    关于python - 在python扩展上解决Sanitizer,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55692357/

    10-09 05:09