google / sanitizers

AddressSanitizer, ThreadSanitizer, MemorySanitizer
Other
11.45k stars 1.03k forks source link

"unknown module" in LeakSanitizer traces #899

Open firewave opened 6 years ago

firewave commented 6 years ago

I am seeing a lot of these with a program built with Clang 5.0.1 on ubuntu 16.04

Direct leak of 32768 byte(s) in 8 object(s) allocated from:
    #0 0x14d2a23 in malloc /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:67:3
    #1 0x7f46220c3faf  (<unknown module>)

The compiler flags include the following

-fsanitize=address -g -fno-omit-frame-pointer -fno-optimize-sibling-calls

I installed libstdc++5-dbgsym but that didn't help.

I also tried ASAN_OPTIONS="fast_unwind_on_malloc=0 malloc_context_size=2" but that didn't help with these leaks and even showed less information for other leaks which are giving proper backtraces. Using it without "malloc_context_size" doesn't seem to do anything - the application isn't starting and the machine is almost completely 100% idle.

As suggested in the FAQ I added "-shared-libstdc++", but that doesn't seem to be available for Clang - it's not even listed in the list of support command-line options.

ramosian-glider commented 6 years ago

Do you have an idea which shared library does this code belong to? You could dump /proc//maps and look up the address in the list of loaded libraries during the program execution.

firewave commented 6 years ago
Direct leak of 8192 byte(s) in 2 object(s) allocated from:
    #0 0x14d2a23 in malloc /opt/media/clang_nightly/llvm/utils/release/final/llvm.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:67:3
    #1 0x7f441ddbefaf  (<unknown module>)
7f123eed7000-7f123f1e9000 rw-p 00000000 00:00 0 
7f123f1e9000-7f123f207000 r-xp 00000000 fc:00 393315                     /lib/x86_64-linux-gnu/libudev.so.1.6.4
7f123f207000-7f123f208000 r--p 0001d000 fc:00 393315                     /lib/x86_64-linux-gnu/libudev.so.1.6.4
7f123f208000-7f123f209000 rw-p 0001e000 fc:00 393315                     /lib/x86_64-linux-gnu/libudev.so.1.6.4
7f123f20e000-7f123f215000 r-xp 00000000 00:00 0  

It's been the same library on several runs - so I installed libudev1-dbgsym but that also didn't help.

dreum commented 6 years ago

0x7f441ddbefaf is not in the range of addresses you've listed. You'll need to look further down your map.

I'm having similar issues with my project. For example:

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x5594b0 in operator new(unsigned long) /opt/jenkins/buildspace/clang-3_9/src/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:78
    #1 0x7ffaf8d2f411  (<unknown module>)
    #2 0x7ffaf960d186  (<unknown module>)
    #3 0x7ffaf960d19c  (<unknown module>)
    #4 0x7ffaf960f2d8  (<unknown module>)
    #5 0x7ffaf94aa0d6  (<unknown module>)

Printing out /proc/self/maps I got:

7ffaf9474000-7ffaf96ba000 r-xp 00000000 00:42 770                        /usr/lib/libgallium.so.0.0.0

In order to get good output I had to print it during the middle of program execution (in this case it was the middle of a test). This test happens to be running Qt widget code, so I suspected that qt was loading and unloading plugins which call into graphics libraries (gallium is part of mesa for those interested). Does anyone know if loading, or more precisely, unloading of libraries before main returns will prevent LSAN from properly determining library addresses?

I'm seeing similar output with dbus as our project uses the qt-dbus bindings which also probably loads things dynamically.

firewave commented 6 years ago

The application I was having the issue with is using SDL and Qt - though I am not sure if the Qt code was actually invoked in that case.

dreum commented 6 years ago

Looks like someone else has noticed the same issue: https://stackoverflow.com/questions/44627258/addresssanitizer-and-loading-of-dynamic-libraries-at-runtime-unknown-module

Timmmm commented 5 years ago

I have the same issue but the address leak sanitizer reports is not mapped at all. That SO link suggests it is bug #89 - the leak originates in a dynamically loaded object (i.e. with dlopen()) which is then dlclose()d before symbolisation so the information about where the library was loaded is lost (which explains why it doesn't appear in the memory map).

They say they won't fix it because it is too complicated which is a bit of a shame, however a workaround is to simply not dlclose() any libraries. You can do that without modifying your code.