Linux下c++程序中的内存泄露检查工具-valgrind、callgrind
背景:
所有使用动态内存分配的程序都有机会遇上内存泄漏问题,在测试公司某个应用客户端(Linux版)时发现存在内存泄漏问题,为抓取内存泄漏日志,查找了一些资料,发现很多博主都推荐使用valgrind工具;
常用检测内存泄漏工具很多,本次只简单记录我使用valgrind工具的过程。
一、valgrind介绍
valgrind是linux下用于调试程序和查找内存泄露的常用工具。提供多种内存检测方法,用于检测不同的数据,满足不同的使用需求,可使用的工具如下:
memcheck:是valgrind应用最广泛的工具,一个重量级的内存检查器(是一个细粒度的的内存检查器),能够发现开发中绝大多数内存错误使用情况,比如:使用未初始化的内存,使用已经释放了的内存,内存访问越界等。
callgrind:它主要用来检查程序中函数调用过程中出现的问题。
cachegrind:它主要用来检查程序中缓存使用出现的问题。
helgrind:它主要用来检查多线程程序中出现的竞争问题。
massif:它主要用来检查程序中堆栈使用中出现的问题。
extension:可以利用core提供的功能,自己编写特定的内存调试工具
二、安装valgrind
2.1 安装命令:sudo apt install valgrind

2.2 验证是否验证成功:
可以执行命令:valgrind ls -l

三、使用方法-memcheck
3.1 测试运行中的内存泄漏问题,可以使用如下命令:
valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-leak-kinds=all ./your_app arg1 arg2
注:--log-file 报告文件名。如果没有指定,输出到stderr。 --tool=memcheck 指定Valgrind使用的工具。
--leak-check 指定如何报告内存泄漏(memcheck能检查多种内存使用错误,内存泄漏是其中常见的一种),可选值有:
- no 不报告
- summary 显示简要信息,有多少个内存泄漏。summary是缺省值。
- yes 和 full 显示每个泄漏的内存在哪里分配。
--show-leak-kinds 指定显示内存泄漏的类型的组合。类型包括definite, indirect, possible,reachable。也可以指定all或none。缺省值是definite,possible。
运行一段时间后想停止进程不要kill掉,需要ctrl + c来结束,输出的log会在上述命令中的valgrind.log中。
3.2 以我司某应用为示例,如下:

3.3 结束后,可以在当前目录下看到valgrind.log

3.4 分析valgrind.log:
valgrind会报告5种内存泄露,"definitely lost", "indirectly lost", "possibly lost", "still reachable", and "suppressed",以下为官方解释及分析(翻译后)如下:
- "definitely lost":确认丢失。程序中存在内存泄露,应尽快修复。当程序结束时如果一块动态分配的内存没有被释放且通过程序内的指针变量均无法访问这块内存则会报这个错误。
-
"indirectly lost":间接丢失。当使用了含有指针成员的类或结构时可能会报这个错误。这类错误无需直接修复,他们总是与"definitely lost"一起出现,只要修复"definitely lost"即可。
-
"possibly lost":可能丢失。大多数情况下应视为与"definitely lost"一样需要尽快修复,除非你的程序让一个指针指向一块动态分配的内存(但不是这块内存起始地址),然后通过运算得到这块内存起始地址,再释放它。
-
"still reachable":可以访问,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃,但长时间运行有可能耗尽系统资源。
-
"suppressed":已被解决。出现了内存泄露但系统自动处理了。可以无视这类错误。这类错误我没能用例程触发,看官方的解释也不太清楚是操作系统处理的还是valgrind,也没有遇到过。所以无视他吧
使用文本编辑器或其他方式打开刚抓取的valgrind.log,如下:


综述,从日志中可以看出我司某应用存在的内存泄漏类型为--"still reachable":可以访问,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃,但长时间运行有可能耗尽系统资源。
四、callgrind使用
callgrind分析:
valgrind --tool=callgrind /usr/share/safeAxxx/bin/safeAxxx

安装kcachegrind:
命令:apt-get install kcachegrind

安装完成后,使用命令行打开文件:
命令行中输入:kcachegrind callgrind.out.xxxx

打开后,可以看到函数之间的调用关系,如下图:

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)