为了测试内核泄漏内存时的行为,我正在编写一个连续分配内存的内核模块,例如:代码看起来像
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中。我有以下问题
答案 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)
代码在分配内存块(例如kmalloc()
)时会泄漏内存,然后丢失对该内存块的所有引用,而不会先释放它。您的代码没有这样做,因为您在范围内仍然有var
并指向您的内存块。如果您在下一行添加var = NULL;
,那么您将获得真正的内存泄漏。
完全有可能让用户空间中的事件触发内核模块开始分配内存。我不确定你是否可以通过系统调用直接进行,但如果你不能,那么还有很多其他方法可以完成任务。你只需要选择一个并实现它。甚至像每次想要触发内存分配时touch
预定文件一样简单的事情也应该有效。虽然我不明白为什么你不能让你的init_module
代码产生一个只是随着时间的推移定期分配内存的线程,如果那是你想要的行为。