zoukankan      html  css  js  c++  java
  • malloc钩子和内存泄漏工具mtrace、Valgrind

    一:malloc钩子函数

    static void* (* old_malloc_hook) (size_t,const void *);
    static void (* old_free_hook)(void *,const void *);
    static void my_init_hook(void);
    static void* my_malloc_hook(size_t,const void*);
    static void my_free_hook(void*,const void *);

    static void my_init_hook(void)
    {
        old_malloc_hook = __malloc_hook;
        old_free_hook = __free_hook;
        __malloc_hook = my_malloc_hook;
        __free_hook = my_free_hook;
    }


    static void* my_malloc_hook(size_t size,const void *caller)
    {
        void *result;
        // print_trace();
        __malloc_hook = old_malloc_hook;
         result = malloc(size);
        old_malloc_hook = __malloc_hook;
        PHONE_DEBUG_PRINT("/n@@@ %p + %p 0x%x/n",caller,result,(unsigned long int)size);
        __malloc_hook = my_malloc_hook;

        return result;
    }

    static void my_free_hook(void *ptr,const void *caller)
    {
        __free_hook = old_free_hook;
        free(ptr);
        old_free_hook = __free_hook;
        PHONE_DEBUG_PRINT("/n@@@ %p - %p/n",caller,ptr);
        __free_hook = my_free_hook;
    }

    just need call my_init_hook() at the check point.

    二:check memory leak

    想要跟踪的时候用mtrace。

    停止跟踪可以使用muntrace.

    内存泄漏检查方法(for Linux) :

    如果你更想读原始文档, 请参考glibc info的"Allocation Debugging"
    一章 (执行info libc);
    glibc提供了一个检查内存泄漏的方法, 前提是你的程序使用glibc的标准函数
    分配内存(如malloc, alloc...):

    1. 在需要内存泄漏检查的代码的开始调用void mtrace(void) (在mcheck.h中
    ? 有声明). mtrace为malloc等函数安装hook, 用于记录内存分配信息.
    在需要内存泄漏检查的代码的结束调用void muntrace(void).
    注意: 一般情况下不要调用muntrace, 而让程序自然结束. 因为可能有些
    释放内存代码要到muntrace之后才运行.

    2. 用debug模式编译被检查代码(-g或-ggdb)

    3. 设置环境变量MALLOC_TRACE为一文件名, 这一文件将存有内存分配信息.

    4. 运行被检查程序, 直至结束或muntrace被调用.

    5. 用mtrace命令解析内存分配Log文件($MALLOC_TRACE)
    (mtrace foo $MALLOC_TRACE, where foo is the executible name)
    如果有内存泄漏, mtrace会输出分配泄漏
    内存的代码位置,以及分配数量.


    其他东西

    1. 可以将mtrace, muntrace放入信号处理函数(USR1, USR2), 以动态地进行
    内存泄漏检查控制.

    2. mtrace是个perl代码, 如果你对符号地址与代码文本的转换感兴趣, 可以
    读一下.

    3. again, 尽量不要用muntrace()


    1 #include <mcheck.h>
    2
    3 int main()
    4 {
    5 mtrace();
    6 malloc(10);
    7 malloc(16);
    8 return 0;
    9 }

    $gcc -g a.c #记得编译带-g调试选项
    $export MALLOC_TRACE=a.log
    $./a.out
    $unset MALLOC_TRACE #记得执行完后unset变量,否则可能运行其他命令可能覆盖log
    $mtrace a.out a.log
    Memory not freed:
    -----------------
    Address Size Caller
    0x09b08378 0xa at /XXX/a.c:6
    0x09b08388 0x10 at /XXX/a.c:7

    可以看到,会显示未释放动态空间的代码具体位置.

    内存泄漏检测工具Valgrind 的工作原理:

      对C/C++程序,采用-g 编译选项进行编译得到二进制程序myprog--如果目标是检查程序漏洞,则常使用的tool为:memcheck (内存错误), helgrind, drd(线程错误)

      Valgrind 的工作原理--Valgrind 基于仿真方式对程序进行调试,它先于应用程序获取实际处理器的控制权,并在实际处理器的基础上仿真一个虚拟处理器,并使应用程序运行于这个虚拟处理器之上,从而对应用程序的运行进行监视。应用程序并不知道该处理器是虚拟的还是实际的,已经编译成二进制代码的应用程序并不用重新进行编译,Valgrind 直接解释二进制代码使得应用程序基于它运行,从而能够滴水不漏地检查内存操作时可能出现的错误。在嵌入式应用程序开发中,c 或c++是最为常用的语言,由于这两种语言非常灵活的特性,使得在编程时很容易出现上述错误。因此,为了提高嵌入式系统的可靠性,可以将Valgrind 引入到嵌入式程序的开发过程中,利用它对应用程序进行调试,从而达到高效、准确去除错误的目的。

  • 相关阅读:
    Java并发编程笔记——技术点汇总
    Hello Blog
    shell变量
    认识bash这个shell
    使用myeclipse创建带注解的model实体类
    python List,切片的用法
    ignite从0到1的学习过程记录-第一篇:安装和体验
    安卓Service完全解析(中)
    安卓Service完全解析(上)
    JAVA之数组
  • 原文地址:https://www.cnblogs.com/dongzhiquan/p/5839844.html
Copyright © 2011-2022 走看看