C语言内存泄露检测--Memwatch

简介:

项目:迅雷下载库内存泄露检测

作者:曾金龙

供职:深圳迅雷网络技术股份有限公司

领域:迅雷下载库

时间:2014-07-26


迅雷的移动下载库是用C语言编写的,为了能够横跨欧亚非拉偷笑(ios,android,还有诺基亚的什么系统来着,对了symban)和性能,我们厂的下载库就选择了C,然后在C代码里面使用各种宏,预编译等来达到一 个下载库,多平台使用。不过平台相关的都已经约束在了一个叫common的库里面的一个子模块里面了。这极大的解放了我厂的码农朋友。

但是C毕竟是C,在聊起C的时候,我们组最喜欢说的是,我们权限最大,想干啥干啥。最悲痛的是,测试妹子过来了,然后说各种问题,但是logcat都捕获不到,或者有时候崩溃了但是没有tombstone,等。其实,C最大的危险就是内存泄露。。。因为C的内存泄露,我和测试妹子的感情最近变得更加的亲密而又微妙。。。


老大发话了,必须解决所有C内存泄露。。。

在我下写我负责的数据存储模块的时候,我就动了一个小技巧,就能够把本模块的内存泄露全部给检测出来,而我这朴素的思想其实也是其他内存泄露检测工具的灵魂,只是,老大嫌我的太朴素了。

我的做法很简单,每次malloc内存的时候不是调用系统的malloc,而是调用我的malloc,取名为fc_malloc(因为我的模块叫file_cache),free则调用fc_free。具体代码如下:

#define fc_malloc(size) fc_malloc_imp(size,__FILE__,__LINE__)

#define fc_free(ptr) fc_free_imp(ptr)

typedef struct mem_log{
void* addr;
char* file;
int   line;
}memlog;
#ifdef _LOGGER
static list g_mem_list
#endif // _LOGGER
void init_module()
{
    #ifdef _LOGGER
    list_init(&g_mem_list);
    #endif
}

void uninit_module()
{
    #ifdef _LOGGER
    list_for_each(g_mem_list,v)
    {
        memlog* iterm=(memlog*)LIST_VALUE(v);
        printf("%s,%d,%x\n",iterm->file,iterm->line,iterm->addr);//output the memory not free..
        free(iterm);
    }
    list_clear(&g_mem_list);

    #endif // _LOGGER

}

void* fc_malloc_imp(size_t size,char* file,int line)
{
    void* ptr=malloc(size);

    #ifdef _LOGGER

    if(ptr!=NULL)
    {
        memlog* iterm = (memlog*)malloc(sizeof(memlog));
        iterm->addr=ptr;
        iterm->file=file;
        iterm->line=line;
        list_insert(&g_mem_list,iterm);
    }
    #endif // _LOGGER
    return ptr;
}
void fc_free_imp(void* ptr)
{
    #ifdef _LOGGER
    if(ptr!=NULL)
    {
        list_erase_by_addr(&g_mem_list,ptr);//in this funciton we need free the memlog iterm memory.
    }

    #endif // _LOGGER
    free(ptr);
}

却是很简单,说白了就是用一个链表去等级下每次malloc的地址信息,当然为了好定位,包含文件和行信息,然后在模块卸载的时候,就可以打印出哪些内存还没有被释放。这样对于检查内存泄露,已经达到目的了,很简单吧。有用的东西都是很简单,但很巧妙。

在老大说我应该去看下现有的内存检测工具之前,我觉得我 的这个“创作”已经帮了我解决了所有的内存泄露问题,至少,我和测试妹子的关系从聊bug转移到聊哪件衣服好看了,恩,不错。



相关实践学习
【玩转ComfyUI】基于函数计算一键部署AI生图平台ComfyUI
本次实验将带大家通过使用阿里云产品函数计算FC,快速使用ComfyUI实现更高质量的图像生成。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
安全 C语言
C语言中的字符、字符串及内存操作函数详细讲解
通过这些函数的正确使用,可以有效管理字符串和内存操作,它们是C语言编程中不可或缺的工具。
606 15
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
1177 159
|
存储 编译器 程序员
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
在C语言中,内存布局是程序运行时非常重要的概念。内存布局直接影响程序的性能、稳定性和安全性。理解C程序的内存布局,有助于编写更高效和可靠的代码。本文将详细介绍C程序的内存布局,包括代码段、数据段、堆、栈等部分,并提供相关的示例和应用。
1019 5
【C语言】内存布局大揭秘 ! -《堆、栈和你从未听说过的内存角落》
|
监控 Java 计算机视觉
Python图像处理中的内存泄漏问题:原因、检测与解决方案
在Python图像处理中,内存泄漏是常见问题,尤其在处理大图像时。本文探讨了内存泄漏的原因(如大图像数据、循环引用、外部库使用等),并介绍了检测工具(如memory_profiler、objgraph、tracemalloc)和解决方法(如显式释放资源、避免循环引用、选择良好内存管理的库)。通过具体代码示例,帮助开发者有效应对内存泄漏挑战。
915 1
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
2256 13
|
存储 编译器 数据处理
C 语言结构体与位域:高效数据组织与内存优化
C语言中的结构体与位域是实现高效数据组织和内存优化的重要工具。结构体允许将不同类型的数据组合成一个整体,而位域则进一步允许对结构体成员的位进行精细控制,以节省内存空间。两者结合使用,可在嵌入式系统等资源受限环境中发挥巨大作用。
768 12
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
738 11
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
736 6
|
大数据 C语言
C 语言动态内存分配 —— 灵活掌控内存资源
C语言动态内存分配使程序在运行时灵活管理内存资源,通过malloc、calloc、realloc和free等函数实现内存的申请与释放,提高内存使用效率,适应不同应用场景需求。
|
传感器 人工智能 物联网
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发
C 语言在计算机科学中尤其在硬件交互方面占据重要地位。本文探讨了 C 语言与硬件交互的主要方法,包括直接访问硬件寄存器、中断处理、I/O 端口操作、内存映射 I/O 和设备驱动程序开发,以及面临的挑战和未来趋势,旨在帮助读者深入了解并掌握这些关键技术。
593 6