内存泄漏检测方式

一 、 日志记录

        通过宏定义重载了 mallocfree 函数,以在分配和释放内存的时候记录一些信息,包括文件名和行号,并将这些信息写入到相应的文件中。然后在 main 函数中演示了使用这些宏进行内存分配和释放。

  1. _malloc 函数:

    • 在分配内存之后,创建一个文件名,其中包含了分配的内存地址(以16进制表示)。
    • 打开这个文件并写入一些信息,包括源文件名、行号、分配的内存地址和大小。
    • 关闭文件并返回分配的内存地址。
  2. _free 函数:

    • 根据释放的内存地址创建相应的文件名。
    • 尝试删除这个文件,如果删除成功则表示释放成功,否则可能是发生了双重释放(double free)。
    • 调用标准库的 free 函数释放内存。
  3. malloc 宏和 free 宏:

    • 利用宏定义将 mallocfree 分别重命名为 _malloc_free,并且在这两个宏中传递 __FILE____LINE__,使得每次分配和释放内存都可以记录相应的文件名和行号。
#define _GNU_SOURCE
#include <dlfcn.h>


#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>



#if 0


void *_malloc(size_t size, const char *file, int line) {
	
	void *p = malloc(size);

	char buff[128] = {0};
	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);
	fclose(fp);
	

	return p;
}


void _free(void *p, const char *file, int line) {
	
	char buff[128] = {0};
	sprintf(buff, "./mem/%p.mem", p);

	if (unlink(buff) < 0) { // double free
		printf("double free: %p\n", p);
		return ;
	}
	free(p);

}


#define malloc(size) _malloc(size, __FILE__, __LINE__)
#define free(p)		 _free(p, __FILE__, __LINE__)



#endif

int main() {

//	DEBUG_MEM_LEAK

	void *p1 = malloc(10);
	void *p2 = malloc(20);

	free(p1);

}

二、  日志记录2

        这段代码使用了动态链接库劫持的方法,通过重载 mallocfree 函数,实现了在内存分配和释放时记录信息的功能。以下是代码的解释:

typedef void *(*malloc_t)(size_t size);
malloc_t malloc_f = NULL;


typedef void (*free_t)(void *p);
free_t free_f = NULL;

int enable_malloc_hook = 1;
int enable_free_hook = 1;


// main --> f --> func --> malloc();

void *malloc(size_t size) {

	if (enable_malloc_hook) {
		enable_malloc_hook = 0;
		//

		void *p = malloc_f(size);
		
		void *caller = __builtin_return_address(0);

		char buff[128] = {0};
		sprintf(buff, "./mem/%p.mem", p);

		FILE *fp = fopen(buff, "w");
		fprintf(fp, "[+%p] --> addr:%p, size:%ld\n", caller, p, size);

		fflush(fp);

		enable_malloc_hook = 1;

		return p;
	}  else {

		return malloc_f(size);
	}
	
}

void free(void *p) {

	if (enable_free_hook) {

		char buff[128] = {0};
		sprintf(buff, "./mem/%p.mem", p);

		if (unlink(buff) < 0) { // double free
			printf("double free: %p\n", p);
			return ;
		}
		free_f(p);

	} else {
		free_f(p);
	}
	
}


//hook

//dlsym


void init_hook(void) {

	if (malloc_f == NULL)
		malloc_f = dlsym(RTLD_NEXT, "malloc");

	if (free_f == NULL)
		free_f = dlsym(RTLD_NEXT, "free");

}

#define DEBUG_MEM_LEAK		init_hook();


int main() {

    DEBUG_MEM_LEAK

	void *p1 = malloc(10);
	void *p2 = malloc(20);

	free(p1);

}

三、bpftrace

        创建mem.bt文件

        uprobe挂在的事件和点,然后过滤当前进程等于memleak

        这个脚本的目的是监测在进程名为 "memleak" 的情况下,libc 库中的 mallocfree 函数的调用,并在每次调用时输出相应的信息。请确保你的系统支持 BPF 功能,并且相关的 uprobes 事件能够被监测。此外,记得在 bpftrace 执行时使用 sudo 权限,因为 uprobes 需要 root 权限。        

uprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc
/comm == "memleak"/
{
   printf("malloc\n"); 
}


uprobe:/lib/x86_64-linux-gnu/libc.so.6:free
/comm == "memleak"/
{
   printf("free\n"); 
}

相关推荐

  1. Android Native内存泄漏检测方案详解

    2024-01-16 16:16:02       13 阅读
  2. Python中的内存泄漏及其检测方法

    2024-01-16 16:16:02       42 阅读
  3. 4、内存泄漏检测(多线程)

    2024-01-16 16:16:02       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-16 16:16:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-16 16:16:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-16 16:16:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-16 16:16:02       18 阅读

热门阅读

  1. redis获取过期时间

    2024-01-16 16:16:02       37 阅读
  2. ChatGPT4.0 >ChatGPT 3.5 > 文心一言

    2024-01-16 16:16:02       34 阅读
  3. Qemu 之安装(源码安装)

    2024-01-16 16:16:02       36 阅读
  4. 2024年1月15日

    2024-01-16 16:16:02       24 阅读
  5. Vue3使用tinymce的配置和坑

    2024-01-16 16:16:02       30 阅读
  6. Shell编程自动化之if、for、while和函数

    2024-01-16 16:16:02       32 阅读