2011-05-06 75 views
9

为了测试内核在泄漏内存时的行为,我正在编写一个内核模块,用于连续分配内存。代码看起来像如何确定Linux内核模块是否泄漏内存

int bytesLeaked = 128000; 
char *var = kmalloc(bytesLeaked, GFP_KERNEL); 
if (var != NULL) 
printk("leaked %d bytes at address %x\n", bytesLeaked, (unsigned int)var); 

此代码位于init_module中。我有以下问题

  1. 如何确定代码是否泄漏了内存? lsmod并没有透露太多。
  2. 互联网上的教程只显示init_module和exit_module中的代码。如果我希望在插入模块之后但退出之前的一段时间内完成内存分配。
  3. 我是否可以编写泄漏内存的代码,只有当用户给出指令时才会这样做,例如,用户空间程序是否可以执行系统调用,从而导致模块泄漏内存?当它分配的内存块(诸如与kmalloc()),然后输给该存储器块的所有参考文献而没有第一释放它

回答

0
  1. 代码泄漏内存。你的代码没有这样做,因为你仍然有var的范围,并指向你的内存块。如果你在下一行添加var = NULL;,那么你有一个真正的内存泄漏。

  2. 而且它是绝对有可能的,以便用户空间中的事件触发你的内核模块开始分配内存。我不确定您是否可以通过系统调用直接执行此操作,但是如果您不能,那么还有其他方法可以完成此任务。你只需要选择一个并实施它。即使每次想要触发内存分配时都要有一个预定文件,您可以使用touch。虽然我不明白为什么你不能让你的init_module代码产生一个只是随着时间的推移定期分配内存的线程,如果这是你想要的行为。

+4

re 1:内存泄漏的定义属性是从不释放分配,不一定没有对它的引用。另外,'var'可能会在某个时间点超出范围,届时您的引用计数将变为0。 (让我们忽略“参考”在C语言中没有明确定义的事实。) – Karmastan 2011-05-06 19:18:30

+0

谢谢。我试图编写线程的产卵,但代码非常复杂http://www.scs.ch/~frey/linux/kernelthreads.html。你能否提供一个关于如何在没有系统调用的情况下通过用户空间事件触发内存分配的见解。 – kakinada 2011-05-09 07:08:26

+0

KEDR支持2.6.31或更新的内核版本。矿是2.6.28。看起来像KEDR不能使用。我会尝试找到类似的内核工具,我有 – kakinada 2011-05-09 07:24:07

18

如果需要检查,如果一个内核模块已经泄漏的内存和你的机器有x86架构,您可以使用KEDR system,它包括内存泄漏检测。

KEDR不要求您重建内核。在线文档(例如,参见“入门”)介绍了如何安装和使用KEDR。总之,程序如下。

安装(从源):解压源存档 - cmake的< ...> - 让 - 使安装

开始KEDR你加载模块:

$ kedr start <name_of_the_module_to_analyze> -f leak_check.conf 

然后你就可以加载模块并像往常一样使用它。当你卸载它,KEDR会给你debugfs报告(通常debugfs安装/sys/kernel/debug),例如:关于每个泄露

$ cat /sys/kernel/debug/kedr_leak_check/info 
Target module: "...", 
Memory allocations: 3 
Possible leaks: 2 
Unallocated frees: 0 

文件possible_leaks/sys/kernel/debug/kedr_leak_check/提供的信息(地址,大小,调用堆栈)内存块。

最后,你可以停止KEDR(注意/sys/kernel/debug/kedr_leak_check/将消失):

kedr stop 

如果您使用的是带有x86之外架构的系统,Kmemleak也可能是有帮助的,虽然它是比较难一点使用。您可能需要使用CONFIG_DEBUG_KMEMLEAK参数设置为'y'来重建内核。尽管如此,Kmemleak也是一个非常有用的工具。有关详细信息,请参阅内核源代码中的Documentation/kmemleak.txt

+2

KEDR支持2.6.31或更新的内核版本。矿是2.6.28。看起来像KEDR不能使用。我将尝试为我的内核找到类似的工具 – kakinada 2011-05-09 07:27:27