linux pmap 内存泄露,一个驱动导致的内存泄漏问题的分析过程(meminfo-pmap-slabtop-alloc_calls)...

关键词:sqllite、meminfo、slabinfo、alloc_calls、nand、SUnreclaim等等。

下面记录一个由于驱动导致的内存泄漏问题分析过程。

首先介绍问题背景,在一款嵌入式设备上,新使用sqllite库进行数据库操作,在操作数据(大量读写操作)一段时间之后,发生OOM现象。

然后OOM会选择进程kill,即使系统中不剩什么进程,仍然内存紧张。

下面就介绍从上往下查找问题,然后在底层掐住RootCause,进而解决问题的分析过程。

1. 问题初步分析

首先怀疑的是sqllite库问题,在PC进行同样的测试未发现内存泄漏。在另一款参考设备上,进行同样的测试,未发现内存泄漏。

以上测试确保了测试程序、sqllite库等一致,仅交叉工具链和平台不一致。

结论:可以基本肯定sqllite库以及测试程序没有问题,可能的问题包括交叉工具链、平台问题。平台问题更大,所以问题集中到具体平台上进行分析。

疑问点:

1. 为何进程退出后,泄漏的内存没有释放?参见分析,是因为SUnreclaim的slab内存不在进程内存统计范围之内。

2. 是否由于工具链不同导致库函数表现不一致?参见分析1,内存泄漏点在内核驱动中。 参见分析2,经过在RAM上运行sqllite测试;单独测试NAND文件系统,得出泄漏和sqllite无关。

3. 是平台内核导致的泄漏吗?参见分析,确定泄漏在kmalloc-4096这个slab中。

2. 具体平台查找内存泄漏方向

定位内存泄漏按照从大到小的思路,即首先看系统内存哪里泄漏,然后再看进程内存哪里泄漏,最后看哪种内存泄漏。

2.1 分析系统内存

首先通过cat /proc/meminfo,然后分析泄漏点。

从MemFree和MemAvailable看,内存将低了235M和228M。

然后看一下下面内存消耗在哪里?可以看出slab消耗了228M,再细节可以看出SUreclaim消耗了228M。基本确定

effb2753294d710f176a1467d3110004.png

结论:确定由于Unreclaim类型的slab泄漏导致的内存泄漏。

疑问点:找出具体哪个slab泄漏了?参见分析,在kmalloc-4096这个slab中。 哪个调用的slab申请?参见分析,通过kmalloc-4096的alloc_calls可以知道调用点。

2.2 分析进程内存

通过pmap -X -p `pidof xxx`来获取进程的地址映射空间,可以分析进程内存细节。

0bbf3ebb4aaec26e1f4672181e80ee5b.png

结论:通过下面的对比,可以看出进程本身没有导致内存泄漏。所以内存泄漏虽然有此进程导致,但是泄漏点不在进程中。

2.3 分析slab内存泄漏点

既然确定slab导致的泄漏,那么就需要使用slabtop、/proc/slabinfo以及/sys/kernel/slab来分析。

从下面可以看出泄漏点在kmalloc-4096这个slab,这个slab消耗的内存为250M左右。

e05a3750f3377c3481a8509e02c1030f.png

然后就是去找slab的调用记录,幸运的是系统在/sys/kernel/slab/*/中提供了alloc_calls和free_calls。

alloc_calls:

1 pidmap_init+0x4e/0x10c age=418000 pid=0

1 con_init+0xf6/0x21c age=418007 pid=0

1 pcpu_mem_zalloc+0x36/0x74 age=417641 pid=1

1 seq_buf_alloc+0x26/0x54 age=0 pid=349

1 register_leaf_sysctl_tables+0x74/0x1b0 age=418000 pid=0

1 ubifs_mount+0x68/0x15e8 age=416589 pid=1

1 ubifs_mount+0xdaa/0x15e8 age=416588 pid=1

1 nand_scan_tail+0xa2/0x6a8 age=417469 pid=1

1 ubi_attach_mtd_dev+0x9a/0xc38 age=417168 pid=1

1 sourcesink_bind+0x382/0x4c0 age=417588 pid=1

1 vid_dev_probe+0x32/0x1a0 age=417569 pid=1

2 hantrodec_probe+0x56/0x944 age=417502/417512/417523 pid=1

55898 spinand_cmdfunc+0x236/0x52c age=8997/225988/416514 pid=1-202 1 flow_cache_cpu_prepare.isra.7+0x3c/0x74 age=417889 pid=1

free_calls:

55840 age=343019 pid=0

59 kvfree+0x2a/0x60 age=0/239003/415431 pid=140-349

1 ubifs_read_superblock+0x690/0xe14 age=416600 pid=1

8 kobject_uevent_env+0xda/0x580 age=416605/417396/417653 pid=1

3 uevent_show+0x5e/0xf4 age=409638/411302/413798 pid=143-150

1 skb_free_head+0x2c/0x6c age=417902 pid=1

结论:从alloc_calls可以看出spinand_cmdfunc中申请了55898次slab,和系统内存泄漏量基本一致。

2.4 分析驱动内存泄漏

通过objdump -S -l -D vmlinux > vmlinux.txt,然后结合反汇编代码,找到spinand_cmdfunc+0x236可以找到具体点。

805829e2: e3f26433 bsr 0x803cf248 //803cf248 <_end>

805829e6: c4004820 lsli r0, r0, 0spinand_cmdfunc():/home/al/deepeye1000/linux/drivers/staging/mt29f_spinand/mt29f_spinand.c:806spinand_program_page(info->spi, state->row, state->col,

所以问题最终指向了mt29f_spinand.c的806行,spinand_program_page()这个函数里面。

分析此驱动代码,可以看出通过devm_kzalloc()申请的内存没有被释放的点。虽然此内存在模块卸载的时候会被自动释放,但是NAND驱动一般不会被卸载。

1443164cc167667f8d9fdfc94ab8605a.png

结论:确定泄漏点在spinand_program_page()中。

3. 旁证测试

基本上找到的问题点,为了验证上述分析做了几个简单的测试。

3.1 在ramfs中进行sqllite数据库操作

既然泄漏点在NAND驱动中,那么避开在NAND中进行读写操作即可。在/tmp目录下,进行数据库操作,作为对比测试。

同样的软件和平台下,运行同样的业务。

结论:在ramfs中进行操作,没有发生内存泄漏。说明泄漏sqllite操作无关。。

3.2 在NAND上进行文件cp、rm等操作

既然泄漏点在NAND,那么不使用数据库读写,纯文件系统读写如何呢?

经过测试,同样发现SUreclaim内存增加导致的泄漏。

结论:内存泄漏跟NAND上文件操作有关。

为什么之前没有发现内存泄漏问题呢?原来主要业务是运行应用,很少对NAND进行写,即使有写也是偶尔的,发现不了内存泄漏。这种情况在频繁的读写、删除操作下比较容易复现。

4. 解决问题

解决的思路就是确保在函数退出的时候,保证wbuf的内存能够得到释放。

diff--git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c

index 2474d88..7042934 100644

--- a/drivers/staging/mt29f_spinand/mt29f_spinand.c+++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c

@@-495,7 +495,8 @@ static int spinand_program_page(struct spi_device *spi_nand,

#ifdef CONFIG_MTD_SPINAND_ONDIEECC

unsignedinti, j;- wbuf = devm_kzalloc(&spi_nand->dev, CACHE_BUF, GFP_KERNEL);

+ wbuf = kzalloc(CACHE_BUF, GFP_KERNEL);if (!wbuf)return -ENOMEM;

@@-509,7 +510,7 @@ static int spinand_program_page(struct spi_device *spi_nand,

retval=spinand_enable_ecc(spi_nand);if (retval < 0) {

dev_err(&spi_nand->dev, "enable ecc failed!!");- return retval;

+ gotoexit;

}

}#else...

-

- return 0;

+exit:

+#ifdef CONFIG_MTD_SPINAND_ONDIEECC

+ kfree(wbuf);

+#endif

+ returnretval;

}

5. 验证测试

基于以上的分析过程,构建测试用例:

1. 进行同样的NAND上sqllite数据操作

2. 同样重复cp、rm操作NAND上文件系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/555160.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础--awt详解以及简单应用

GUI 图形用户界面 CLI 命令行用户接口 Java为GUI提供的对象存在java.Awt和Javax.Swing两个包中. Java当中如何完成图形化界面的制作呢? AWT:abstract Window ToolKit.需要调用本地系统实现功能.属于重量级控件.依赖于平台.跨平台性不是特别好. Javax.Swing:在AWT基础上.建立一…

Java图形化界面设计之容器(JFrame)详解

Java图形化界面设计之容器&#xff08;JFrame&#xff09;详解 Java图形化界面设计——容器&#xff08;JFrame&#xff09; 程序是为了方便用户使用的&#xff0c;因此实现图形化界面的程序编写是所有编程语言发展的必然趋势&#xff0c;在命令提示符下运行的程序可以让我们…

10个最受欢迎的JavaScript图表库

目前网上有很多用于绘制图表图形的免费JavaScript插件和图表库&#xff0c;技术学派在这里给大家推荐10个比较强大的绘制图表图形的JavaScript图表库。其中一些插件需要主流浏览器的支持&#xff0c;而另外一些经过整合后&#xff0c;也能在不同的平台和老版本的浏览器上工作。…

sudo 命令_su、sudo、sudo su、sudo -i的用法和区别

sudo 命令 1、sudo 简介 sudo是linux系统管理指令&#xff0c;是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具&#xff0c;如halt&#xff0c;reboot&#xff0c;su等等。这样不仅减少了root用户的登录 和管理时间&#xff0c;同样也提高了安全性。sudo不是…

c语言不能在函数中求数组大小,C语言中数组长度不能用变量定义吗?

翻翻过去那场雪1、C语言中不支持。C中支持变长数组(你可以自行度娘变长数组和alloca函数)&#xff0c;但是因为其实在栈上分配&#xff0c;不被推荐使用。做为解决方案&#xff0c;你可以使用C式的malloc函数或者C式的new函数来在堆上动态分配内存&#xff0c;这样长度是完全可…

Java如何基于ProcessBuilder类调用外部程序

Java如何基于ProcessBuilder类调用外部程序 demo1 Testpublic void testProcessBuilder() {ProcessBuilder processBuilder new ProcessBuilder(); // processBuilder.command("ping","127.0.0.1");processBuilder.command("ipconfig");//…

计算机专业课程设计报告c语言,计算机程序设计(C语言)课程设计报告.doc

计算机程序设计(C语言)课程设计报告.doc计算机程序设计C语言课程设计报告题目电子动画时钟 学院 机电工程学院专业 班级090109班学号 姓名 指导教师 设计日期 一、概述选题背景 随着社会的进步和科技的发展&#xff0c;电子钟表逐渐成为了人们生活中不可缺少的一部分。设计思路…

c语言用栈编写数制转换程序,数制转换-栈的应用(C++实现)

本程序实现的是十进制与不同进制之间的的数据转换&#xff0c;利用的数据结构是栈&#xff0c;基本数学方法辗转相除法。conversion.h#includeusing namespace std;//将十进制的数据n转换成m进制的数据stack conversion(unsigned int n,unsigned int m){stack s;while(n){s.pus…

两个变量实现查找坏环c语言,C/C++编程笔记:C语言编程知识要点总结!大一C语言知识点(全)...

程序员无言 2020-07-07一、C语言程序的构成与C、Java相比&#xff0c;C语言其实很简单&#xff0c;但却非常重要。因为它是C、Java的基础。不把C语言基础打扎实&#xff0c;很难成为程序员高手。1、C语言的结构先通过一个简单的例子&#xff0c;把C语言的基础打牢。C语言的结构…

累加器A用c语言,累加器A的主要作用是什么_一文解析累加器a和acc的区别

描述累加器简介在中央处理器中&#xff0c;累加器(accumulator) 是一种寄存器&#xff0c;用来储存计算产生的中间结果。如果没有像累加器这样的寄存器&#xff0c;那么在每次计算 (加法&#xff0c;乘法&#xff0c;移位等等) 后就必须要把结果写回到内存&#xff0c;也许马上…

Java中的<<、>>、>>>运算符

二进制中的原码、反码、补码 有符号数&#xff1a; 对于有符号数而言&#xff0c;符号的正、负机器是无法识别的&#xff0c;但由于“正、负”恰好是两种截然不同的状态&#xff0c;如果用“0”表示“正”&#xff0c;用“1”表示“负”&#xff0c;这样符号也被数字化了&…

actionscript 3.0 怎么写android 程序,(ActionScript3.0笔记)第一个程序HelloWorld!

(ActionScript3.0笔记)第一个程序HelloWorld!创建我的第一个ActionScript3.0程序--HelloWord&#xff01;首先下载ActionScript3.0的集成开发环境&#xff0c;FLASH CS4 Professional。从网站下载FLASH CS4 Professional软件的安装包程序&#xff0c;下载好后进行安装。安装后在…

android.app.activityview,ViewModel 概览

ViewModel 概览ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。注意&#xff1a;如需将 ViewModel导入 Android 项目&#xff0c;请参阅 Lifecycle 版本说明中关于声明依赖项的说明。Android 框架可…

使用Navicat将数据从Excel导入到MySQL数据库

数据库中的表已经建好了&#xff0c;现在要将数据从Excel导入 要求&#xff1a;Excel中要有一行为字段名&#xff08;可以与数据表中的字段名顺序不一样&#xff09; 具体步骤 1、右键单击表&#xff0c;选择 导入向导 2、选择数据导入格式&#xff0c;然后点击下一步 3…

html5 a-z字母排序,Mint UI实现A-Z字母排序的城市选择列表

本文实例为大家分享了Mint Ul实现A-Z字母排序的城市选择列表的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下效果图如下&#xff1a;项目文件存放路径图&#xff1a;所有代码如下&#xff1a;import city from "../assets/json/city"//导入所有城市的JSON…

Geometry几何结构与WKT空间坐标计算缓冲距离模型构建

geometry&#xff0c;英语单词&#xff0c;名词&#xff0c;意思是“几何学几何结构”。 http://www.baike.com/wiki/WKTWKT&#xff0c;是一种文本标记语言&#xff0c;用于表示矢量几何对象、空间参照系统及空间参照系统之间的转换。它的二进制表示方式&#xff0c;亦即WKB(…

html5开发之ios屏幕适配,iOS开发屏幕尺寸以及屏幕适配等问题(转载内容)

原帖地址&#xff1a;http://blog.csdn.net/phunxm/article/details/42174937/仅供我个人收藏学习&#xff0c;原博主如不同意请联系qq651263878进行删除&#xff0c;在此表示感谢以及歉意。1.iPhone尺寸规格后续上市的iPhone7以及iPhone7plus 与六代相同1 inch 2.54cm 25.4…

flink checkpoint 恢复_Flink解析 | Apache Flink结合Kafka构建端到端的ExactlyOnce处理

周凯波(宝牛)阿里巴巴技术专家&#xff0c;四川大学硕士&#xff0c;2010年毕业后加入阿里搜索事业部&#xff0c;从事搜索离线平台的研发工作&#xff0c;参与将搜索后台数据处理架构从MapReduce到Flink的重构。目前在阿里计算平台事业部&#xff0c;专注于基于Flink的一站式计…

Java通过ftl模板导出word最详细教程

首先用office建一个word文档 参数写自己查询出来的字段&#xff0c;我在这里房里图片是方便找到位置替换为64位编码 模板创建好之后&#xff0c;另存为Word 2003 XML文档(*.xml) 存储为别的可能会报错&#xff0c;我只用这一种 存储为xml之后千万不要用word打开&#xff0c;最…

封装html ui 控件,聊聊前端 UI 组件:组件设计

本文首发于欧雷流。由于我会时不时对文章进行补充、修正和润色&#xff0c;为了保证所看到的是最新版本&#xff0c;请阅读原文。在本系列文章《聊聊前端 UI 组件&#xff1a;组件体系》中初步说明了 UI 组件的架构设计&#xff0c;本文将在此基础上进一步展开说说那篇文章中一…