Dmalloc
下载:http://dmalloc.com/releases/dmalloc-5.5.2.tgz
编译:
--prefix指定的目录请自行更改,此目录下
- ./configure --enable-threads --prefix=xxx/Install
- 修改Makefile中的CC,CXX,ld,ar,ranlib等tools为对应工具链的tools
- make
- make install
使用:
- 执行编译生成的dmalloc(位于Install/bin目录)
./dmalloc -b -l /tmp/logfile -i 100 all,-l指定dmalloc 生成日志的文件名,-i 指定扫描间隔,更多参数请自行参考./dmalloc --usage
- 将执行dmalloc打印出来的DMALLOC_OPTIONS,设为环境变量
如:
- 需要检测的应用包含dmalloc.h,以及链接libdmalloc.a重新编译
如:arm-linux-gnueabihf-gcc -DDMALLOC_FUNC_CHECK -DDMALLOC -I./dmalloc/include -L./dmalloc/lib/ test.c -ldmalloc -o test
- 执行需检测的应用,待应用执行结束后,查看dmalloc的日志。
例程:
日志:直接查看not freed选项
从日志信息可以看出我们例程中的第13行malloc了10240 byte,但没有做free。
缺陷:dmalloc只是用来代替系统中malloc, realloc, calloc,free等等内存管理函数,用来检测内存泄露问题,对其他的泄漏情况无能为力。
Valgrind:
下载:https://sourceware.org/pub/valgrind/valgrind-3.15.0.tar.bz2
编译:
- ./autogen.sh
- 修改configure脚本 armv7*) 改为 armv7* | arm )
- ./configure --host=arm-linux CC=arm-linux-gnueabihf-gcc CXX= arm-linux-gnueabihf--g++ --prefix=XXX(注意板子上必须存在与安装目录一致的目录)
- make
- make install
- 将安装目录整个挂载到板子上(因生成的valgrind太大,copy到板子上不现实)
使用:
注意:板端的libc-2.28.so必须为没有strip过的,且测试的例程必须带调试信息(编译时加入-g选项)
例:./valgrind --log-file=/mnt/AI_File/valgrind.log --
tool=memcheck --leak-check=full --show-reachable=no --workaround-gcc296-bugs=yes
/mnt/AI_File/test
--log-file为valgrind日志的生成目录,不设置默认生成在当前路径,/mnt/AI_File/test
为笔者的测试例程。
例程:
Valgrind日志:
从日志可以看出例程在14行申请了10240 byte没有释放。
缺陷:Valgrind只能检查一些内存申请/释放,以及一些内存的错误使用等情况,但对于其他的一些内存不释放的情况(如:strdup,dlopen等申请内存的动作)同样无能为力。
Kmemleak:
Kmemleak只要打开相应的kernel config后面,再敲指令启动kmemleak扫描即可,仅适用于kernel mode的内存泄漏。
- 打开kernel 相关的配置项
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=4096
- 挂载debugfs
mount -t debugfs nodev /sys/kernel/debug/
- 启动kmemleak扫描
echo scan=5 > /sys/kernel/debug/kmemleak,这里设定为2s扫描一次
- 启动待测试可执行文件
- 查看kememleak的扫描日志
cat /sys/kernel/debug/kmemleak
- 清除扫描报告
echo clear > /sys/kernel/debug/kmemleak
- 隔一段时间重复步骤(5),(6)
日志分析:
以上例程为sdk在每次准备buffer时通过kmalloc多申请一块同样大小的内存,不使用不释放,从日志可以看出size 2048即我们申请的大小,以及backtrace。通过backtrace和函数偏移来推断泄漏的位置。