在Kernel hacking中打开CONFIG_DEBUG_KMEMLEAK =y即使能了kmemleak,其实就是开了一个内核线程,该内核线程每10分钟(默认值)扫描内存,并打印发现新的未引用的对象的数量。kmemleak的原理其实就是通过kmalloc、vmalloc、kmem_cache_alloc等内存的分配,跟踪其指针,连同其他的分配大小和堆栈跟踪信息,存储在PRIO搜索树。如果存在相应的释放函数调用跟踪和指针,就会从kmemleak数据结构中移除。下面我们看看具体的用法。
查看内核打印信息详细过程如下:
1、挂载debugfs文件系统
mount -t debugfs nodev /sys/kernel/debug/
2、开启内核自动检测线程
echo scan > /sys/kernel/debug/kmemleak
3、查看打印信息
cat /sys/kernel/debug/kmemleak
4、清除内核检测报告,新的内存泄露报告将重新写入/sys/kernel/debug/kmemleak
echo clear > /sys/kernel/debug/kmemleak
内存扫描参数可以进行修改通过向/sys/kernel/debug/kmemleak 文件写入。 参数使用如下:
off 禁用kmemleak(不可逆)
stack=on 启用任务堆栈扫描(default)
stack=off 禁用任务堆栈扫描
scan=on 启动自动记忆扫描线程(default)
scan=off 停止自动记忆扫描线程
scan=<secs>设置n秒内自动记忆扫描,默认600s
scan 开启内核扫描
clear 清除内存泄露报告
dump=<addr>转存信息对象在<addr>
通过“kmemleak = off”,也可以在启动时禁用Kmemleak在内核命令行。在初始化kmemleak之前,内存的分配或释放这些动作被存储在一个前期日志缓冲区。这个缓冲区的大小通过配CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE设置。
假如通过“Free”查看内存几乎耗尽,但通过 top/ps 命令却看不出来用户态应用程序占用太多的内存空间, 那么内核模块可能发生了内存泄露
SLAB 是Linux内核中按照对象大小进行分配的内存分配器。
通过SLAB的信息来查看内核模块占用的内存空间:
方法1. 查看meminfo文件
方法2. 查看slabinfo文件
一般查看slabinfo文件就足以,如果发现slabinfo中占用内存过大,那基本可以断定,内核模块出现了内存泄露了
还有个命令 slabinfo 也是可以看,其实也是去读 /proc/slabinfo 后可视化出来
Linux内核的Kmemleak实现内存泄露检测
看看下面这个函数是哪里导致的内存泄漏呢?
一眼可能不容易看出上面的有什么问题,有kmalloc,有kfree 成对出现的。
问题正好出在 pr_debug 这个函数中的参数传递, 熟悉函数调用传参的人应该会知道编译器一般对参数的处理采用堆栈的方式,是一个先进后出的过程,这样参数的执行一般是逆序的(由于编译器实现的不同,这个过程不是确定的),这样kfree会在kmalloc之前运行,导致每次运行都会泄漏一点内存。
Resolving Memory Leaks In Linux Kernel
Slab Allocator
Proc Info
Using Crash Debugger
是不是说没有一种内存检查工具能够在linux使用呢,也不是,像valgrind工具还是相当不错的。他的下载地址是 下载一个valgrind 3.2.3 (tar.bz2) 工具,按照里面的README提示,安装后就可以使用这个工具来检测内存泄露和内存越界等。这是一个没有界面的内存检测工具,安装后,输入valgrind ls -l 验证一下该工具是否工作正常(这是README里面的方法,实际上是验证一下对ls -l命令的内存检测),如果你看到一堆的信息说明你的工具可以使用了。 在编译你的程序时,请设置-g参数,编译出后使用如下的命令来判断你的程序存在内存泄露: valgrind --tools=memcheck --leak-check=full yourProg在输出信息中就会看到你的内存问题了。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)