kmemleak的使用---内存泄露检测工具【转】
转自:http://blog.csdn.net/lishenglong666/article/details/8287783
版权声明:本文为博主原创文章,未经博主允许不得转载。
内核泄露检测(kmemleak)
介绍:
Kmemleak 提供了一种可选的内核泄漏检测,其方法类似于跟踪内存收集器。(http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Tracing_garbage_collectors)当独立的对象没有被释放时,其报告记录在 /sys/kernel/debug/kmemleak中。
用法:
CONFIG_DEBUG_KMEMLEAK 在Kernel hacking中被使能,一个内核线程每10分钟(默认值)扫描内存,并打印发现新的未引用的对象的数量。
查看内核打印信息详细过程如下:
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设置。
功能实现的基本方法原理
通过的kmalloc、vmalloc、kmem_cache_alloc等内存分配会跟踪其指针,连同其他
的分配大小和堆栈跟踪信息,存储在PRIO搜索树。
相应的释放函数调用跟踪和指针就会从kmemleak数据结构中移除。
分配的内存块,被认为是独立的,如果没有指针指向它起始地址或块的内部的任何位置,可以发现扫描内存(包括已保存的寄存器)。这意味着,有可能没有办法为内核通过所分配的地址传递块到一个释放函数,因此,该块被认为是一个内存泄漏。
扫描算法步骤:
1。标记的所有分配对象为白色(稍后将剩余的白色物体
考虑独立的)
2。扫描存储器与所述数据片段和栈开始,检查对地址的值存储在PRIO搜索树。如果
一个白色的对象的指针被发现,该对象将被添加到黑名单
3。扫描的灰色对象匹配的地址(一些白色物体可以变成黑色,并添加结束时的黑名单),直到黑色集结束
4。剩下的白色物体被认为是独立儿,并报告写入/sys/kernel/debug/kmemleak。
一些分配的内存块的指针在内核的内部数据结构和它们不能被检测为孤儿。对
避免这种情况,kmemleak也可以存储的数量的值,指向一个
内的块的地址范围内的地址,需要找到使
块不被认为是泄漏。其中一个例子是使用vmalloc()函数。
Kmemleak API
------------
见include / linux / kmemleak.h中的函数原型的头。
kmemleak_init - 初始化kmemleak
kmemleak_alloc - 一个内存块分配的通知
kmemleak_alloc_percpu - 通知的一个percpu的内存块分配
kmemleak_free - 通知的内存块释放
kmemleak_free_part - 通知释放部分内存块
kmemleak_free_percpu - 一个percpu内存块释放的通知
kmemleak_not_leak - 当不是泄露时,标记对象
kmemleak_ignore - 当泄漏时不扫描或报告对象
kmemleak_scan_area - 添加扫描区域内的内存块
kmemleak_no_scan - 不扫描的内存块
kmemleak_erase - 删除一个指针变量的旧值
kmemleak_alloc_recursive - 为kmemleak_alloc,只检查递归
kmemleak_free_recursive - 为kmemleak_free,只检查递归
处理假阳性/阴性
--------------------------------------
对于假性的内存泄漏,但不需要报告的,由于值的内存扫描过程中发现kmemleak是指向这样的对象。为了减少假性报告的数目,kmemleak提供kmemleak_
ignore,kmemleak_scan_area,kmemleak_no_scan,kmemleak_erase的功能,可以指定指针扫描方式,他们的扫描默认情况下不启用。
对于不能确定是否是内存泄露的,kmemleak提供kmemleak_not_leak。kmemleak_ignore的功能可以指定固定类型的数据是否需要扫描或打印,以上具体函数分析详见3.3详细处理处理过程及功能函数分析。
有的泄露只是瞬间的,尤其是在SMP系统,因为指针暂时存储在CPU的寄存器或栈。当内存泄漏时Kmemleak定义MSECS_MIN_AGE(默认为1000)一个对象的最低时间。
限制和缺点
-------------------------
主要缺点是减少了内存分配和性能释放。为了避免其他开销,只进行内存扫描,当在/ sys /kernel/debug/ kmemleak文件被读取。不管怎样,这个工具是用于调试目的,其表现的性能不是重要的。为了保持算法简单,kmemleak的值指向任何扫描一个块的地址范围内的地址。这可能会导致增加假阴性的报告。然而,它包括真正的内存泄漏,最终内存泄露将变得可见。
假阴性的另一个来源是数据存储在非指针值。
在未来的版本中,kmemleak只能扫描指针成员中分配的结构。此功能解决了许多上述假阴性的情况下。
该工具可能存在误报。这些个案的分配块可能不需要被释放(如一些在init_call功能的情况下),这样的指针通过其他方法计算,与通常的container_of宏或指针被存储在一个位置相比不会被kmemleak扫描。页分配和ioremap不被跟踪
测试的特定部分kmemleak
---------------------------------------
在初始启动时,/sys/kernel/debug/kmemleak输出页面比较多。这样的情况下,当检测指定已经开发的代码错误时,可以通过清除/sys/kerner/debug/kmemleak的输出。通过启动kmemleak的扫描后,你可以找到新的未引用的对象,这应该与测试特定的代码段。
详细步骤如下:
要测试的关键部分之前需要清除kmemleak报告:
echo clear > /sys/kernel/debug/kmemleak
测试你的内核或模块...
echo scan =5> /sys/kernel/debug/kmemleak
然后像往常一样查看报告:
cat /sys/kernel/debug/kmemleak
已经测试的实例详见内核文档kmenleak_test.txt文档
1:检测内核内存泄漏的功能
- 关注点1
- 关注点2
* kmemleak_not_leak - mark an allocated object as false positive
* @ptr: pointer to beginning of the object
*
* Calling this function on an object will cause the memory block to no longer
* be reported as leak and always be scanned.
*/
* kmemleak_ignore - ignore an allocated object
* @ptr: pointer to beginning of the object
*
* Calling this function on an object will cause the memory block to be
* ignored (not scanned and not reported as a leak). This is usually done when
* it is known that the corresponding block is not a leak and does not contain
* any references to other allocated memory blocks.
*/
* kmemleak_no_scan - do not scan an allocated object
* @ptr: pointer to beginning of the object
*
* This function notifies kmemleak not to scan the given memory block. Useful
* in situations where it is known that the given object does not contain any
* references to other objects. Kmemleak will not scan such objects reducing
* the number of false negatives.
*/
- 关注点3
that's where your strings go, usually the things you forgot when linking and that cause your kernel not to work. objdump -s -j .rodata .process.o will hexdump it. Note that depending on the compiler, you may have more sections like this. |
- kmemleak_scan()
scan_block(_sdata, _edata, NULL, 1);
scan_block(__bss_start, __bss_stop, NULL, 1);
/* per-cpu sections scanning */
for_each_possible_cpu(i)
scan_block(__per_cpu_start + per_cpu_offset(i),
__per_cpu_end + per_cpu_offset(i), NULL, 1);
#endif
* Struct page scanning for each node.
*/
lock_memory_hotplug();
for_each_online_node(i) {
pg_data_t *pgdat = NODE_DATA(i);
unsigned long start_pfn = pgdat->node_start_pfn;
unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages;
unsigned long pfn;
for (pfn = start_pfn; pfn < end_pfn; pfn++) {
struct page *page;
if (!pfn_valid(pfn))
continue;
page = pfn_to_page(pfn);
/* only scan if page is in use */
if (page_count(page) == 0)
continue;
scan_block(page, page + 1, NULL, 1);
}
}
unlock_memory_hotplug();
struct task_struct *p, *g;
read_lock(&tasklist_lock);
do_each_thread(g, p) {
scan_block(task_stack_page(p), task_stack_page(p) +
THREAD_SIZE, NULL, 0);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
- 问题
kmemleak的使用---内存泄露检测工具【转】的更多相关文章
- vld(Visual Leak Detector) 内存泄露检测工具
初识Visual Leak Detector 灵活自由是C/C++语言的一大特色,而这也为C/C++程序员出了一个难题.当程序越来越复 杂时,内存的管理也会变得越加复杂,稍有不慎就会出现内存问题.内存 ...
- 【YFMemoryLeakDetector】人人都能理解的 iOS 内存泄露检测工具类
背景 即使到今天,iOS 应用的内存泄露检测,仍然是一个很重要的主题.我在一年前,项目中随手写过一个简单的工具类,当时的确解决了大问题.视图和控制器相关的内存泄露,几乎都不存在了.后来想着一直就那个工 ...
- vld,Bounds Checker,memwatch,mtrace,valgrind,debug_new几种内存泄露检测工具的比较,Valgrind Cheatsheet
概述 内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况,在大型的.复杂的应用程序中,内存泄漏是常见的问题.当以前分配的一片内存不再需要使用或无法访问时,但是却 ...
- 精准 iOS 内存泄露检测工具
MLeaksFinder:精准 iOS 内存泄露检测工具 发表于 2016-02-22 | zepo | 23 Comments 背景 平常我们都会用 Instrument 的 Lea ...
- memwatch内存泄露检测工具
工具介绍 官网 http://www.linkdata.se/sourcecode/memwatch/ 其功能如下官网介绍,挑选重点整理: 1. 号称功能: 内存泄露检测 (检测未释放内存, 即 动态 ...
- Android内存泄露---检测工具篇
内存使用是程序开发无法回避的一个问题.如果我们毫不在意肆意使用,总有一天会为此还账,且痛不欲生...所以应当防患于未然,把内存使用细化到平时的每一行代码中. 内存使用概念较大,本篇先讲对已有app如何 ...
- 内存泄露检测工具Valgrind
内存泄露简介 什么是内存泄漏 内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因,程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果. 内存泄 ...
- linux下内存泄露检测工具Valgrind介绍
目前在linux开发一个分析实时路况的应用程序,在联合测试中发现程序存在内存泄露的情况. 这下着急了,马上就要上线了,还好发现了一款Valgrind工具,完美的解决了内存泄露的问题. 推荐大家可以使用 ...
- Unix下C程序内存泄露检测工具:valgrind的安装使用
Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...
随机推荐
- Linux命令行–基本的bash shell命令
启动shell: /etc/passwd:包含系统用户账户列表以及每个用户的基本配置信息 每个条目有七个字段,每个字段用冒号隔开 用户名 用户密码 用户的系统UID 用户的系统GID 用户的全名 用户 ...
- C语言中malloc()和calloc()c函数用法
C语言中malloc()和calloc()c函数用法 函数malloc()和calloc()都可以用来动态分配内存空间,但两者稍有区别. malloc()函数有一个参数,即要分配的内存空间的大小: ...
- 发送xml或json格式的数据给服务器
后台通过context.Request.InputStream来接收 #region 发送消息 + void SendMessage() /// <summary> /// 发送消息 // ...
- IntelliJ IDEA 修改缓存文件设置
今天在查看C盘,发现虽然我idea安装在了D盘,但是idea的缓存还是在C盘 config 目录是 IntelliJ IDEA 个性化化配置目录,或者说是整个 IDE 设置目录.也是我个人认为最重要的 ...
- IDisplayTransformation
IDisplayTransformation Bounds Full extent in world coordinates. The Bounds property controls the ful ...
- PHP PSR-1 基本代码规范(中文版)
基本代码规范 本篇规范制定了代码基本元素的相关标准,以确保共享的PHP代码间具有较高程度的技术互通性. 关键词 “必须”("MUST").“一定不可/一定不能”("MUS ...
- curl命令常见用法汇总 good
curl是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在"标准输出"(stdout)上面. curl是一个强大的命令行工具,它可以通过网络将信息传递给服务器或者从服 ...
- Mysql主从库同步错误:1062 Error 'Duplicate entry '1438019'
mysql主从库同步错误:1062 Error 'Duplicate entry '1438019' for key 'PRIMARY'' on query mysql主从库在同步时会发生1062 L ...
- Swift实战-豆瓣电台(九)简单手势控制暂停播放(全文完)
Swift实战-豆瓣电台(九)简单手势控制暂停播放 全屏清晰观看地址:http://www.tudou.com/programs/view/tANnovvxR8U/ 这节我们主要讲UITapGestu ...
- Groupon面经Prepare: Max Cycle Length
题目是遇到偶数/2,遇到奇数 *3 + 1的题目,然后找一个range内所有数字的max cycle length.对于一个数字,比如说44,按照题目的公式不停计算,过程是 44, 22, 11, 8 ...