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

android JNI开发

Android NDK开发简介 NDK和SDK以及JNI有啥关系

Eclipse集成JNI与AndroidNDK操作

Android Studio编译并集成SO文件

使用 JNI 集成 java 和 .net dll