Linux-3.14.12内存管理笔记【内存泄漏检测kmemleak示例】【转】

本文转载自:http://blog.chinaunix.net/uid-26859697-id-5758037.html

分析完kmemleak实现后,照常实验一下,以确定功能正常。

如kmemcheck一样,该功能需要在内核开启的情况下才能够使用。主要的配置项有:CONFIG_DEBUG_KERNEL、CONFIG_HAVE_DEBUG_KMEMLEAK、CONFIG_DEBUG_KMEMLEAK,以及配置信息记录条数的CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE,通常情况下配置数量的可以不必修改,但是针对自启动初始化的模块,还是有必要进行调整的,以便记录更多的信息,避免遗漏。

以上几项的在make menuconfig编译配置内核时,配置路径如下:

Kernel hacking

+——>Kernel Debugging(该项需要开启)

+——>Memory Debugging

+——>Kernel memory leak detector(开启该项)

当然,这几项配置项是对其他配置项存在一定的依赖的,具体可以在make menuconfig反斜杠搜索对应配置项进行了解。

设置的过程中有几项需要特别注意的就是,在“Kernel memory leak detector”开启后展开的几项子项注意不要进行设置了,其中有:“Simple test for the kernel memory leak detector”和“Default kmemleak to off”。

例如实验中配置选项设置如下:

编译好内核之后,安装该调测版本的内核,重新启动linux系统,进入新内核。将会能够查看到/sys/kernel/debug/kmemleak该路径文件的存在。如果存在,则表明开启成功。

该实验仍使用64位系统做演示,修改前面kmemcheck的实验代码,构造内存泄漏。具体代码如下:

  1. #include <linux/init.h>
  2. #include <linux/module.h>
  3. #include <linux/mm.h>
  4. #include <linux/slab.h>
  5. #include <asm/page.h>
  6. void kmemleak_memalloc(void)
  7. {
  8. char *pmem;
  9. pmem = kmalloc(300, GFP_KERNEL);
  10. if (!pmem)
  11. {
  12. printk("[Kmemleak]: kmalloc fail!\n");
  13. }
  14. else
  15. {
  16. printk("[Kmemleak]: kmalloc return %p \n", pmem);
  17. }
  18. }
  19. int __init kmemleak_test_init(void)
  20. {
  21. printk("[Kmemleak]: kmemleak_test_init! \n");
  22. kmemleak_memalloc();
  23. return 0;
  24. }
  25. void __exit kmemleak_test_exit(void)
  26. {
  27. printk("[Kmemleak]: kmemleak_test_exit now \n");
  28. }
  29. module_init(kmemleak_test_init)
  30. module_exit(kmemleak_test_exit)
  31. MODULE_LICENSE("GPL");

Makefile脚本稍作修改后:

  1. obj-m = kmemleak_test.o
  2. all:
  3. make -C /lib/modules/`uname -r`/build M=`pwd`
  4. clean:
  5. rm -f *.o *.ko *.mod.c modules.order Module.symvers

编译内核ko后,通过ismod命令安装模块,根据代码的编写打印的日志信息,通过dmesg进行确认模块初始化完毕且内存申请妥当。

相关信息如下:

为了保证实验的成功,ko安装完毕后,等待了几分钟后。

通过命令:echo scan > /sys/kernel/debug/kmemleak,进行内存扫描检测。检测结果将会在/sys/kernel/debug/kmemleak文件中记录。通过dmesg的信息可以看到申请的内存空间位于0xffff95c9bf81b600地址。搜索一下,便可以看到kmemleak中的信息记录:

kmemleak的检测结果信息中,清晰地记录了申请该内存的调用栈信息、内存头32byte的信息以及泄漏的内存地址及大小。但是这里的大小并不是一个很精确的大小,这里呈现的是一个slab内存片的大小,实验中申请的空间大小为300字节,对应为512字节的slab片。具体的结合代码进行分析部分就省略掉了,那是开发人员必备的基础能力,鄙人就不班门弄斧了。

接下来细述一下kmemleak的控制参数,控制kmemleak主要是通过往/sys/kernel/debug/kmemleak文件中写入参数。例如前面使能kmemleak进行内存泄漏扫描的命令是写入scan,具体的命令则是:echo scan > /sys/kernel/debug/kmemleak。而清除kmemleak的扫描结果使用的参数是clear,对应的命令是:echo clear > /sys/kernel/debug/kmemleak。

更多的kmemleak参数有:

  1. off - disable kmemleak (irreversible)
  2. stack=on - enable the task stacks scanning (default)
  3. stack=off - disable the tasks stacks scanning
  4. scan=on - start the automatic memory scanning thread (default)
  5. scan=off - stop the automatic memory scanning thread
  6. scan=<secs> - set the automatic memory scanning period in seconds
  7. (default 600, 0 to stop the automatic scanning)
  8. scan - trigger a memory scan
  9. clear - clear list of current memory leak suspects, done by
  10. marking all current reported unreferenced objects grey
  11. dump=<addr> - dump information about the object found at <addr>

如果要是测试内核模块,正确的操作步骤应为:

1、 清除kmemleak的历史信息,以便记录新数据:

#echo clear > /sys/kernel/debug/kmemleak

2、 加载需要测试的内核模块,并执行相关测试用例;

#ismod ***.ko

3、 使能kmemleak进行内存泄漏扫描:

#echo scan > /sys/kernel/debug/kmemleak

4、 查看分析扫描结果:

#cat /sys/kernel/debug/kmemleak

至此,实验完毕,kmemleak挺好用的,适用于内核模块开发用于检测定位内存泄漏问题。

原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9016132.html

时间: 2024-10-09 12:29:15

Linux-3.14.12内存管理笔记【内存泄漏检测kmemleak示例】【转】的相关文章

Linux内存管理 (一) 内存组织

内存管理是内核最复杂同时也是最重要的一部.其特点在于非常需要处理器和内核之间的协作. 首先内存划分为结点,在内核中表示为pg_data_t,每个结点划分为内存域. 以下的所有数据结构或代码都做了不同程度的精减,一方面是为了保留相关代码,除去细枝末叶,另一方面是为了美观. 结点的数据结构为 <mmzone.h>typedef struct pglist_data { struct zone node_zones[MAX_NR_ZONES]; /*内存结点所包含的内存域数组*/ struct zo

内存管理:内存泄漏和空悬指针

********内存管理基础********************* 内存管理:针对的是实例的内存占用的管理(放在堆里面) 实例:1:由class类型构建的实例,2:闭包对象 内存管理技术:ARC:Automatic Reference Count 自动:由语言本身帮我们销毁内存,不需要你手动销毁, 比如在c中就调用dealloc() 引用:let p = Person()  p就是对Person()这个对象的一个引用 计数: let p = Person() //一个 / / let pp

java基础---JVM内存管理以及内存运行机制学习总结

自己从网上搜资料拼接了一张JVM内存图:如下图所示: 我们思考几个问题: 1.jVM是怎么运行的? 2.JVM运行时内存是怎么分配的? 3.我们写的java代码(类,对象,方法,常量,变量等等)最终存放在哪个区? VM运行时数据区域: 1.程序计数器(program Counter Register):   是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的行号指示器.在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的 方式去实 现),字节码解释器工作时就是通过改

内存管理笔记

目前实现智能管理内存的技术,一是引用计数,一是垃圾回收. 引用计数:是一种很有效的机制,通过给没个对象维护一个引用计数器,记录该对象当前呗引用的次数.当对象增加一次引用时,计数器加1:而对象失去一次引用时,计数器减1:当引用计数为0时,标志着该对象的生命周期结束,自动触发对象的回收释放.引用计数的重要规则是每个程序片段必须负责任地维护引用计数,在需要维持对象生存的程序段的开始和结束分别增加或减少一次引用计数,这样就能实现十分灵活的智能内存管理. 垃圾回收:它通过引用一种自动的内存回收器,试图将程

内存管理笔记(分页,分段,逻辑地址,物理地址)【转】

本文转载自:http://www.cnblogs.com/felixfang/p/3420462.html 1. 物理地址和逻辑地址 物理地址:加载到内存地址寄存器中的地址,内存单元的真正地址.在前端总线上传输的内存地址都是物理内存地址,编号从0开始一直到可用物理内存的最高端.这些数字被北桥(Nortbridge chip)映射到实际的内存条上.物理地址是明确的.最终用在总线上的编号,不必转换,不必分页,也没有特权级检查(no translation, no paging, no privile

黑马程序员_ Objective-c 内存管理笔记

引用计数器 当一个对象被创建出来,就要分配给内存这个对象,当不用这个对象的时候,就要及时的回收,为了可以明确知道对象有没有被使用,就要用引用计数器来体现,只要计数器不为0,表明对象被使用中. 1.方法的基本使用 1> retain :计数器+1,会返回对象本身 2> release :计数器-1,没有返回值 3> retainCount :获取当前的计数器 4> dealloc * 当一个对象要被回收的时候,就会调用 * 一定要调用[super dealloc],这句调用要放在最后

内存管理 浅析 内存管理/内存优化技巧

内存管理 浅析 下列行为都会增加一个app的内存占用: 1.创建一个OC对象: 2.定义一个变量: 3.调用一个函数或者方法. 如果app占用内存过大,系统可能会强制关闭app,造成闪退现象,影响用户体验.如何让回收那些不再使用的对象呢?本文着重介绍OC中的内存管理. 所谓内存管理,就是对内存进行管理,涉及的操作有: 1.分配内存:比如创建一个对象,会增加内存占用: 2.清除内存:比如销毁一个对象,会减少内存占用. 内存管理的管理范围: 1.任何继承了NSObject的对象: 2.对其他非对象类

内存管理之内存池概述(转)

原文链接:http://www.xiaoyaochong.net/wordpress/index.php/2013/08/10/%E5%BC%95%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E4%B9%8B%E5%86%85%E5%AD%98%E6%B1%A0%E6%A6%82%E8%BF%B0/ 在我们编写代码的过程中,不可避免的要和内存打交道,在申请释放不太频繁的情况下,通常让系统进行内存管理即可.但是,直接使用系统调用malloc/free.new/delet

浅谈C语言内存管理、内存泄露、堆栈

1.内存分配区间: 对于一个C语言程序而言,内存空间主要由五个部分组成:代码段(.text).数据段(.data).静态区(.BSS).堆和栈组成. BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量和静态变量 (这里注意一个问题:一般的书上都会说全局变量和静态变量是会自动初始化的,那么哪来的未初始化的变量呢?变量的初始化可以分为显示初始化和隐式初始化,全局变量和静态变量如果程序员自己不初始化的话的确也会被初始化,那就是不管什么类型都初始化为0,这种没有显示初始