Linux下关于mtrace工具排查内存泄露的问题

 更新时间:2023年09月04日 09:09:52   作者:凌肖战  
这篇文章主要介绍了Linux下关于mtrace工具排查内存泄露的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

mtrace工具排查内存泄露

内存泄露为申请了堆内存,但没有释放,即未还给操作系统。长此以往,系统的可分配内存越来越少,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

 Linux下进行 C/C++ 开发,常常会动态分配一些堆内存。那就可能会存在"内存泄露"的问题。

如果 Linux下做 C/C++ 开发时,出现内存泄漏了,我们该如何去定位呢?

常用的定位工具:

mtrace 工具 与 valgrind工具 ,这两个都是典型的内存泄漏分析工具。

1. mtrace 工具使用思路

在我们的调用内存分配和释放的函数中装载 “钩子(hook)” 函数,通过 “钩子” 函数打印的 log 日志,对日志文件的分析来帮助我们分析对内存的使用是否存在问题。

对该工具的使用包括两部分内容:一个是要修改源码,装载 hook 函数。

另一个是通过运行修改后的程序,生成特殊的 log 文件。

然后利用  mtrace工具分析日志,判断是否存在内存泄露以及定位可能发生内存泄露的代码位置。

2. mtrace 工具使用说明

接下来用一段代码说明一下, mtrace 工具如何定位 "内存泄露" 。

在使用之前,需要修改我们的源码,用来跟踪内存分配和释放,其中需要使用两个函数:

#include <mcheck.h>
void mtrace(void);   //开启内存分配跟踪  
void muntrace(void); //关闭内存分配跟踪

将上述函数接口加入待检测的代码中,代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <mcheck.h>
int main(int argc, char **argv)
{
    setenv("MALLOC_TRACE", "memery_leak.log", 1);
    mtrace();
    char *p1 = (char*)malloc(16);
    char* p2 = (char*)malloc(20);
    free(p1);
    p1 = NULL;
    muntrace();
    return 0;
}

编译代码,终端输入命令:gcc -g main.c -o main.out

运行程序,终端输入:./main.out 命令。当前目录下就会生成 memory_leak.log 文件。

定位问题,终端输入:mtrace main.out memory_leak.log 命令后,并没有定位到 C 源码的具体行数,如下所示:

下面使用 地址转化工具 addr2line 工具分析一下,上面地址是对应到哪一行 C 代码行。

如下所示:

可以看出,能够猜到可能是后面的地址不对。导致 addr2line 工具转换失败。

网上百度到,可能的原因如下:

1. 关闭 Linux 系统的 ASLR 功能。

ASLR 功能全称为 Address Space Layout Randomization,地址空间布局随机化。

它将进程的某些内存空间地址进行随机化来增大入侵者预测目的地址的难度,从而降低进程被成功入侵的风险。

2. 编译源码时,加上 "-no-pie" 选项。

下来进行具体的操作,操作如下:

(1)关闭 ASLR 功能:

输入命令:cat /proc/sys/kernel/randomize_va_space ,查看 Linux 系统的 ASLR 值是 2,说明默认 ASLR 功能是开启的。

设置 ASLR 的值:输入命令 : echo 0 > /proc/sys/kernel/randomize_va_space

(2)加入 "-no-pie" 选项后重新编译程序。输入命令: gcc -g -no-pie main.c -o main.out

(3)然后运行程序,终端输入命令: ./main.out

(4)使用 mtrace 工具查看 新生成的 memory_leak.log 文件。

如下所示:

可以看到,定位到了 C 代码中的具体行。

到此,mtrace 工具定位到 C 代码的具体的 11 行代码存在内存泄露 。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Apache启动提示错误undefined symbol: libiconv_open解决方法

    Apache启动提示错误undefined symbol: libiconv_open解决方法

    这篇文章主要介绍了Apache启动提示错误undefined symbol: libiconv_open解决方法,需要的朋友可以参考下
    2015-06-06
  • Linux下SFTP用户权限设置条件及实现命令

    Linux下SFTP用户权限设置条件及实现命令

    SFTP账号是基于SSH账号的,其拥有的权限是比较大的,今天主要教大家如何进行SFTP用户权限设置,感兴趣的你可不要错过了哈,希望本文知识可以帮助到你
    2013-02-02
  • centos更改时区的方法

    centos更改时区的方法

    centos默认使用UTC时区,中国用户需要修改成自己的时区,这篇文章主要介绍了centos更改时区的方法,需要的朋友可以参考下
    2014-03-03
  • Linux简介及最常用命令(简单易学,但能解决95%以上的问题)

    Linux简介及最常用命令(简单易学,但能解决95%以上的问题)

    这篇文章主要介绍了Linux简介及最常用命令(简单易学,但能解决95%以上的问题),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-08-08
  • Linux的路由表详细介绍

    Linux的路由表详细介绍

    这篇文章主要介绍了Linux的路由表详细介绍的相关资料,希望通过本文大家能彻底了解Linux 路由表的知识,需要的朋友可以参考下
    2017-08-08
  • linux中快速列出文件列表的多种方法总结

    linux中快速列出文件列表的多种方法总结

    这篇文章主要给大家总结介绍了关于linux中如何快速列出文件列表的多种方法,分别介绍了walk、os.scandir、tree、find以及locate等方法,文中给出了详细的示例代码,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-10-10
  • 详解Centos6.5下docker 环境搭建

    详解Centos6.5下docker 环境搭建

    本篇文章主要介绍了详解Centos6.5下docker 环境搭建,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • LNMP部署及HTTPS服务开启教程

    LNMP部署及HTTPS服务开启教程

    本文主要给大家介绍的是LNMP环境的部署以及开启https服务的方法和示例,有需要的小伙伴可以参考下
    2018-11-11
  • 在Linux系统上刷新DNS缓存的方法

    在Linux系统上刷新DNS缓存的方法

    DNS是互联网的一项服务,它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网,而不用记住能够被机器直接读取的 IP 数串,但是,有时候我们可能需要刷新或清除 DNS 缓存,本文将详细介绍如何在Linux系统上刷新DNS缓存,需要的朋友可以参考下
    2024-06-06
  • Ubuntu20.04防火墙设置简易教程(小白)

    Ubuntu20.04防火墙设置简易教程(小白)

    这篇文章主要介绍了Ubuntu20.04防火墙设置简易教程(小白),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07

最新评论