专栏首页一个程序员的修炼之路Linux Kernel模块内存泄露的一种查找思路

Linux Kernel模块内存泄露的一种查找思路

一. 问题描述

最近有个客户报了一个问题:如果运行我们的产品,则每天将会增长大概30M的内存,大概4个多月内存就会耗尽。和大多数程序员的反应一样,“不会吧,在其他客户机器上都跑的好好的啊,从来都没有遇到过这样的问题”。最后的结果,也往往告诉程序员一个铁的事实:你的程序确实出问题了!

如果你某天发现通过“Free”查看内存几乎耗尽,但通过top/ps命令却看不出来用户态应用程序占用太多的内存空间,那么内核模块可能发生了内存泄露。

二. SLAB简介

SLAB是Linux内核中按照对象大小进行分配的内存分配器。

通过SLAB的信息来查看内核模块占用的内存空间,提供了三种方式(怎么有点像茴香豆的几种写法....囧):

1. 查看meminfo文件

++++++++++++++++++++++++++++++++++++++++++++++++++++++

[root@RHEL5_64 ~]# cat /proc/meminfo | grep Slab Slab: 121588 kB

++++++++++++++++++++++++++++++++++++++++++++++++++++++

2. 查看slabinfo文件

++++++++++++++++++++++++++++++++++++++++++++++++++++++

[root@RHEL5_64 ~]# cat /proc/slabinfo slabinfo - version: 2.1 # name <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab> : tunables <limit> <batchcount> <sharedfactor> : slabdata <active_slabs> <num_slabs> <sharedavail> cifs_small_rq 31 32 448 8 1 : tunables 54 27 8 : slabdata 4 4 0 cifs_request 5 5 16512 1 8 : tunables 8 4 0 : slabdata 5 5 0 cifs_oplock_structs 0 0 64 59 1 : tunables 120 60 8 : slabdata 0 0 0 ......

size-32 29904 29904 32 112 1 : tunables 120 60 8 : slabdata 267 267 0 kmem_cache 156 156 2688 1 1 : tunables 24 12 8 : slabdata 156 156 0

++++++++++++++++++++++++++++++++++++++++++++++++++++++

3. 通过slabtop命令查看

++++++++++++++++++++++++++++++++++++++++++++++++++++++

[root@RHEL5_64 ~]# slabtop

Active / Total Objects (% used) : 630313 / 712770 (88.4%) Active / Total Slabs (% used) : 30213 / 30214 (100.0%) Active / Total Caches (% used) : 105 / 157 (66.9%) Active / Total Size (% used) : 104775.55K / 113499.95K (92.3%) Minimum / Average / Maximum Object : 0.02K / 0.16K / 128.00K OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME 494040 419833 84% 0.09K 12351 40 49404K buffer_head 71856 71832 99% 0.21K 3992 18 15968K dentry_cache 40080 40076 99% 0.74K 8016 5 32064K ext3_inode_cache 29904 29904 100% 0.03K 267 1121068K size-32

......

++++++++++++++++++++++++++++++++++++++++++++++++++++++

以上三种方法,一般查看slabinfo文件就足以,如果发现slabinfo中占用内存过大,那基本可以断定,内核模块出现了内存泄露了,那么我们就要寻找哪里出现了内存泄露呢?

三. 内核模块内存泄露的分析

起初也怀疑是不是因为cache占用了过多的内存,可清楚缓存后内存依旧很大。那摆在面前的只有两条路了:

1. 产品在服务启动的时候,会Load一个我们的Kernel模块,对这个Kernel模块进行Code Review,比如搜索kmalloc的地方,然后查看是否进行了释放。

2. 使用Kdump产生kernel Dump,然后使用Crash对其进行分析。

第一种方法我想程序员都会放在最后一步计划中吧,嘿嘿。于是让客户触发了一个Kernel Dump,然后对其进行了分析,步骤如下:

1. 使用crash加载vmcore (首先要安装相应kernel的Debug Info, Redhat的要有合作账号才能下载到)

++++++++++++++++++++++++++++++++++++++++++++++++++++++

[root@RHEL5_64 analysis]# crash vmcore vmlinux

++++++++++++++++++++++++++++++++++++++++++++++++++++++

2. 查看Slab中那种类型的cache占用内存比较多,名为size-32的cache中分配了208177857个对象,每个对象32个字节,也就是占用了将近6.7G的内存。

++++++++++++++++++++++++++++++++++++++++++++++++++++++

crash> kmem -s ffff810107e4a040 size-32 32 208177857 208177984 1858732 4k

++++++++++++++++++++++++++++++++++++++++++++++++++++++

3. 接着查看Slab size-32中分配的对象地址信息,由于size-32的对象巨多无比,于是将输出的内容重定向到“kmem_size32_slab.txt”:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

crash> kmem -S size-32 > kmem_size32_slab.txt

++++++++++++++++++++++++++++++++++++++++++++++++++++++

4. 然后我们查看重定向到"kmeme_size32_slab.txt"中的对象地址信息,并随机选择一个已分配的对象地址“ffff81021927a780”:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

…… SLAB MEMORY TOTAL ALLOCATED FREE ffff81021927a000 ffff81021927a200 112 112 0 FREE / [ALLOCATED] [ffff81021927a200] …… [ffff81021927a760] [ffff81021927a780] [ffff81021927a7a0] …… ……

++++++++++++++++++++++++++++++++++++++++++++++++++++++

5. 这时候再利用刚才对象的指针,查找对象附近的内存信息,可以查看到很多"sbin/*agt","t.point.*"等字符串信息:

++++++++++++++++++++++++++++++++++++++++++++++++++++++

crash> rd -a ffff81021927a780 10000 …... ffff81021927a824: sbin/*agt/ ffff81021927a832: ' ffff81021927a838: v ffff81021927a840: tmp ffff81021927a844: s.*/ ffff81021927a849: } ffff81021927a850: ( ffff81021927a852: ' ffff81021927a858: q ffff81021927a860: tmp ffff81021927a864: @Vv*/ ffff81021927a86a: t.point.* ffff81021927a878: a ffff81021927a880: tmp ffff81021927a884: @Vv*/ ffff81021927a88a: t.point.* ffff81021927a898: U ffff81021927a8a0: usr ffff81021927a8a4: sbin/*agt/ ……

++++++++++++++++++++++++++++++++++++++++++++++++++++++

6. 以这些对象中存储的字符串为线索,结合产品内核模块中的代码:kmalloc之后存储的字符串哪些可能含有"sbin/*agt","t.point.*",并且最终没有释放。这样很快就定位到了问题的根本原因了。

以上的步骤也只是提供了一种查找产品内核模块内存泄露的一种思路,并且在第4,5步骤需要不断的进行尝试,在这个例子中幸运的是,泄露的那些内存存储的都是些产品中需要用到的字符串,比较容易定位到问题。如果存储的是内核对象的一些地址,可能需要更进一步的分析,并且这些分析都要建立在对自己的产品比较熟悉的基础上。

在解决问题的过程中,也找到了一些资料供大家分享:

Resolving Memory Leaks In Linux Kernel

Slab Allocator

Proc Info

Using Crash Debugger

<<Debug Hackers>>

本文分享自微信公众号 - 一个程序员的修炼之路(CoderStudyShare),作者:iceking

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2015-08-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linux Kernel 模块内存泄露查找 (2)

    在之前的一篇博文<<Linux Kernel模块内存泄露的一种查找思路>>中,我介绍了一种查找内核内存泄露的一种方法。这不才几个月,又有客户埋怨:使用了产品5天...

    河边一枝柳
  • 关于MySQL内存泄露如何排查的一些思路

    MySQL使用内存上升90%!在运维过程中50%的几率,会碰到这样的问题。算是比较普遍的现象。

    数据和云
  • 解Bug之路-记一次JVM堆外内存泄露Bug的查找

    用户1263954
  • 解Bug之路-记一次JVM堆外内存泄露Bug的查找

    JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

    呆呆
  • 解Bug之路-记一次JVM堆外内存泄露Bug的查找 顶

    JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

    无毁的湖光-Al
  • 今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的前言内存泄露Bug现场查找线索总结

    美的让人心动
  • 今咱们来聊聊JVM 堆外内存泄露的BUG是如何查找的

    JVM的堆外内存泄露的定位一直是个比较棘手的问题。此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤了Bug的源头。笔...

    美的让人心动
  • K8S 问题排查:cgroup 内存泄露问题

    这篇文章的全称应该叫:[在某些内核版本上,cgroup 的 kmem account 特性有内存泄露问题],如果你遇到过 pod 的 cannot alloca...

    YP小站
  • 安全漏洞公告

    1 PHP FPM 'php-fpm.conf.in'本地权限提升漏洞 PHP FPM 'php-fpm.conf.in'本地权限提升漏洞发布时间:2014-0...

    安恒信息
  • 跨平台c开发库tbox:内存库使用详解

    TBOX的内存管理模型,参考了linux kernel的内存管理机制,并在其基础上做了一些改进和优化。

    ruki
  • 学习下 BlackHat Asia 2021 大会议题

    BlackHat Asia 2021会议已经结束,相关议题资料也放出,刚好这两天周末抽空学习下,共39个议题,覆盖范围还是比较广的,虽然议题质量不如USA主会场...

    泉哥
  • 句柄泄露问题追踪

    无论是在编写Windows程序还是Linux程序,都可能存在句柄泄露的问题。在Linux中一般来说一个进程的fd使用是有上限的,可以使用ulimit命令进行上限...

    河边一枝柳
  • ROP-Ret2libc学习

    ​ 针对于程序的逻辑了解我们可以编写两个模块,一个是程序自身的代码模块,另一个是共享对象模块。以此来学习动态链接的程序是如何进行模块内的函数调用和...

    ly0n
  • 一次恐怖的 Java 内存泄漏排查实战

    最近在看《深入理解Java虚拟机:JVM高级特性与最佳实践》(第二版)这本书,理论+实践结合,深入浅出,强烈推荐给大家。

    Java技术栈
  • 一次恐怖的 Java 内存泄漏排查实战

    精讲java
  • JVM第一篇:一个Java内存泄漏的排查案例

    黄小怪
  • [linux][memory]balloon技术分析

    前言: 我大天朝人觉得什么东西含量不够,叫做有“水份”。内存的含量不足,叫“balloon”。作者是外语专业毕业的,感觉不同国度的人虽然语言不同,但是表达出来的...

    皮振伟
  • 分享Linux内存占用几个案例

    最近一台 CentOS 服务器,发现内存无端损失了许多,free 和 ps 统计的结果相差十几个G,非常奇怪,后来Google了许久才搞明白。

    YP小站
  • Linux中删除文件,磁盘空间未释放问题追踪

    在客户使用我们产品后,发现一个问题:在删除了文件后,磁盘空间却没有释放。是有进程在打开这个文件,还是其他情况?我们一起来看看一下两个场景

    河边一枝柳

扫码关注云+社区

领取腾讯云代金券