Android native內存檢測

內存越界檢測Address Sanitizer

0. 參考:

  1. AddressSanitizerOnAndroid google/sanitizers
  2. AddressSanitizerFlags google/sanitizers
  3. SanitizerCommonFlags google/sanitizers

需要注意:NDK R14/R15的越界檢測不支持Android < 6.0。此問題在NDK R16修復。

1. 編譯

使用cmake進行編譯的參數:

SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")

2. 安裝

運行asan_device_setup腳本往已經root的設備安裝越界檢測的庫:

#Mac${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/bin/asan_device_setup#Linux${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/asan_device_setup

執行了這一步後,會修改設備/system/bin/app_process(被上面的asan_device_setup改為一個腳本)為如下的腳本:

#!/system/bin/sh-from-zygoteASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0,malloc_context_size=0,allow_user_segv_handler=1 ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b LD_PRELOAD=$LD_PRELOAD:libclang_rt.asan-arm-android.so exec /system/bin/app_process32 $@

如果不用了,要卸載,可以執行

#Mac${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/darwin-x86_64/bin/asan_device_setup --revert#Linux${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/asan_device_setup --revert

3. 如果配合gdb或Android Studio lldb使用風味更佳~

內存泄漏檢測malloc_debug

How to find memory leaks for native code in post Android 18?

NDK的作者建議使用Address Sanitizer,並且在Android 18後應該不支持DDMS的native檢測了。

Android NDK 內存泄露檢測介紹使用LeakTracer,但是看代碼感覺功能還是很弱。

在android/platform_bionic提到android在Android N時更換過malloc實現,再根據Merge "Remove dlmalloc." · android/platform_bionic@c650447猜想在Android N前默認使用的是dlmalloc,而Android N後默認使用的是jemalloc。——這個猜想是正確的。

source.android.com/devi

啟用方式:

adb shell setprop libc.debug.malloc.program app_processadb shell setprop libc.debug.malloc 1adb shell stopadb shell start

dump方式:

am dumpheap -n package_name /data/local/tmp/dump.txt

分析方式:

github.com/android/plat

其他做法

  1. 使用malloc_debug也可以做簡易的越界檢測,安卓7.0前可以使用libc.debug.malloc 10。
  2. 如果越界檢測查不出問題,建議直接使用tombstone + 反彙編 + 看日誌研究。

推薦閱讀:

android 小白不敢觸及 NDK?
從 Android 應用層轉到 NDK 開發的學習路線是怎樣的?
為什麼 Google Android 不全面推進 NDK,反而用一個全新,但性能提升有限的 ART 來代替 Dalvik 虛擬機?

TAG:Android | AndroidNDK | Clang |