嵌入式 linux 内存泄漏分析工具(1):valgrind

简介: 嵌入式 linux 内存泄漏分析工具(1):valgrind

valgrind 介绍


valgrind 是一个 GPL 软件,用于 Linux ( For x86 ,amd64 and mips ...) 程序的内存调试和代码分析。使用 valgrind 的工具包,可以自动检测许多内存管理和线程的bug,让你的程序运行的更加稳定。


valgrind 的工具包包含多个工具:


  • memcheck:内存检查


  • 使用未初始化的内存:Use of uninitialised memory


  • 使用已释放的内存 :Reading/writing memory after it has been free’d


  • 使用超过malloc分配的内存空间:Reading/writing off the end of malloc’d blocks


  • 对堆栈的非法访问:Reading/writing inappropriate areas on the stack


  • 申请的空间是否有释放:Memory leaks – where pointers to malloc’d blocks are lost forever


  • malloc/free/new/delete 申请和释放内存的匹配:Mismatched use of malloc/new/new [] vs free/delete/delete []


  • src和dst的重叠:Overlapping src and dst pointers in memcpy() and related functions


  • callgrind:收集程序运行的一些数据,函数调用关系等。还可以有选择的进行cache模拟。在运行结束,他会把分析数据写入一个文件,callgrind_annotate 可以把这个文件内容转换成可读形式。


  • cachegrind:它模拟 CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中 cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。


  • helgrind:它主要用来检查多线程程序中出现的竞争问题。Helgrind寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。


  • massif:堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。


valgrind 安装和编译


下载


wget http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2


编译及安装


以 mips,uclibc环境为例


--host:指定交叉编译工具链,默认glibc


--prefix:指定安装路径


-muclibc:指定uclibc环境


-D__UCLIBC__:define __UCLIBC__。valgrind 需要定义这个宏否则运行报错。


./autogen.sh
./configure --host=mips-linux-gnu CFLAGS="-D__UCLIBC__ -muclibc" --prefix=/home_a/wxyang/nfsroot/t30/valgrind/
make
make install


安装工具集


image.png


valgrind 应用实例分析


启动开发板,设置环境变量:


export VALGRIND_LIB=/mnt/t30/valgrind/lib/valgrind
export PATH=/mnt/t30/valgrind/bin/:$PATH


启动应用程序:


valgrind --log-file=valgrind.log --tool=memcheck --leak-check=full --show-reachable=yes ./test


--tool=memcheck:设置启动工具为memcheck --leak-check=full:完全检查内存泄漏

--log-file=valgrind.log:输出日志文件 --show-reachable=yes:检测控制范围之外的泄漏


注意:应用程序编译时加上-g, 尽量不要用O2优化(用-O0),同时不要用 strip 压缩,否则看不到详细信息。


日志分析:常见错误


  • malloc/free: in use at exit :内存在退出前没有释放


  • invalid write of size :非法写入内存,一般为数组越界


  • invalid read of size :非法读内存:一般为数组越界


  • definitely lost /possibly lost /still reachable in loss record:内存未释放


  • definitely :确认丢失。程序中存在内存泄露,应尽快修复。


  • indirectly:间接丢失。当使用了含有指针成员的类或结构时可能会报这个错误 。


  • possibly:可能丢失。大多数情况下应视为与"definitely lost"一样需要尽快修复。


  • still reachable:可以访问,未丢失但也未释放。如果程序是正常结束的,那么它可能不会造成程序崩溃,但长时间运行有可能耗尽系统资源。


  • suppressed:已被解决。出现了内存泄露但系统自动处理了。可以无视这类错误。


  • invalid free()/delete/delete[] :同一指针被多次释放


  • source and destination overlay :一般是使用strncpy,memcpy引起


  • syscall param contains uninitialized byte:调用系统函数时传入了未初始化的变量


  • conditional jump or move depends on uninitialized value :条件判断时使用了未初始化的变量


  • access not with mapped region/stack overflow :栈溢出


  • mismatch free()/delete/delete[]/new  :delete/malloc/free搭配错误


错误举例


indirectly lost:如图可以追溯到具体文件及函数调用,明显是cjson使用有问题。


image.png


still reachable:


image.png


总结


  • 本文简单介绍 valgrind 安装和使用,以及对内存泄漏简单分析,算是提供一种排查思路;


  • 通常自己写的程序一般有些许掌控力,不过对于大型项目,多人协助,以及引入的第三方库,难免会遗留一些bug。这个时候就需要一些工具辅助排查了,能够大大提升效率。


  • 希望本文对你,有些许帮助。
相关文章
|
4月前
|
存储 弹性计算 缓存
阿里云服务器ECS经济型、通用算力、计算型、通用和内存型选购指南及使用场景分析
本文详细解析阿里云ECS服务器的经济型、通用算力型、计算型、通用型和内存型实例的区别及适用场景,涵盖性能特点、配置比例与实际应用,助你根据业务需求精准选型,提升资源利用率并降低成本。
306 3
|
3月前
|
存储 人工智能 自然语言处理
AI代理内存消耗过大?9种优化策略对比分析
在AI代理系统中,多代理协作虽能提升整体准确性,但真正决定性能的关键因素之一是**内存管理**。随着对话深度和长度的增加,内存消耗呈指数级增长,主要源于历史上下文、工具调用记录、数据库查询结果等组件的持续积累。本文深入探讨了从基础到高级的九种内存优化技术,涵盖顺序存储、滑动窗口、摘要型内存、基于检索的系统、内存增强变换器、分层优化、图形化记忆网络、压缩整合策略以及类操作系统内存管理。通过统一框架下的代码实现与性能评估,分析了每种技术的适用场景与局限性,为构建高效、可扩展的AI代理系统提供了系统性的优化路径和技术参考。
168 4
AI代理内存消耗过大?9种优化策略对比分析
|
5月前
|
缓存 Linux 数据安全/隐私保护
Linux环境下如何通过手动调用drop_caches命令释放内存
总的来说,记录住“drop_caches” 命令并理解其含义,可以让你在日常使用Linux的过程中更加娴熟和自如。
1028 23
|
4月前
|
存储 Ubuntu Linux
内存卡格式化必看!4个格式化工具与注意事项
今天就给大家推荐几款经过实测的内存卡格式化工具,它们不仅使用简单、支持多种格式,而且在修复损坏卡方面也表现稳定,是实用性与安全性兼具的好帮手。
|
7月前
|
监控 Linux Python
Linux系统资源管理:多角度查看内存使用情况。
要知道,透过内存管理的窗口,我们可以洞察到Linux系统运行的真实身姿,如同解剖学家透过微观镜,洞察生命的奥秘。记住,不要惧怕那些高深的命令和参数,他们只是你掌握系统"魔法棒"的钥匙,熟练掌握后,你就可以骄傲地说:Linux,我来了!
235 27
|
8月前
|
消息中间件 Linux
Linux中的System V通信标准--共享内存、消息队列以及信号量
希望本文能帮助您更好地理解和应用System V IPC机制,构建高效的Linux应用程序。
278 48
|
7月前
|
存储 Java
课时4:对象内存分析
接下来对对象实例化操作展开初步分析。在整个课程学习中,对象使用环节往往是最棘手的问题所在。
|
7月前
|
Java 编译器 Go
go的内存逃逸分析
内存逃逸分析是Go编译器在编译期间根据变量的类型和作用域,确定变量分配在堆上还是栈上的过程。如果变量需要分配在堆上,则称作内存逃逸。Go语言有自动内存管理(GC),开发者无需手动释放内存,但编译器需准确分配内存以优化性能。常见的内存逃逸场景包括返回局部变量的指针、使用`interface{}`动态类型、栈空间不足和闭包等。内存逃逸会影响性能,因为操作堆比栈慢,且增加GC压力。合理使用内存逃逸分析工具(如`-gcflags=-m`)有助于编写高效代码。
137 2
|
8月前
|
缓存 NoSQL Linux
Linux系统内存使用优化技巧
交换空间(Swap)的优化 禁用 Swap sudo swapoff -a 作用:这个命令会禁用系统中所有的 Swap 空间。swapoff 命令用于关闭 Swap 空间,-a 参数表示关闭 /etc/fstab 文件中配置的所有 Swap 空间。 使用场景:在高性能应用场景下,比如数据库服务器或高性能计算服务器,禁用 Swap 可以减少磁盘 I/O,提高系统性能。
294 3
|
8月前
|
缓存 Linux
Linux查看内存命令
1. free free命令是最常用的查看内存使用情况的命令。它显示系统的总内存、已使用内存、空闲内存和交换内存的总量。 free -h • -h 选项:以易读的格式(如GB、MB)显示内存大小。 输出示例: total used free shared buff/cache available Mem: 15Gi 4.7Gi 4.1Gi 288Mi 6.6Gi 9.9Gi Swap: 2.0Gi 0B 2.0Gi • to
578 2