17

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

The compiler invocation is

clang -g -o _ext.so code.ll -fsanitize=address -lrt -lpthread -ldl -lstdc++ -lm -fPIC -shared

So, it does not load symbols from asan correctly. I've tried using -static-libsan, but the result was the same.

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).

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).

My clang version:

$ 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

1 Answer 1

29

To sanitize a single library (without sanitizing main python executable) with Clang you should

  • Add -shared-libasan to LDFLAGS (Clang defaults to -static-libasan, unlike GCC)
  • Run with LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so) (on macOS, use DYLD_INSERT_LIBRARIES instead of LD_PRELOAD). It should be somewhere with standard Clang libs.

(see AddressSanitizerAsDso wiki).

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).

For more details on differences between GCC and Clang with respect to sanitization of shlibs see this answer.

Sign up to request clarification or add additional context in comments.

4 Comments

It works. The correct file name is /usr/lib/llvm-8/lib/clang/8.0.0/lib/linux/libclang_rt.asan-x86_64.so.
@Alex Check my update, we can identify library location automagically.
For Mac users: Use DYLD_INSERT_LIBRARIES instead of LD_PRELOAD
@StuartBerg Thanks! Would you mind adding this to answer?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.