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
AddressSanitizer dedicates one-eighth of the virtual address space to its shadow memory and uses a direct mapping with a scale and offset to translate an applica- tion address to its corresponding shadow address. Given the application memory address Addr, the address of the shadow byte is computed as (Addr>>3)+Offset.
Address Sanitizer is a tool developed by Google detect memory access error such as use-after-free and memory leaks. It is built into GCC versions >= 4.8 and can be used on both C and C++ codes.
To sanitize a single library (without sanitizing main python
executable) with Clang you should
-shared-libasan
to LDFLAGS
(Clang defaults to -static-libasan
, unlike GCC)LD_PRELOAD=$(clang -print-file-name=libclang_rt.asan-x86_64.so)
(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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With