1. 需要合入一个
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代码,确认正是此处泄漏。