嵌入式 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。这个时候就需要一些工具辅助排查了,能够大大提升效率。


  • 希望本文对你,有些许帮助。
相关文章
|
11天前
|
缓存 Linux
linux 手动释放内存
在 Linux 系统中,内存管理通常自动处理,但业务繁忙时缓存占用过多可能导致内存不足,影响性能。此时可在业务闲时手动释放内存。
64 17
|
14天前
|
消息中间件 Linux
Linux:进程间通信(共享内存详细讲解以及小项目使用和相关指令、消息队列、信号量)
通过上述讲解和代码示例,您可以理解和实现Linux系统中的进程间通信机制,包括共享内存、消息队列和信号量。这些机制在实际开发中非常重要,能够提高系统的并发处理能力和数据通信效率。希望本文能为您的学习和开发提供实用的指导和帮助。
77 20
|
2月前
|
缓存 Java Linux
如何解决 Linux 系统中内存使用量耗尽的问题?
如何解决 Linux 系统中内存使用量耗尽的问题?
223 48
|
1月前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
2月前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
82 1
|
2月前
|
JavaScript
如何使用内存快照分析工具来分析Node.js应用的内存问题?
需要注意的是,不同的内存快照分析工具可能具有不同的功能和操作方式,在使用时需要根据具体工具的说明和特点进行灵活运用。
58 3
|
2月前
|
缓存 Ubuntu Linux
Linux环境下测试服务器的DDR5内存性能
通过使用 `memtester`和 `sysbench`等工具,可以有效地测试Linux环境下服务器的DDR5内存性能。这些工具不仅可以评估内存的读写速度,还可以检测内存中的潜在问题,帮助确保系统的稳定性和性能。通过合理配置和使用这些工具,系统管理员可以深入了解服务器内存的性能状况,为系统优化提供数据支持。
68 4
|
2月前
|
存储 算法 安全
深入理解Linux内核的内存管理机制
本文旨在深入探讨Linux操作系统内核的内存管理机制,包括其设计理念、实现方式以及优化策略。通过详细分析Linux内核如何处理物理内存和虚拟内存,揭示了其在高效利用系统资源方面的卓越性能。文章还讨论了内存管理中的关键概念如分页、交换空间和内存映射等,并解释了这些机制如何协同工作以提供稳定可靠的内存服务。此外,本文也探讨了最新的Linux版本中引入的一些内存管理改进,以及它们对系统性能的影响。
|
2月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
510 1
|
1月前
|
存储 监控 算法
深入探索Java虚拟机(JVM)的内存管理机制
本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。