zoukankan      html  css  js  c++  java
  • 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.  
    7. void kmemleak_memalloc(void)
    8. {
    9.     char *pmem;
    10.    
    11.     pmem = kmalloc(300, GFP_KERNEL);
    12.     if (!pmem)
    13.     {
    14.         printk("[Kmemleak]: kmalloc fail! ");
    15.     }
    16.     else
    17.     {
    18.         printk("[Kmemleak]: kmalloc return %p ", pmem);
    19.     } 
    20. }
    21.  
    22. int __init kmemleak_test_init(void)
    23. {
    24.    
    25.     printk("[Kmemleak]: kmemleak_test_init! ");
    26.  
    27.     kmemleak_memalloc();
    28.  
    29.     return 0;
    30. }
    31.  
    32. void __exit kmemleak_test_exit(void)
    33. {
    34.     printk("[Kmemleak]: kmemleak_test_exit now ");
    35. }
    36.  
    37.  
    38. module_init(kmemleak_test_init)
    39. module_exit(kmemleak_test_exit)
    40.  
    41. MODULE_LICENSE("GPL");

        Makefile脚本稍作修改后:

    1. obj-m = kmemleak_test.o
    2.  
    3. all:
    4.     make -C /lib/modules/`uname -r`/build M=`pwd`
    5.  
    6. clean:
    7.     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挺好用的,适用于内核模块开发用于检测定位内存泄漏问题。

     

  • 相关阅读:
    momentjs时间格式插件
    TagCanvas 插件
    Vue2.0 探索之路——生命周期和钩子函数的一些理解
    vue.js学习:1.0到2.0的变化(区别)
    dom操作节点之常用方法
    javascript 中 x offsetX clientX screenX pageX的区别
    Vuex详解笔记2
    Vuex详解笔记1
    Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#<Object>‘的解决方法
    CSS技巧和经验列表
  • 原文地址:https://www.cnblogs.com/zzb-Dream-90Time/p/9016132.html
Copyright © 2011-2022 走看看