移植Valgrind檢測Android JNI內存泄漏


1、相關工具

Valgrind:從Valgrind官網下載最新的源碼包,我這里用的是:valgrind 3.14.0 (tar.bz2) [17MB] - 9 October 2018.

Ubuntu:V18.04.1_X64(Linux ubuntu 4.15.0-45-generic x86_64)

NDK:android-ndk-r12b-linux-x64

Android手機:ROOT

2、編譯步驟

(1)解壓源碼

#tar -jxvf valgrind-3.14.0.tar.bz2

(2)進入解壓文件夾中,查看README.android 了解編譯步驟,里面用的Android版本都很舊,不過沒關系,新版NDK也能編譯。這里簡化一下,在工程目錄寫一個腳本批量執行一下,含義對照README就懂了:

#!/bin/sh

export NDKROOT=/home/kuliuheng/_8GB_EXT/android-ndk-r12b-linux-x64
export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar
export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ld
export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc

./autogen.sh

CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-arm" \
    CFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-arm" \
    ./configure --prefix=/data/local/Inst \
    --host=armv7-unknown-linux --target=armv7-unknown-linux \
    --with-tmpdir=/sdcard

  (3)執行編譯

make -j4
make -j4 install DESTDIR=`pwd`/Inst

 (4)上一步編譯出來的內容都會放到本地的一個名為Inst的目錄中,里面是configure配置的三層路徑/data/local/Inst,這樣直接通過 adb push Inst / 命令就可以推送到Android機器上去了(當然必須要ROOT,否則肯定寫不進去)。

3、安裝Valgrind到Android手機

#adb shell
#cd /data/local/Inst
/data/local/Inst # chmod -R 777 bin
/data/local/Inst # chmod -R 777 lib
export VALGRIND_LIB="/data/local/Inst/lib/valgrind"

  請注意后面兩句很重要,如果這么寫的話在我的手機上會遇到一個問題是(而且我的手機無法使用 chmod +x,只能用chmod 777):

valgrind: failed to start tool 'memcheck' for platform 'arm-linux': Permission denied

4、啟動Valgrind測試 

  首先請參考下這個文章《Can't run a Java Android program with Valgrind》,這里我抽取出關鍵步驟來看下:

(1)創建一個啟動工具的腳本(包裝命令內容,我的APP名稱是com.klh.testandroid):

#!/system/bin/sh

PACKAGE="com.klh.testandroid"

# Callgrind tool
#VGPARAMS='-v --error-limit=no --trace-children=yes --log-file=/sdcard/valgrind.log.%p --tool=callgrind --callgrind-out-file=/sdcard/callgrind.out.%p'

# Memcheck tool
VGPARAMS='-v --error-limit=no --trace-children=yes --log-file=/sdcard/valgrind.log.%p --tool=memcheck --leak-check=full --show-reachable=yes'

export TMPDIR=/data/data/$PACKAGE

exec /data/local/Inst/bin/valgrind $VGPARAMS $* 

 (2)將腳本上傳到Android手機,並設置權限

> adb push start_valgrind.sh /data/local/Inst/
> adb shell chmod 777 /data/local/Inst/start_valgrind.sh

 (3)設置一個包裝環境屬性,用於啟動程序時自動關聯Valgrind及日志系統:

adb root
adb shell setprop wrap.com.klh.testandroid "logwrapper /data/local/Inst/start_valgrind.sh"

   請注意這里有兩個坑:1、setprop的Key長度不能大於31,Value長度不能大於91,參考文章《How can I overcome the property length limitation of the “adb shell setprop”》;2、我的手機上用adb shell setprop的方式無法設置,會提示錯誤“usage: setprop <key> <value>”,需要adb shell登錄之后單獨執行setprop。

(4)啟動程序(下面分別是命令行退出和啟動App的方式)

adb shell am force-stop com.klh.testandroid
adb shell am start -a android.intent.action.MAIN -n com.klh.testandroid/.MainActivity

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM