1. 程式人生 > >Android Native記憶體洩露檢測(針對Android7.0)

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程式碼,確認正是此處洩漏。