c/c++ 内存泄漏检测

简介: c/c++ 内存泄漏检测

线上系统发现虚拟内存在不断的涨,出现内存泄露如何解;

1、内存泄露为什么不好处理;

       1)虚拟内存在涨的时候,我们不确定是程序的需要还是内存泄漏;

       2)不知道到底是哪行代码导致内存泄漏;

内存泄漏产生的原因无非是malloc/new和free/delete调用不匹配;

2、如何判断内存泄漏,哪个地方的代码实现导致内存泄漏;内存泄漏检测;

       1)通过mtrace检测内存泄漏;运行代码后通过mem.txt日志查看内存泄漏情况;对于线上系统是需要重启的,如果不重启可以通过热更新,在.conf文件中加入mtrace;

运行上图程序得到mem.txt文件如下,通过+和-的匹配情况判断是否有内存泄漏;

然后通过addr2line命令就可以查看是在哪里出现了内存泄漏;

       2)宏定义检测内存泄漏;

宏定义检测的优缺点:只适合在单文件中使用;

对于线上系统,通过热更新检测;

       3)通过hook方式检测内存泄漏;

typedef void *(*malloc_t)(size_t size);
typedef void (*free_t)(void *ptr);
malloc_t malloc_f = NULL;
free_t free_f = NULL;
int enable_malloc_hook = 1;
int enable_free_hook = 1;
void *malloc(size_t size) {
    if(enable_malloc_hook)
   {
        enable_malloc_hook= 0;
        void *p = malloc_f(size);
        void * caller = __builten_return address(0);
        char buff[128];
       sprintf(buff, "./mem/%p.mem", p);
        FILE *fp = fopen(buff,"w");
        fprintf(fp,"[+]%s :%d, addr: %p,size: %ld\n"FILE_,_LINE__, p,size);
        fflush(fp);
        enable malloc_hook = 1;
    }
    else
    {
        p = malloc_f(size);
    }
    return p;
}
void free(void *ptr) {
    if(enable_free_hook)
    {
        enable_free_hook = 0;
        char buff[128] = (0};
        sprintf(buff,"./mem/%p.mem", p);
        free_f(ptr);
        enable free hook = 1;
    }
}
static void init_hook(void) {
    if (malloc_f == NULL) {
        malloc_f = (malloc_t)dlsym(RTLD_NEXT, "malloc");
    }
    if (free_f == NULL) {
        free_f = (free_t)dlsym(RTLD_NEXT, "free");
    }
}
int main() {
    init_hook();
    void *p1 = malloc(10); 
    void *p2 = malloc(15);
    void *p3 = malloc(20);
    free(p2);
    free(p3);
}

       4)__libc_malloc();接口,malloc底层调用的是该接口;思路和hook是一样的;

       5)老版本接口,是被攻击的很重要的点,即__malloc_hook,是一种指针的方式;系统提供了一个指针,每一次调用malloc函数的时候,底层会调用到__malloc_hook指针,这个指针是固定的值;这是linux本身提供的hook的机制;这种方式慎用,因为它已经是已被遗弃的老的接口;

目录
相关文章
|
19天前
|
存储 Java C++
C++ 引用和指针:内存地址、创建方法及应用解析
C++中的引用是现有变量的别名,创建时需用`&`运算符,如`string &meal = food;`。指针存储变量的内存地址,使用`*`创建,如`string* ptr = &food;`。引用必须初始化且不可为空,而指针可初始化为空。引用在函数参数传递和提高效率时有用,指针适用于动态内存分配和复杂数据结构操作。选择使用取决于具体需求。
38 9
|
1天前
|
Dart 前端开发 Java
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
【4月更文挑战第30天】本文探讨了Flutter应用中的内存泄漏检测与解决方法。内存泄漏影响性能和用户体验,常见原因包括全局变量、不恰当的闭包使用等。开发者可借助`observatory`工具或`dart_inspector`插件监测内存使用。解决内存泄漏的策略包括避免长期持有的全局变量、正确管理闭包、及时清理资源、妥善处理Stream和RxDart订阅、正确 disposal 动画和控制器,以及管理原生插件资源。通过这些方法,开发者能有效防止内存泄漏,优化应用性能。
【Flutter前端技术开发专栏】Flutter中的内存泄漏检测与解决
|
1天前
|
开发工具 Swift iOS开发
【Swift开发专栏】Swift中的内存泄漏检测与修复
【4月更文挑战第30天】本文探讨了Swift中的内存泄漏问题,尽管有ARC机制,但仍需关注内存管理。文章分为三部分:内存管理基础知识、检测方法和修复技巧。了解ARC原理和循环引用陷阱是防止内存泄漏的关键。检测方法包括使用Xcode内存调试器、LeakSanitizer和性能分析工具。修复技巧涉及打破循环引用、使用弱/无主引用及手动管理内存。理解这些对优化应用性能和稳定性至关重要。
|
7天前
|
存储 缓存 算法
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
|
7天前
|
存储 程序员 编译器
C++从入门到精通:3.4深入理解内存管理机制
C++从入门到精通:3.4深入理解内存管理机制
|
7天前
|
存储 人工智能 程序员
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
37 1
|
7天前
|
C语言 C++
【C++基础(九)】C++内存管理--new一个对象出来
【C++基础(九)】C++内存管理--new一个对象出来
|
9天前
|
存储 编译器 Linux
c++的学习之路:8、内存管理与模板
c++的学习之路:8、内存管理与模板
9 0
|
14天前
|
存储 Linux C语言
C/C++之内存旋律:星辰大海的指挥家
C/C++之内存旋律:星辰大海的指挥家
23 0
|
18天前
|
编译器 C++
C++ 解引用与函数基础:内存地址、调用方法及声明
C++ 中的解引用允许通过指针访问变量值。使用 `*` 运算符可解引用指针并修改原始变量。注意确保指针有效且不为空,以防止程序崩溃。函数是封装代码的单元,用于执行特定任务。理解函数的声明、定义、参数和返回值是关键。函数重载允许同一名称但不同参数列表的函数存在。关注公众号 `Let us Coding` 获取更多内容。
136 1