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


  • 希望本文对你,有些许帮助。
相关文章
|
25天前
|
监控 Java Linux
Linux系统之安装Ward服务器监控工具
【10月更文挑战第17天】Linux系统之安装Ward服务器监控工具
49 5
Linux系统之安装Ward服务器监控工具
|
28天前
|
JSON JavaScript Linux
Linux系统之安装cook菜谱工具
【10月更文挑战第15天】Linux系统之安装cook菜谱工具
34 2
Linux系统之安装cook菜谱工具
|
11天前
|
算法 Linux 开发者
深入探究Linux内核中的内存管理机制
本文旨在对Linux操作系统的内存管理机制进行深入分析,探讨其如何通过高效的内存分配和回收策略来优化系统性能。文章将详细介绍Linux内核中内存管理的关键技术点,包括物理内存与虚拟内存的映射、页面置换算法、以及内存碎片的处理方法等。通过对这些技术点的解析,本文旨在为读者提供一个清晰的Linux内存管理框架,帮助理解其在现代计算环境中的重要性和应用。
|
17天前
|
Web App开发 JavaScript 前端开发
使用 Chrome 浏览器的内存分析工具来检测 JavaScript 中的内存泄漏
【10月更文挑战第25天】利用 Chrome 浏览器的内存分析工具,可以较为准确地检测 JavaScript 中的内存泄漏问题,并帮助我们找出潜在的泄漏点,以便采取相应的解决措施。
125 9
|
17天前
|
缓存 监控 Linux
Linux性能分析利器:全面掌握perf工具
【10月更文挑战第18天】 在Linux系统中,性能分析是确保软件运行效率的关键步骤。`perf`工具,作为Linux内核自带的性能分析工具,为开发者提供了强大的性能监控和分析能力。本文将全面介绍`perf`工具的使用,帮助你成为性能优化的高手。
59 1
|
17天前
|
缓存 监控 Linux
掌握Linux性能分析:深入探索perf工具
【10月更文挑战第26天】
22 1
|
17天前
|
存储 缓存 监控
|
1月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
49 2
|
1月前
|
算法 Linux
Linux中内存问题
【10月更文挑战第6天】
41 2
|
14天前
|
缓存 算法 Linux
Linux内核中的内存管理机制深度剖析####
【10月更文挑战第28天】 本文深入探讨了Linux操作系统的心脏——内核,聚焦其内存管理机制的奥秘。不同于传统摘要的概述方式,本文将以一次虚拟的内存分配请求为引子,逐步揭开Linux如何高效、安全地管理着从微小嵌入式设备到庞大数据中心数以千计程序的内存需求。通过这段旅程,读者将直观感受到Linux内存管理的精妙设计与强大能力,以及它是如何在复杂多变的环境中保持系统稳定与性能优化的。 ####
23 0