一、 <span class="searchword0">Kmemleak</span>检测工具介绍 Kmemleak工作于内核态,Kmemleak 提供了一种可选的内核泄漏检测,其方法类似于跟踪内存收集器。当独立的对象没有被释放时,其报告记录在 /sys/kernel/debug/kmemleak中,Kmemcheck能够帮助定位大多数内存错误的上下文。 Kmemleak使用过程概述 首先CONFIG_DEBUG_KMEMLEAK 在Kernel hacking中被使能. 查看内核打印信息详细过程如下: 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秒内自动记忆扫描 scan 开启内核扫描 clear 清除内存泄露报告 dump=<addr> 转存信息对象在<addr> 通过“kmemleak = OFF”,也可以在启动时禁用Kmemleak在内核命令行。在初始化kmemleak之前,内存的分配或释放这些动作被存储在一个前期日志缓冲区。这个缓冲区的大小通过配CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE设置。 二、 Kmemleak动态检测原理 通过的kmalloc、vmalloc、kmem_cache_alloc等内存分配会跟踪其指针,连同其他的分配大小和堆栈跟踪信息,存储在PRIO搜索树。相应的释放函数调用跟踪和指针就会从kmemleak数据结构中移除。 分配的内存块,被认为是独立的,如果没有指针指向它起始地址或块的内部的任何位置,可以发现扫描内存(包括已保存的寄存器)。这意味着,有可能没有办法为内核通过所分配的地址传递块到一个释放函数,因此,该块被认为是一个内存泄漏。 扫描算法步骤: 1。标记的所有分配对象为白色(稍后将剩余的白色物体考虑独立的) 2。扫描存储器与所述数据片段和栈开始,检查对地址的值存储在PRIO搜索树。如果一个白色的对象的指针被发现,该对象将被添加到灰名单 3。扫描的灰色对象匹配的地址(一些白色物体可以变成灰色,并添加结束时的灰名单),直到黑色集结束 4。剩下的白色物体被认为是独立儿,并报告写入/sys/kernel/debug/kmemleak。 一些分配的内存块的指针在内核的内部数据结构和它们不能被检测为孤儿。对避免这种情况,kmemleak也可以存储的数量的值,指向一个内的块的地址范围内的地址,需要找到使块不被认为是泄漏。 三、kmem相关函数 从kernel源代码中的目录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检测工具介绍
最新推荐文章于 2024-09-29 17:27:18 发布