Jeff-Lewis / address-sanitizer

Automatically exported from code.google.com/p/address-sanitizer
0 stars 0 forks source link

JNI-based app fails with shadow memory range interleaves with existing memory mapping after ASan instrumentation #386

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Build JNI C++ code with -fsanitize=address flag turned on against 
jdk-7u10-64.
2. Build Java code which uses the JNI interface against jdk-7u10-64.
3. Run the generated jar above.

What is the expected output? What do you see instead?
I expect the program to run. Instead the program crashes with the following 
error:
==4402== Shadow memory range interleaves with an existing memory mapping. ASan 
cannot proceed correctly. ABORTING.
==4402== Process memory map follows:
    0x000000400000-0x000000401000   /usr/local/jdk-7u10-64/bin/java
    0x000000600000-0x000000601000   /usr/local/jdk-7u10-64/bin/java
    0x000096e00000-0x000098350000   
    0x000098350000-0x00009c000000   
    0x00009c000000-0x0000c5d90000   
    0x0000c5d90000-0x0000deab0000   
    0x0000deab0000-0x000100000000   
    0x7f575894e000-0x7f5758951000   
    0x7f5758951000-0x7f5758a4f000   [stack:6043]
    0x7f5758a4f000-0x7f5758a52000   
...

What version of the product are you using? On what operating system?
GCC version: gcc-4.8.1-glibc-2.17
JDK version: jdk-7u10-64

Please provide any additional information below.
I have a question. Is there a way to re-configure the reserved base addresses 
for ASan so that they don't interleave with existing memory mapping from JVM?

Any help would be highly appreciated!

Original issue reported on code.google.com by wdon...@gmail.com on 9 Apr 2015 at 7:00

GoogleCodeExporter commented 9 years ago
These guys are in the shadow gap. Any idea where they come from?
        0x000096e00000-0x000098350000   
        0x000098350000-0x00009c000000   
        0x00009c000000-0x0000c5d90000   
        0x0000c5d90000-0x0000deab0000   
        0x0000deab0000-0x000100000000   

// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000: 

// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||                       

// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||                       

// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||                       

// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||                       

// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||   

If you are OK with patching the compiler, mapping can be changed. See 
AddressSanitizer.cpp and asan_mapping.h (compiler-rt).
It looks like increasing the offset (currently 0x00007fff8000) could help.
But it's very unlikely to be accepted upstream.

Original comment by euge...@google.com on 9 Apr 2015 at 10:57

GoogleCodeExporter commented 9 years ago
> These guys are in the shadow gap. Any idea where they come from?

Guess this is typical situation when some constructor kicks in before asan_init 
is able to mmap shadow. I added a comment to FAQ.

Original comment by tetra2...@gmail.com on 9 Apr 2015 at 8:17

GoogleCodeExporter commented 9 years ago
Oh, but it's even worse than that - it's not about library initialization order 
but the fact that ASan is initialized super late, when JNI library is dlopen-ed.

Original comment by euge...@google.com on 9 Apr 2015 at 8:28

GoogleCodeExporter commented 9 years ago
But wouldn't LD_PRELOAD help in this case?

Original comment by tetra2...@gmail.com on 10 Apr 2015 at 4:03

GoogleCodeExporter commented 9 years ago
It should help.

Original comment by euge...@google.com on 10 Apr 2015 at 8:46

GoogleCodeExporter commented 9 years ago
Many thanks for the very quick response! When you mentioned LD_PRELOAD, did you 
mean the instructions at 
https://code.google.com/p/address-sanitizer/wiki/AsanAsDso? Also is there a 
tool to find out which module maps to the addresses such as '0x000096e00000'? I 
tried to us LD_PRELOAD=/usr/lib64/libasan.so.0 and got the following error:

ASAN:SIGSEGV
=================================================================
==112764== ERROR: AddressSanitizer: SEGV on unknown address 0x000000000008 (pc 
0x7f9b8a16e91b sp 0x7f9b8d859050 bp 0x7f9b8d8590f0 T1)
AddressSanitizer can not provide additional info.
    #0 0x7f9b8a16e91a (+0x7091a)
Thread T1 created by T0 here:
    #0 0x7f9b8fec2b6b (/usr/lib64/libasan.so.0.0.0+0xab6b)
    #1 0x7f9b8fa8f4c8 (/usr/local/jdk-7u45-64/lib/amd64/jli/libjli.so+0xd4c8)
    #2 0x7f9b8fa84589 (/usr/local/jdk-7u45-64/lib/amd64/jli/libjli.so+0x2589)
...

I tried to set ASAN_OPTIONS=handle_segv=0 as suggested by 
https://code.google.com/p/address-sanitizer/issues/detail?id=58 but I got the 
following error:
>> undefined symbol: __asan_option_detect_stack_use_after_return
Probably I got the wrong version of dynamic library? Do I need to build ASAN by 
myself? I am trying other things and will report it back for more findings.

Original comment by wdon...@gmail.com on 10 Apr 2015 at 9:10

GoogleCodeExporter commented 9 years ago
Before we continue on this, is there a chance for you to use gcc 4.9? This has 
many usability improvements compared to 4.8.

> When you mentioned LD_PRELOAD, did you mean the instructions
> at https://code.google.com/p/address-sanitizer/wiki/AsanAsDso?

Yes, more or less.

> Also is there a tool to find out which module maps to the addresses
> such as '0x000096e00000'?

I guess it's not a module but rather some anonymous mapping coming from malloc 
or maybe JVM is directly mmapping buffers for internal use. You can run under 
gdb and break on mmaps/mallocs to find out.

> #0 0x7f9b8fec2b6b (/usr/lib64/libasan.so.0.0.0+0xab6b)

Running addr2line on these addresses may help to understand what's going on.

Original comment by tetra2...@gmail.com on 10 Apr 2015 at 9:57

GoogleCodeExporter commented 9 years ago
I tried with gcc 4. (gcc-4.9-glibc-2.20). But somehow I got the following error:
  xxx.cpp:269: error: undefined reference to '__asan_init_v4'
  <some roor>/third-party2/libgcc/4.9.x/gcc-4.9-glibc-2.20/e1a7e4e/include/c++/4.9.x/bits/move.h:102: error: undefined reference to '__asan_init_v4'
How to resolve this please?

The command 'addr2line -e /usr/lib64/libasan.so.0 0xab6b' showed output as:
??:0
Probably the binary does not have symbols embedded? Thanks!

Original comment by wdon...@gmail.com on 11 Apr 2015 at 5:40

GoogleCodeExporter commented 9 years ago
> I tried with gcc 4. (gcc-4.9-glibc-2.20). But somehow I got the following 
error:
>  xxx.cpp:269: error: undefined reference to '__asan_init_v4'

Could you check "undefined ASan symbols" FAQ entry is applicable here?

> The command 'addr2line -e /usr/lib64/libasan.so.0 0xab6b' showed output as:
> ??:0
> Probably the binary does not have symbols embedded? Thanks!

Sure but you can still dump function name via -f.

Original comment by tetra2...@gmail.com on 11 Apr 2015 at 7:27

GoogleCodeExporter commented 9 years ago
Finally I got it to work with gcc 4.8.1! I needed to use LD_PRELOAD against the 
right version of the runtime library libclang_rt.asan-x86_64.so. Also I needed 
to set ASAN_OPTIONS=handle_segv=0. This is really great. Many thanks for the 
great help! Also thanks to you guys for creating such a great tool!

Original comment by wdon...@gmail.com on 12 Apr 2015 at 12:23

GoogleCodeExporter commented 9 years ago
Glad to hear you've succeeded! BTW can anyone think of a good way to emit a 
user-friendly error message when dlopen fails to load sanitized library due to 
missing or incompatible LD_PRELOAD?

Original comment by tetra2...@gmail.com on 12 Apr 2015 at 7:26

GoogleCodeExporter commented 9 years ago
Perhaps close as not-a-bug?

Original comment by tetra2...@gmail.com on 12 Apr 2015 at 11:54

GoogleCodeExporter commented 9 years ago

Original comment by euge...@google.com on 15 Apr 2015 at 7:05

GoogleCodeExporter commented 9 years ago
Adding Project:AddressSanitizer as part of GitHub migration.

Original comment by ramosian.glider@gmail.com on 30 Jul 2015 at 9:14