kmemleak检测内存泄漏

kmemleak

kmemleak 是 Linux 内核中用于检测 内核内存泄漏(memory leak) 的工具,工作方式类似于用户空间中的垃圾回收器标记-扫描算法。它能帮助开发者查找在内核中分配但未释放、也没有任何引用指针指向的内存区域。

工作原理

  • 分配跟踪:对内核中某些常见的内存分配函数(如 kmalloc, vmalloc, kmem_cache_alloc 等)打钩,记录每一次分配的地址、大小、调用栈信息。
  • 引用扫描:周期性扫描内核中已知的根(如全局变量、任务栈、slab缓存等),查找指向上述分配内存的指针。
  • 未被引用的对象:如果某块内存不能从任何已知根中访问到,认为它“可能”泄漏,并标记为 leak。

启用方式

  1. 编译内核时打开 kmemleak 选项:
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n
  1. 启动参数添加:
kmemleak=on
  1. 确认内核是否编译支持 kmemleak
zcat /proc/config.gz | grep KMEMLEAK

你应该看到这些配置:

CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n
  1. 使用方法
mount -t debugfs debugfs /sys/kernel/debug
echo scan > /sys/kernel/debug/kmemleak
cat /sys/kernel/debug/kmemleak
  1. 检测到泄漏时,你会看到类似输出:
unreferenced object 0xffff908c436a4380 (size 128):
  comm "insmod", pid 104, jiffies 4295071470 (age 28.527s)
  hex dump (first 32 bytes):
    70 65 72 2f 30 00 00 00 00 00 00 00 69 4e 72 2a  per/0.......iNr*
    00 00 00 00 00 00 00 00 10 be b5 be ff ff ff ff  ................
  backtrace:
    [<(____ptrval____)>] 0xffffffffc017b022
    [<(____ptrval____)>] do_one_initcall+0x3f/0x1c0
    [<(____ptrval____)>] do_init_module+0x46/0x220
    [<(____ptrval____)>] __do_sys_init_module+0x158/0x190
    [<(____ptrval____)>] do_syscall_64+0x35/0x80
    [<(____ptrval____)>] entry_SYSCALL_64_after_hwframe+0x6c/0xd6

提供一份人为引发memleak的demo

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>

static void *leak_ptr;

static int __init leak_init(void)
{
    pr_info("Leak demo: loading module\n");

    leak_ptr = kmalloc(128, GFP_KERNEL);  // 分配 128 字节,不释放
    if (!leak_ptr)
        return -ENOMEM;

    pr_info("Allocated memory at %px (not freeing it)\n", leak_ptr);
    return 0;
}

static void __exit leak_exit(void)
{
    pr_info("Leak demo: unloading module\n");

    // kfree(leak_ptr); // 故意不释放 leak_ptr -> 制造内存泄漏

    pr_info("Leaked memory at %px\n", leak_ptr);
}

module_init(leak_init);
module_exit(leak_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Joshua Zhong");
MODULE_DESCRIPTION("Deliberate memory leak for kmemleak test");

编译后insmod这个ko,再rmmod之。

注意事项

  • kmemleak 不能检测引用环(如 A 引用 B,B 引用 A)
  • 它是标记-清除算法,以不可达对象为泄漏依据
  • 一些内核分配器(如 vmalloc)可能不完全支持
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值