kmemleak的使用

kmemleak 是一个类似在kernel 里面的Valgrind, 可以检测kernel 模块的memory leak情况。

至于如何使用,kernel 里面自己的文档就已经写的很清楚,可以参考: Documentation/dev-tools/kmemleak.rst

如果出现如下错误:

# echo scan > /sys/kernel/debug/kmemleak
sh: write error: Operation not permitted

这个可能是在kernel中的配置使能了CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 或者是boot arg里面有:kmemleak=off 。

解决办法就是去掉 CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF 这个配置或者在bootargs 里面加上 kmemleak=on 即可解决。

参考如下log:

# modprobe kmemleak-test
[  560.184144] kmemleak: Kmemleak testing
[  560.184233] kmemleak: kmalloc(32) = (____ptrval____)
[  560.184335] kmemleak: kmalloc(32) = (____ptrval____)
[  560.184436] kmemleak: kmalloc(1024) = (____ptrval____)
[  560.184538] kmemleak: kmalloc(1024) = (____ptrval____)
[  560.184640] kmemleak: kmalloc(2048) = (____ptrval____)
[  560.184742] kmemleak: kmalloc(2048) = (____ptrval____)
[  560.184843] kmemleak: kmalloc(4096) = (____ptrval____)
[  560.184946] kmemleak: kmalloc(4096) = (____ptrval____)
[  560.185164] kmemleak: vmalloc(64) = (____ptrval____)
[  560.185368] kmemleak: vmalloc(64) = (____ptrval____)
[  560.185573] kmemleak: vmalloc(64) = (____ptrval____)
[  560.185778] kmemleak: vmalloc(64) = (____ptrval____)
[  560.185984] kmemleak: vmalloc(64) = (____ptrval____)
[  560.186086] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186193] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186299] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186488] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186595] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186701] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186809] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.186916] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.187023] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.187131] kmemleak: kzalloc(sizeof(*elem)) = (____ptrval____)
[  560.187239] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187339] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187440] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187540] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187641] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187743] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187843] kmemleak: kmalloc(129) = (____ptrval____)
[  560.187944] kmemleak: kmalloc(129) = (____ptrval____)
# echo scan > /sys/kernel/debug/kmemleak

[  696.107594] kmemleak: 12 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
#
# cat /sys/kernel/debug/kmemleak
unreferenced object 0xffff00080089f9a0 (size 32):
  comm "modprobe", pid 153, jiffies 4295032338
  hex dump (first 32 bytes):
    cf df df df df df df cf cf df df df df df df cf  ................
    c0 f9 89 00 08 00 ff ff cf df df df df df df cf  ................
  backtrace (crc 271abd9a):
    [<(____ptrval____)>] kmemleak_alloc+0x34/0x40
    [<(____ptrval____)>] kmalloc_trace+0x1d8/0x284
    [<(____ptrval____)>] kmemleak_test_init+0x50/0x2a8 [kmemleak_test]
    [<(____ptrval____)>] do_one_initcall+0x80/0x1c8
    [<(____ptrval____)>] do_init_module+0x60/0x218
    [<(____ptrval____)>] load_module+0x1bbc/0x1d88
    [<(____ptrval____)>] init_module_from_file+0x88/0xcc
    [<(____ptrval____)>] __arm64_sys_finit_module+0x1dc/0x2e4
    [<(____ptrval____)>] invoke_syscall+0x48/0x114
    [<(____ptrval____)>] el0_svc_common.constprop.0+0x40/0xe0
    [<(____ptrval____)>] do_el0_svc+0x1c/0x28
    [<(____ptrval____)>] el0_svc+0x34/0xd8
    [<(____ptrval____)>] el0t_64_sync_handler+0x120/0x12c
    [<(____ptrval____)>] el0t_64_sync+0x190/0x194

Comments !