Android Native内存泄露检测(针对Android7.0)

1. 需要合入一个

Patch

2. 执行指令

adb root
adb shell setprop libc.debug.malloc.program cameraserver
adb shell setprop libc.debug.malloc.options “backtrace_enable_on_signal leak_track”
adb shell ps | find /I “cameraserver”
adb shell kill -9 pid_of_cameraserver // restart cameraserver
adb shell ps | find /I “cameraserver”
adb shell kill -45 pid_of_cameraserver // begin capture
run use case
adb shell ps | find /I “cameraserver” // need be same as last one, otherwise cameraserver die
during test
adb shell kill -28 pid_of_cameraserver // sigwinch will dump the callstack has memory leak

3. kill -28的指令是可以重复执行的。
4. 先看一个测试DEMO
#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<termios.h>

#include<string.h>

char *mm = NULL; 

int main(void)
{
	int cnt = 0;
	do
	{
		mm = (char *)malloc(4096);
		memset(mm,0x0,4096);
		usleep(1*1000*1000);
		
		printf("leak count = %d\n",cnt++);
	}while(1);
	
	return 0;
}

上文中的malloc会最终调用到 bionic/libc/malloc_debug/malloc_debug.cpp中的debug_malloc函数。demo中每次泄漏4K的内存,我们随后通过libc提供的feature定位到它。

4. 检测步骤
a) setprop libc.debug.malloc.program leak

设置需要跟踪的进程名称

b) setprop libc.debug.malloc.options "backtrace_enable_on_signal leak_track"  

设置跟踪进程的内存泄漏项检测

c) kill -9 杀掉该进程,同时重新启动这个进程,以使得该进程之后的内存分配,带有debug选项

d) kill -45 进程ID,发送信号到目标进程,启动内存泄漏检测

e) kill -28 进程ID,发送信号到目标进程,打印可疑的内存泄漏项

内存泄漏Log如下:

11-06 02:44:01.317  3565  3565 E malloc_debug: leak: Run: 'kill -45 3565' to enable backtracing.
11-06 02:44:01.318  3565  3565 E malloc_debug: leak: Run: 'kill -28 <pid of process>' to print memory leak information.
11-06 02:44:25.699  3565  3565 E malloc_debug: leak:3565 backtrace enabled.
11-06 02:44:33.851  3565  3582 E malloc_debug: PrintLeaks::leak:3565 backtrace printing. Thread = PrintLeaks Thread
11-06 02:44:33.852  3565  3582 E malloc_debug: +++ leak leaked memory dumping started +++
11-06 02:44:33.852  3565  3582 E malloc_debug: +++ total size: 40 K, total records: 1, top records: 1 +++
11-06 02:44:33.852  3565  3582 E malloc_debug: +++ Backtrace at time of allocation: total size 40960 (leak times: 10, avg size: 4096) +++
//这个时间点总共泄漏了40K,每次泄漏4K,持续了10次泄漏
11-06 02:44:33.852  3565  3582 E malloc_debug:           #00  pc 0000000000000764  /system/bin/leak
11-06 02:44:33.852  3565  3582 E malloc_debug:           #01  pc 000000000001a7d8  /system/lib64/libc.so (__libc_init+88)
11-06 02:44:33.852  3565  3582 E malloc_debug:           #02  pc 0000000000000690  /system/bin/leak
11-06 02:44:33.853  3565  3582 E malloc_debug: +++ leak leaked memory dumping ended +++
11-06 02:44:42.341  3565  3587 E malloc_debug: PrintLeaks::leak:3565 backtrace printing. Thread = PrintLeaks Thread
11-06 02:44:42.342  3565  3587 E malloc_debug: +++ leak leaked memory dumping started +++
11-06 02:44:42.342  3565  3587 E malloc_debug: +++ total size: 76 K, total records: 1, top records: 1 +++
11-06 02:44:42.342  3565  3587 E malloc_debug: +++ Backtrace at time of allocation: total size 77824 (leak times: 19, avg size: 4096) +++
11-06 02:44:42.343  3565  3587 E malloc_debug:           #00  pc 0000000000000764  /system/bin/leak
11-06 02:44:42.343  3565  3587 E malloc_debug:           #01  pc 000000000001a7d8  /system/lib64/libc.so (__libc_init+88)
11-06 02:44:42.343  3565  3587 E malloc_debug:           #02  pc 0000000000000690  /system/bin/leak
11-06 02:44:42.343  3565  3587 E malloc_debug: +++ leak leaked memory dumping ended +++
11-06 02:45:04.320  3565  3601 E malloc_debug: PrintLeaks::leak:3565 backtrace printing. Thread = PrintLeaks Thread
11-06 02:45:04.321  3565  3601 E malloc_debug: +++ leak leaked memory dumping started +++
11-06 02:45:04.321  3565  3601 E malloc_debug: +++ total size: 164 K, total records: 1, top records: 1 +++
11-06 02:45:04.321  3565  3601 E malloc_debug: +++ Backtrace at time of allocation: total size 167936 (leak times: 41, avg size: 4096) +++
5. 定位内存泄漏的位置
  #gdb leak
  (gdb) b *0x0000000000000764
  Breakpoint 1 at 0x764: file hardware/rockchip/memleak/leak.cpp, line 27.

需要特别留意的是这里的可执行文件leak必须包含符号表(symbol目录下),经过定位后,泄漏点在leak.cpp的第27行,结合之前的DEMO代码,确认正是此处泄漏。

猜你喜欢

转载自blog.csdn.net/zhuyong006/article/details/83783001