• #内存泄露# #mtrace# mtrace


    1、安装mtrace工具
    centos : sudo yum install glibc-utils

    对创建的线程也有作用

    linux 提供mtrace/muntrace来检测程序是否有内存泄露。一般来说要检测哪一段代码是否有内存泄露,就可以用这一对函数包起来。mtrace每一对malloc-free的执行,若每一个malloc都有相应的free,则代表没有内存泄露,对于任何非malloc/free情況下所发生的内存泄露问题,mtrace并不能找出来。也就是对于new的内存,只能检测出有泄露,但不能定位。因此可能不适用于C++

    在使用mtrace之前,先要设置一个环境变量“MALLOC_TRACE”来指定mtrace检测结果的生成文件名。通过此文件就可以看出代码是否有内存泄露。MALLOC_TRACE可以用export MALLOC_TRACE=xxx来设置,也可以通过setenv设置。

    setenv("MALLOC_TRACE","mtrace_test_output",1);
    mtrace_test_output就是储存检测结果的文件的名称。但是检测结果的格式是一般人无法理解的,而只要有安装mtrace的话,就会有一名为mtrace的Perl script,在shell输入以下指令:mtrace [binary] [file] 就会将output_file_name的內容转化成能被理解的语句。

    mtrace mtrace_test mtrace_test_outpute
    mtrace/muntrace是一个C函數,在<mcheck.h>里声明及定义,函数原型为:

    void mtrace(void);
    void muntrace(void);
    mtrace 用于开启内存使用记录,
    muntrace用于取消内存使用记录。
    MALLOC_TRACE用于内存使用情况记录到一个文件决定。
    其实mtrace是类似malloc_hook的 malloc handler,只不过mtrace的handler function已由系统为你写好了而已。

    下面我们来对mtrace进行一系列测试工作。

    内存分配函数:malloc,calloc,realloc,_alloca, new, free, delete请参考:

    https://blog.csdn.net/xiaoting451292510/article/details/105094625

    #include <iostream>
    #include <mcheck.h>
    #include <stdlib.h>
    #include <stdio.h>
    using namespace std;
    class new_delete_test
    {
    public:
    new_delete_test() :
    m_member(0x00)
    {
    printf("contructor ");
    }
    ~new_delete_test() {
    printf("detructor ");
    }
    private:
    int m_member;
    };
    int main()
    {
    setenv("MALLOC_TRACE","mtrace_test_output",1);
    mtrace();
    printf("malloc & new ");
    void *p_malloc = malloc(100);
    void *p_malloc_no_free = malloc(100);
    void *p_calloc = calloc(10, 10);
    void *p_calloc_no_free = calloc(10, 10);
    void *p_realloc = malloc(100);
    p_realloc = realloc(p_realloc, 10);
    p_realloc = realloc(p_realloc, 50);
    p_realloc = realloc(p_realloc, 100);
    p_realloc = realloc(p_realloc, 200);
    void *p_realloc_no_free = malloc(1);
    p_realloc_no_free = realloc(p_realloc, 100);
    int *p_new = new int;
    int *p_new_no_delete = new int;
    int *p_new_array = new int[100];
    int *p_new_array_no_delete = new int[100];
    new_delete_test *p_new_class = new new_delete_test;
    new_delete_test *p_new_class_no_free = new new_delete_test;
    new_delete_test *p_new_class_array = new new_delete_test[3];
    new_delete_test *p_new_class_array_no_free = new new_delete_test[3];
    printf("*********************************************** ");

    printf("free & delete ");
    free(p_malloc);
    p_malloc = NULL;
    free(p_calloc);
    p_calloc = NULL;
    free(p_realloc_no_free);
    p_realloc_no_free = NULL;
    delete p_new;
    p_new = NULL;
    delete p_new_array;
    p_new_array = NULL;
    delete p_new_class;
    p_new_class = NULL;
    delete[] p_new_class_array;
    p_new_class_array = NULL;
    printf("*********************************************** ");
    muntrace();

    return 0;
    }

    编译生成mtrace_test

    g++ -Wall -g mtrace_test.cpp -o mtrace_test
    运行mtrace_test

    ./mtrace_test
    生成mtrace_test_output文件

    运行以下命令

    mtrace mtrace_test mtrace_test_output
    可以得到内存泄露信息

    Memory not freed:
    -----------------
    Address Size Caller
    0x000000000147d3b0 0x400 at 0x7f4ea91dc1d5
    0x000000000147d830 0x64 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:26
    0x000000000147d910 0x64 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:28
    0x000000000147d980 0x1 at /home/cll/99_temp/memory_leak/mtrace/mtrace_test.cpp:34
    0x000000000147dae0 0x4 at 0x7f4ea97f6c75
    0x000000000147dca0 0x190 at 0x7f4ea97f6c75
    0x000000000147de60 0x4 at 0x7f4ea97f6c75
    0x000000000147dea0 0x14 at 0x7f4ea97f6c75

    对于任何非malloc/free情況下所发生的内存泄露问题,mtrace并不能找出来。也就是对于new的内存,只能检测出有泄露,但不能定位。


    ————————————————
    版权声明:本文为CSDN博主「arvin_xiaoting」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/xiaoting451292510/article/details/105094202

    有时候,不小心知道了一些事,才发现自己所在乎的事是那么可笑。
  • 相关阅读:
    Git使用经验小结
    Git使用经验小结
    关于IT增值服务"拜师学艺"价格调整的通知
    关于IT增值服务"拜师学艺"价格调整的通知
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 397 整数替换
    Java实现 LeetCode 396 旋转函数
    Java实现 LeetCode 396 旋转函数
    Java实现 LeetCode 396 旋转函数
  • 原文地址:https://www.cnblogs.com/axjlxy/p/15292773.html
Copyright © 2020-2023  润新知