Issue
I'm using address sanitizer with the Android NDK following the instructions here: https://developer.android.com/ndk/guides/asan
I get a SIGABRT when an exception is thrown even when the exception is handled. For example the following code causes SIGABRT at the point the exception is thrown when run with ASAN but there is no abort when run without ASAN. From what I read online, ASAN can handle code with exceptions. What am I doing wrong?
#include <jni.h>
#include <exception>
void testThrowException()
{
try {
throw std::exception(); // Stops here with SIGABRT
}
catch (std::exception& )
{
}
}
extern "C"
{
JNIEXPORT void JNICALL
Java_com_example_hellojnicallback_MainActivity_doNativeStuff(JNIEnv *env, jobject thiz) {
testThrowException();
}
}
Here is my CMakeLists.txt:
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -DANDROID_ARM_MODE=arm -DANDROID_STL=c++_shared")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -DANDROID_ARM_MODE=arm -DANDROID_STL=c++_shared")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -fsanitize=address")
add_library(hello-jnicallback SHARED
hello-jnicallback.cpp)
# Include libraries needed for hello-jnicallback lib
target_link_libraries(hello-jnicallback
android
log)
And here is my wrap.sh:
#!/system/bin/sh
HERE="$(cd "$(dirname "$0")" && pwd)"
export ASAN_OPTIONS=log_to_syslog=false,allow_user_segv_handler=1,detect_leaks=0
export LD_PRELOAD=$HERE/libclang_rt.asan-i686-android.so
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" -ge "28" ]; then
cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
cmd="$cmd -XjdwpProvider:adbconnection $@"
fi
exec $cmd
I'm using NDK version 20.0.5594570 from Android Studio running on Windows.
I have tested on Android emulator (x86) running Android 10 and on a Pixel (arm 64) running Android 9 with same result.
EDIT: Based on Dan Alberts response here are the updated CMakeLists.txt and wrap.sh. With these changes plus moving the -DANDROID_ARM_MODE=arm", "-DANDROID_STL=c++_shared" to build.gradle it is working correctly.
add_library(hello-jnicallback SHARED
hello-jnicallback.cpp)
target_compile_options(hello-jnicallback PUBLIC -fsanitize=address -fno-omit-frame-pointer)
set_target_properties(hello-jnicallback PROPERTIES LINK_FLAGS -fsanitize=address)
# Include libraries needed for hello-jnicallback lib
target_link_libraries(hello-jnicallback
android
log)
#!/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
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" -ge "28" ]; then
cmd="$cmd -XjdwpProvider:adbconnection -XjdwpOptions:suspend=n,server=y -Xcompiler-option --debuggable $@"
else
cmd="$cmd -XjdwpProvider:adbconnection $@"
fi
exec $cmd
Solution
Are you somehow seeing an out of date copy of that page? Your wrap.sh is missing pieces needed to make this work (your LD_PRELOAD is wrong).
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fno-omit-frame-pointer -DANDROID_ARM_MODE=arm -DANDROID_STL=c++_shared")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer -DANDROID_ARM_MODE=arm -DANDROID_STL=c++_shared")
-DANDROID_STL is not a compiler flag. You need to set that in your build.gradle like the doc shows.
Answered By - Dan Albert
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.