如何确定Linux内核模块是否泄漏内存

时间:2011-05-06 11:12:50

标签: linux-kernel memory-management kernel-module

为了测试内核泄漏内存时的行为,我正在编写一个连续分配内存的内核模块,例如:代码看起来像

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. 我是否可以编写仅在用户给出指令时泄漏内存的代码,例如用户空间程序可以进行系统调用,这会导致模块泄漏内存吗?

2 个答案:

答案 0 :(得分:18)

如果您需要检查内核模块是否泄漏内存并且您的计算机是否具有x86体系结构,则可以使用KEDR system,它包括内存泄漏检测程序。

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

安装(来源):untar源档案 - cmake< ...> - make - make install

在加载模块之前启动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

答案 1 :(得分:0)

  1. 代码在分配内存块(例如kmalloc())时会泄漏内存,然后丢失对该内存块的所有引用,而不会先释放它。您的代码没有这样做,因为您在范围内仍然有var并指向您的内存块。如果您在下一行添加var = NULL;,那么您将获得真正的内存泄漏。

  2. 完全有可能让用户空间中的事件触发内核模块开始分配内存。我不确定你是否可以通过系统调用直接进行,但如果你不能,那么还有很多其他方法可以完成任务。你只需要选择一个并实现它。甚至像每次想要触发内存分配时touch预定文件一样简单的事情也应该有效。虽然我不明白为什么你不能让你的init_module代码产生一个只是随着时间的推移定期分配内存的线程,如果那是你想要的行为。