You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For the longest time, when I attempted to use ASAN with clang, I got the "Shadow memory range interleaves with an existing memory mapping" error.
(/home/ezyang/Dev/labs/python-ext-env) ezyang@autobox:~/Dev/labs/python-ext$ LD_PRELOAD=/usr/lib/llvm-5.0/lib/clang/5.0.0/lib/linux/libclang_rt.asan-x86_64.so python script.py
==17683==Shadow memory range interleaves with an existing memory mapping. ASan cannot proceed corr
ectly. ABORTING.
==17683==ASan shadow was supposed to be located in the [0x00007fff7000-0x10007fff7fff] range.
==17683==Process memory map follows:
0x00007fff7000-0x00008fff7000
0x00008fff7000-0x02008fff7000
0x02008fff7000-0x10007fff8000
0x56532c2df000-0x56532c59d000 /home/ezyang/Dev/labs/python-ext-env/bin/python3.6
0x56532c79d000-0x56532c7a0000 /home/ezyang/Dev/labs/python-ext-env/bin/python3.6
0x56532c7a0000-0x56532c803000 /home/ezyang/Dev/labs/python-ext-env/bin/python3.6
0x56532c803000-0x56532c834000
0x600000000000-0x602000000000
0x602000000000-0x602000010000
0x602000010000-0x602e00000000
0x602e00000000-0x602e00010000
0x602e00010000-0x603000000000
[snip]
Perplexingly, I could get gcc working with ASAN, so for a while I wondered if this was just a problem with clang's copy of ASAN (weird, because clang's ASAN is the maintained copy, and gcc's apparently unmaintained.) There are a few existing bugs (e.g. #856) which suggested various causes for the problem, but none seemed applicable in my situation.
Actually, the problem is very simple: I was statically linking my dynamic library (which was being dynamically loaded by Python) with the ASAN runtime, which obviously is not going to work.
"Now, why would anyone ever do that?" It's actually pretty easy to get into this situation:
You want to build a Python C extension with ASAN enabled, but you don't have an ASAN-built copy of Python
You run CFLAGS="-fsanitize=address" python setup.py install" and then run you rest script. When you run your test script, ASAN helpfully tells you "ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD." You add LD_PRELOAD=/path/to/gcc/libasan.so and ASAN works. You are happy.
Next, you decide to do it again with Clang. So you say CC=clang CFLAGS="-fsanitize=address" python setup.py install". Once again, ASAN gives the same "runtime does not come first" message, so you add LD_PRELOAD. BOOM, shadow error.
The PEBKAC, in this case, is assuming that because gcc dynamically links libasan, clang does as well. But the defaults are different: clang defaults to statically linking libasan. And of course the statically linked libasan in the Python extension library is going to be run too late, and if you add the LD_PRELOAD, the statically linked libasan is of course not going to be able get the shadow range it wants, because the preloaded libasan grabbed it already.
I know, it takes forever for fixes in upstream to make their way to distro copies of clang. So I am half writing this post for Google juice, for other poor souls in dynamic linking hell. But it would also be really nice if ASAN didn't suggest LD_PRELOADing from the static runtime, if it's not actually going to work.
P.S. These invocations work for me for building a simple hello world Python extension with the distro-packaged Clang 5.0 on Ubuntu Xenial:
Actually, the problem is very simple: I was statically linking my dynamic library (which was being
dynamically loaded by Python) with the ASAN runtime, which obviously is not going to work.
Yeah, I'm afraid this won't supported mode of work. Suggested approach is in Asaq FAQ:
Q: I've built my shared library with ASan. Can I run it with unsanitized executable?
A: Yes! You'll need to build your library with dynamic version of ASan and then run executable with LD_PRELOAD=path/to/asan/runtime/lib.
but it seems you've figured it out yourself already. This SO post might be helpful too.
But it would also be really nice if ASAN didn't suggest LD_PRELOADing from the static runtime,
if it's not actually going to work.
Agreed, this is really confusing (as is the fact that we fail to detect presence of duplicate Asan runtimes). @chefmax WDYT?
For the longest time, when I attempted to use ASAN with clang, I got the "Shadow memory range interleaves with an existing memory mapping" error.
Perplexingly, I could get gcc working with ASAN, so for a while I wondered if this was just a problem with clang's copy of ASAN (weird, because clang's ASAN is the maintained copy, and gcc's apparently unmaintained.) There are a few existing bugs (e.g. #856) which suggested various causes for the problem, but none seemed applicable in my situation.
Actually, the problem is very simple: I was statically linking my dynamic library (which was being dynamically loaded by Python) with the ASAN runtime, which obviously is not going to work.
"Now, why would anyone ever do that?" It's actually pretty easy to get into this situation:
CFLAGS="-fsanitize=address" python setup.py install"
and then run you rest script. When you run your test script, ASAN helpfully tells you "ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD." You addLD_PRELOAD=/path/to/gcc/libasan.so
and ASAN works. You are happy.CC=clang CFLAGS="-fsanitize=address" python setup.py install"
. Once again, ASAN gives the same "runtime does not come first" message, so you addLD_PRELOAD
. BOOM, shadow error.The PEBKAC, in this case, is assuming that because
gcc
dynamically links libasan,clang
does as well. But the defaults are different:clang
defaults to statically linking libasan. And of course the statically linked libasan in the Python extension library is going to be run too late, and if you add theLD_PRELOAD
, the statically linked libasan is of course not going to be able get the shadow range it wants, because the preloaded libasan grabbed it already.I know, it takes forever for fixes in upstream to make their way to distro copies of clang. So I am half writing this post for Google juice, for other poor souls in dynamic linking hell. But it would also be really nice if ASAN didn't suggest LD_PRELOADing from the static runtime, if it's not actually going to work.
P.S. These invocations work for me for building a simple hello world Python extension with the distro-packaged Clang 5.0 on Ubuntu Xenial:
Obviously change the paths appropriately depending on your Clang install. (Also, if someone could answer https://stackoverflow.com/questions/48833176/get-location-of-libasan-from-gcc-clang that would also be super helpful :)
The text was updated successfully, but these errors were encountered: