Android native內存檢測
內存越界檢測Address Sanitizer
0. 參考:
- AddressSanitizerOnAndroid google/sanitizers
- AddressSanitizerFlags google/sanitizers
- 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。——這個猜想是正確的。
https://source.android.com/devices/tech/debug/native-memory
啟用方式:
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
分析方式:
https://github.com/android/platform_development/blob/master/scripts/native_heapdump_viewer.py
其他做法
- 使用malloc_debug也可以做簡易的越界檢測,安卓7.0前可以使用libc.debug.malloc 10。
- 如果越界檢測查不出問題,建議直接使用tombstone + 反彙編 + 看日誌研究。
推薦閱讀:
※android 小白不敢觸及 NDK?
※從 Android 應用層轉到 NDK 開發的學習路線是怎樣的?
※為什麼 Google Android 不全面推進 NDK,反而用一個全新,但性能提升有限的 ART 來代替 Dalvik 虛擬機?
TAG:Android | AndroidNDK | Clang |