Android jni 集成 Address Sanitizer
Posted Alex_MaHao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android jni 集成 Address Sanitizer相关的知识,希望对你有一定的参考价值。
Address Sanitizer
该工具是google开源,用于对c++中的代码进行质量检测。
具体介绍:https://developer.android.google.cn/ndk/guides/asan?hl=zh_cn
按照官方的文档集成,会遇到一些问题,比如对应so找不到等。所以踩了一些坑。记录一下。
集成
整体思路如下:
对于debug版本,集成Address Sanitizer
,便于在开发期间发现问题。
对于release版本,不进行集成,并避免对应的一些so添加到release中去。
将对应所需资源拷贝到工程目录下
google的集成文档中需要添加一些so文件,但是并没有提供对应so下载。通过github等找了一份。
具体下载地址如下:https://download.csdn.net/download/lisdye2/12464858
将该文件包含目录放到对应的工程目录下。和src
同级。
build.gradle中添加配置
debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// 添加c层代码检测 https://developer.android.com/ndk/guides/asan
sourceSets.debug.jniLibs.srcDir "sanitizer/jniLibs"
sourceSets.debug.resources.srcDir("sanitizer")
sourceSets.debug.resources.filter.exclude("sanitizer/jniLibs/**")
externalNativeBuild
cmake
arguments "-DSANITIZER=TRUE"
CMakeLists.txt中添加配置
if (SANITIZER)
target_compile_options(native-lib PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(native-lib PROPERTIES LINK_FLAGS -fsanitize=address)
endif()
其中native-lib
表示对应的so文件名称,根据需求替换
运行
运行时,加入了Address Sanitizer
会影响执行的效率。如果遇见地址错误等,会崩溃,并抛出异常堆栈。如下为堆栈的起始,具体内容很长。
==29443==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x0071f1395248 at pc 0x0071e6ed2234 bp 0x0071f1395210 sp 0x0071f1395208
...
个性化配置
Asan提供了一些个性化的配置,需要借助wrap.sh来配置。具体链接:https://developer.android.com/ndk/guides/wrap-script#debugging_when_using_wrapsh
在这里备注一下内容,如果配置了wrap.sh,可能会导致无法debug工程。所以需要添加一些额外的配置,具体如下:
#!/system/bin/sh
HERE="$(cd "$(dirname "$0")" && pwd)"
export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1
ASAN_LIB=$(ls $HERE/libclang_rt.asan-*-android.so)
if [ -f "$HERE/libc++_shared.so" ]; then
# Workaround for https://github.com/android-ndk/ndk/issues/988.
export LD_PRELOAD="$ASAN_LIB $HERE/libc++_shared.so"
else
export LD_PRELOAD="$ASAN_LIB"
fi
# malloc_debug存在问题,仅做记录备用
#LIBC_DEBUG_MALLOC_OPTIONS=backtrace\\ leak_track\\ verbose\\ abort_on_error\\ fill "$@"
#"$@"
cmd=$1
shift
os_version=$(getprop ro.build.version.sdk)
if [ "$os_version" -eq "27" ]; then
cmd="$cmd -Xrunjdwp:transport=dt_android_adb,suspend=n,server=y -Xcompiler-option --debuggable $@"
elif [ "$os_version" -eq "28" ]; then
cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
cmd="$cmd -XjdwpProvider:adbconnection $@"
fi
exec $cmd
以上是关于Android jni 集成 Address Sanitizer的主要内容,如果未能解决你的问题,请参考以下文章
Android jni 集成 Address Sanitizer