2017-12-21 3 views
0

valgrind, gperftools 및 libasan과 같은 도구를 사용하여 더 복잡한 시스템에서 메모리 누수를 찾으려고합니다. 나는 내가 제거 할 수 없었던 누출을 얻고 있었고 그래서 내가 생각할 수있는 가장 단순한 프로그램을 만들었습니다.누출 감지 누출 감지

LeakSanitizer가 여전히 누수를보고하는 이유는 무엇입니까?

env ASAN_OPTIONS=symbolize=1 ASAN_SYMBOLIZER_PATH=/usr/bin/llvm-symbolizer-3.8 ./run 

분석은 다음과 같습니다 당신이 프로그램을 실행할 수

# Makefile 

CC=g++ 
FLAGS=--std=c++11 -O0 -g -I. -fsanitize=address -fno-omit-frame-pointer -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free 
TGT=run 
LINK=-static-libasan -ltcmalloc 

all: $(TGT) 

$(TGT): 
     $(CC) $(FLAGS) test.cc -o $(TGT) $(LINK) 

clean: 
     rm -f $(TGT) 

: 여기

// File: test.cc 

int main() 
{ 
    unsigned char* data = new unsigned char[1024]; 
    delete[] data; 
    data = 0; 

    return 0; 
} 

내 메이크입니다 test.cc : 여기

내 주요 파일입니다 :

================================================================= 
==23139==ERROR: LeakSanitizer: detected memory leaks 

Direct leak of 8 byte(s) in 1 object(s) allocated from: 
    #0 0x481492 in operator new(unsigned long) (/home/user/tests/cpp/leakTest/basic/run+0x481492) 
    #1 0x7f46c64bf0dd in InitModule src/malloc_extension.cc:212 

SUMMARY: AddressSanitizer: 8 byte(s) leaked in 1 allocation(s). 
,451,515,

내 시스템 :

[email protected]:~$ lsb_release -a 
LSB Version: core-9.20160110ubuntu0.2-amd64:core-9.20160110ubuntu0.2-noarch:security-9.20160110ubuntu0.2-amd64:security-9.20160110ubuntu0.2-noarch 
Distributor ID: Ubuntu 
Description: Ubuntu 16.04.3 LTS 
Release: 16.04 
Codename: xenial 

[email protected]:~/$ uname -a 
Linux computer 4.4.0-103-generiC#126-Ubuntu SMP Mon Dec 4 16:23:28 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux 

[email protected]:~/$ dpkg -l | grep asan 
ii libasan2:amd64        5.4.0-6ubuntu1~16.04.5      amd64  AddressSanitizer -- a fast memory error detector 

[email protected]:~/$ dpkg -l | grep llvm 
ii libllvm3.6v5:amd64       1:3.6.2-3ubuntu2        amd64  Modular compiler and toolchain technologies, runtime library 
ii libllvm3.8:amd64        1:3.8-2ubuntu4        amd64  Modular compiler and toolchain technologies, runtime library 
ii libllvm4.0:amd64        1:4.0-1ubuntu1~16.04.2      amd64  Modular compiler and toolchain technologies, runtime library 
ii llvm           1:3.8-33ubuntu3.1       amd64  Low-Level Virtual Machine (LLVM) 
ii llvm-3.8          1:3.8-2ubuntu4        amd64  Modular compiler and toolchain technologies 
ii llvm-3.8-dev         1:3.8-2ubuntu4        amd64  Modular compiler and toolchain technologies, libraries and headers 
ii llvm-3.8-runtime        1:3.8-2ubuntu4        amd64  Modular compiler and toolchain technologies, IR interpreter 
ii llvm-runtime         1:3.8-33ubuntu3.1       amd64  Low-Level Virtual Machine (LLVM), bytecode interpreter 

[email protected]:~/$ dpkg -l | grep tcmalloc 
ii libtcmalloc-minimal4       2.4-0ubuntu5.16.04.1       amd64  efficient thread-caching malloc 

[email protected]:~/$ g++ -v 
Using built-in specs. 
COLLECT_GCC=g++ 
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper 
Target: x86_64-linux-gnu 
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.5' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu 
Thread model: posix 
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.5) 

[email protected]:~/$ dpkg -l | grep libstdc 
ii libstdc++-5-dev:amd64       5.4.0-6ubuntu1~16.04.5      amd64  GNU Standard C++ Library v3 (development files) 
ii libstdc++6:amd64        5.4.0-6ubuntu1~16.04.5      amd64  GNU Standard C++ Library v3 

편집 : 흠. Makefile에서 asan의 링크를 '-static-libasan'에서 '-lasan'으로 변경하면 누수가보고되지 않습니다. -static-libasan과 연결하지 않아야합니까?

+0

가능성은 그 LeakSanitizer는 프레임 포인터에 의존합니까? –

+0

정적 연결은 잘되어야합니다. 정적 연결을 사용하는 위양성은 정적 라이브러리의 문제보다는 프로그램의 한계라고 생각하는 경향이 있습니다. –

+0

@JustinRandall '-fno-omit-frame-pointer'를 제거해도 차이가 없습니다. 프로그램의 제한은 무엇입니까? 미안하지만이 수준의 디버깅에 익숙하지 않습니다. – vincent

답변

1

저는 tcmalloc에 ​​익숙하지 않지만 의도적으로 그 개체를 유출 한 것 같습니다. 는 누출 지적 :

이 소스 코드 ( github)와
Direct leak of 8 byte(s) in 1 object(s) allocated from: 
    #0 0x481492 in operator new(unsigned long) (/home/user/tests/cpp/leakTest/basic/run+0x481492) 
    #1 0x7f46c64bf0dd in InitModule src/malloc_extension.cc:212 

의 상관 관계 : 그것은 또한 일부 Valgrind의 버전에서 검출되는 것으로보고되었다

static void InitModule() { 
    current_instance = new MallocExtension; // reported leak 
#ifndef NO_HEAP_CHECK 
    HeapLeakChecker::IgnoreObject(current_instance); 
#endif 
} 

:
https://github.com/gperftools/gperftools/issues/758

+0

흠. 이 함수 선언 바로 전에 current_instance는 정적 변수로 선언됩니다. 그런 다음 InitModule 뒤에있는 함수는 current_instance (singleton)를 반환합니다. 왜 그게 누출일까요? – vincent

+0

@vincent 정적이 동적으로 할당되기 때문에 프로그램이 종료되기 전에 할당이 해제 될 것으로 예상됩니다. valgrind/asan의 통계와 통계는 구별되지 않습니다.때로는 어떤 객체를 할당 해제하는 것을 피하고, 프로그램이 죽을 때 (tcmalloc을위한 디자인 선택 일 수도있다) OS가 그 메모리를 해제하도록하는 것이 좋다. 이 답변도 참조하십시오. https://stackoverflow.com/questions/10572610/memory-leaks-when-using-a-singleton – valiano

+0

좋습니다. 감사. – vincent