aclements / libelfin

C++11 ELF/DWARF parser
MIT License
314 stars 99 forks source link

Memory leaks in `make check` with address sanitizer. #34

Open FinnG opened 5 years ago

FinnG commented 5 years ago

I'm trying to use libelfin in a personal project, but when I turned on address sanitizer in my unit tests I noticed some leaks coming from this library. I was able to reproduce these leaks in libelfin's own test suite:

commit ac45a094fadba77ad840063fb7aab82571546be0
Author: James Moore <james@restphone.com>
Date:   Sat Aug 25 09:36:46 2018 -0700

    Added #include <errno.h> to files that use errno.

    This fixes #32.

gfg@rom ~/git/uprofile/ext/libelfin $ make clean
make -C elf clean
make[1]: Entering directory '/home/gfg/git/uprofile/ext/libelfin/elf'
rm -f  libelf++.a elf.o mmap_loader.o to_string.o to_string.cc libelf++.so.* libelf++.so libelf++.pc
make[1]: Leaving directory '/home/gfg/git/uprofile/ext/libelfin/elf'
make -C dwarf clean
make[1]: Entering directory '/home/gfg/git/uprofile/ext/libelfin/dwarf'
rm -f  libdwarf++.a dwarf.o cursor.o die.o value.o abbrev.o expr.o rangelist.o line.o attrs.o die_str_map.o elf.o to_string.o to_string.cc libdwarf++.so.* libdwarf++.so libdwarf++.pc
make[1]: Leaving directory '/home/gfg/git/uprofile/ext/libelfin/dwarf'
gfg@rom ~/git/uprofile/ext/libelfin $ cd elf
gfg@rom ~/git/uprofile/ext/libelfin/elf $ make LDFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address CXX=g++-7
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o elf.o elf.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o mmap_loader.o mmap_loader.cc
python3 enum-print.py -u --hex --no-type --mask shf --mask pf \
    -x loos -x hios -x loproc -x hiproc < data.hh >> to_string.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o to_string.o to_string.cc
ar rcs libelf++.a elf.o mmap_loader.o to_string.o
ln -s libelf++.so.0 libelf++.so
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC -fsanitize=address -shared -Wl,-soname,libelf++.so.0 -o libelf++.so.0 elf.o mmap_loader.o to_string.o
gfg@rom ~/git/uprofile/ext/libelfin/elf $ cd ../dwarf
gfg@rom ~/git/uprofile/ext/libelfin/dwarf $ make LDFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address CXX=g++-7
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o dwarf.o dwarf.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o cursor.o cursor.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o die.o die.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o value.o value.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o abbrev.o abbrev.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o expr.o expr.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o rangelist.o rangelist.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o line.o line.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o attrs.o attrs.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o die_str_map.o die_str_map.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o elf.o elf.cc
python3 ../elf/enum-print.py < dwarf++.hh >> to_string.cc
python3 ../elf/enum-print.py -s _ -u --hex -x hi_user -x lo_user < data.hh >> to_string.cc
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC   -c -o to_string.o to_string.cc
ar rcs libdwarf++.a dwarf.o cursor.o die.o value.o abbrev.o expr.o rangelist.o line.o attrs.o die_str_map.o elf.o to_string.o
g++-7 -fsanitize=address -std=c++0x -Wall -fPIC -fsanitize=address -shared -Wl,-soname,libdwarf++.so.0 -o libdwarf++.so.0 dwarf.o cursor.o die.o value.o abbrev.o expr.o rangelist.o line.o attrs.o die_str_map.o elf.o to_string.o
ln -s libdwarf++.so.0 libdwarf++.so
gfg@rom ~/git/uprofile/ext/libelfin/dwarf $ cd ..

Then just run the tests:

gfg@rom ~/git/uprofile/ext/libelfin $ make check LDFLAGS=-fsanitize=address CXXFLAGS=-fsanitize=address CXX=g++-7
cd test && ./test.sh
FAIL dump-sections golden-gcc-4.9.2/example
    failed: exit status 1
    --- golden-gcc-4.9.2/sections   2019-04-24 18:26:21.146740912 -0700
    +++ /tmp/libelfin.QNDlEwzNUP.out    2019-05-14 13:04:42.896855383 -0700
    @@ -56,17 +56,90 @@
            0000000000000039 0000000000000001 (shf)0x30       undef    0     1

<snip>

    +SUMMARY: AddressSanitizer: 8460 byte(s) leaked in 66 allocation(s).
6 test(s) failed
Makefile:14: recipe for target 'check' failed
make: *** [check] Error 1
gfg@rom ~/git/uprofile/ext/libelfin $ 
FinnG commented 5 years ago

Full ASAN output here: https://gist.github.com/FinnG/dc069596b5c879cc1a1ff6c9bc5f7c82

My C++ is a little rusty, but it looks like this may be a circular reference in a shared pointer object. I notice the constructor for the elf class looks like it contains a comment warning about a circular reference.

meowstr commented 2 months ago

:3c i fixed them