内存泄漏分析的利器——gperftools的Heap Checker

        在《内存问题分析的利器——valgraind的memcheck》一文中,我们介绍了如何使用valgrind分析各种内存问题。valgrind是基于模拟器的技术实现,而本文介绍的gperftools则是通过在用户代码中嵌入检测代码实现的。(转载请指明出于breaksoftware的csdn博客)

        先介绍下gperftools的编译安装。

        首先下载安装编译依赖的一些工具

sudo apt install autoconf 
sudo apt install libtool
sudo apt install libtool-bin

        然后从git上获取libunwind,并编译安装

git clone https://github.com/libunwind/libunwind.git
cd libunwind
sh ./autogen.sh 
./configure 
make
sudo make install

        现在可以编译安装gperftools了

git clone https://github.com/gperftools/gperftools.git
sh autogen.sh 
./configure 
make
sudo make install

        最后,我们安装下结果可视化分析工具kcachegrind

sudo apt install kcachegrind

        由于heap checker是内存泄漏检测工具,我们构造一段有问题的代码

#include <stdlib.h>

int main() {
    const int array_count = 4;
    int* p = new int[array_count];
    return 0;
}

        这段代码第5行在堆上申请了空间,但是没有释放。为了包含更多调试信息,我们使用-g方式编译该文件

g++ leak.cpp -ltcmalloc -g -o leak

        注意此处我们链接了tcmalloc库,它是gperftools内存问题分析方案的基础。一般来说,比较推荐链接该库,它的效率比编译器自带的内存管理库要高。

        gperftools运行方式比较独特,对于heap checker工具,我们需要这样调用

HEAPCHECK=normal /home/fangliang/gperftools_test/heap_checker/leak

        HEAPCHECK除了nomal外,还可以选择strict或者draconian。最后一个参数就是我们程序的路径。其分析结果展现如下

WARNING: Perftools heap leak checker is active -- Performance may suffer
Have memory regions w/o callers: might report false leaks
Leak check _main_ detected leaks of 16 bytes in 1 objects
The 1 largest leaks:
Using local file /home/fangliang/gperftools_test/heap_checker/leak.
Leak of 16 bytes in 1 objects allocated from:
	@ 55f9903b8723 main
	@ 7fed6bbc9b97 __libc_start_main
	@ 55f9903b862a _start


If the preceding stack traces are not enough to find the leaks, try running THIS shell command:

pprof /home/fangliang/gperftools_test/heap_checker/leak "/tmp/leak.3384._main_-end.heap" --inuse_objects --lines --heapcheck  --edgefraction=1e-10 --nodefraction=1e-10 --gv

If you are still puzzled about why the leaks are there, try rerunning this program with HEAP_CHECK_TEST_POINTER_ALIGNMENT=1 and/or with HEAP_CHECK_MAX_POINTER_OFFSET=-1
If the leak report occurs in a small fraction of runs, try running with TCMALLOC_MAX_FREE_QUEUE_SIZE of few hundred MB or with TCMALLOC_RECLAIM_MEMORY=false
Exiting with error code (instead of crashing) because of whole-program memory leaks

        第6行显示我们程序有1块16字节的空间泄漏。第7到第9行,展示了泄漏处的调用堆栈。但是这个信息展现方式并没有直接指出问题产生的行数。我们可以使用其提示的第14行指令,调用可视化工具

        如此,我们便可以清晰的知道,leak.cpp第5行代码申请的空间存在内存泄漏。

        如果我们项目中不可以链接tcmalloc,我们还可以使用如下方式调用heap checker,其结果和上面描述的一致

LD_PRELOAD="/usr/local/lib/libtcmalloc.so" HEAPCHECK=normal /home/fangliang/gperftools_test/heap_checker/leak

猜你喜欢

转载自blog.csdn.net/breaksoftware/article/details/81234967