Я пытаюсь создать простой двоичный файл Android для тестирования UBSAN (дезинфицирующее средство для неопределенного поведения) с помощью ndk r15c и clang. Однако сборка завершается неудачно при попытке связать со следующей ошибкой:
jni/main.cpp:17: error: undefined reference to '__ubsan_handle_type_mismatch_v1'
jni/main.cpp:24: error: undefined reference to '__ubsan_handle_add_overflow'
jni/main.cpp:30: error: undefined reference to '__ubsan_handle_type_mismatch_v1'
jni/main.cpp:32: error: undefined reference to '__ubsan_handle_type_mismatch_v1'
jni/main.cpp:32: error: undefined reference to '__ubsan_handle_type_mismatch_v1'
jni/main.cpp:32: error: undefined reference to '__ubsan_handle_dynamic_type_cache_miss'
jni/main.cpp:33: error: undefined reference to '__ubsan_handle_dynamic_type_cache_miss'
jni/main.cpp:33: error: undefined reference to '__ubsan_handle_dynamic_type_cache_miss'
jni/main.cpp:34: error: undefined reference to '__ubsan_vptr_type_cache'
jni/main.cpp:34: error: undefined reference to '__ubsan_vptr_type_cache'
jni/main.cpp:34: error: undefined reference to '__ubsan_vptr_type_cache'
jni/main.cpp:34: error: undefined reference to '__ubsan_handle_dynamic_type_cache_miss'
jni/main.cpp:36: error: undefined reference to '__ubsan_vptr_type_cache'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.c:336: error: undefined reference to '__ubsan_handle_sub_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.c:357: error: undefined reference to '__ubsan_handle_load_invalid_value'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.c:343: error: undefined reference to '__ubsan_handle_load_invalid_value'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.c:348: error: undefined reference to '__ubsan_handle_load_invalid_value'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.h:192: error: undefined reference to '__ubsan_handle_load_invalid_value'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_ostream.h:136: error: undefined reference to '__ubsan_handle_negate_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/char_traits.h:194: error: undefined reference to '__ubsan_handle_negate_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_string.h:379: error: undefined reference to '__ubsan_handle_add_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_string_base.h:105: error: undefined reference to '__ubsan_handle_negate_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_string_base.h:105: error: undefined reference to '__ubsan_handle_divrem_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_alloc.h:330: error: undefined reference to '__ubsan_handle_negate_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_alloc.h:330: error: undefined reference to '__ubsan_handle_divrem_overflow'
/opt/android_ndk/android-ndk-r15c/sources/cxx-stl/stlport/stlport/stl/_alloc.h:352: error: undefined reference to '__ubsan_handle_divrem_overflow'
Мой файл Android.mk выглядит следующим образом:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS += -Wall
LOCAL_LDLIBS := -L$(LOCAL_PATH)/lib -llog -g
LOCAL_C_INCLUDES := bionic
LOCAL_C_INCLUDES += $(LOCAL_PATH)/include
LOCAL_SRC_FILES:= main.cpp
LOCAL_CPPFLAGS := -Wall -fPIE -fexceptions -fsanitize=undefined
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog -fPIE -pie -fsanitize=undefined
LOCAL_MODULE := ubsan_test
include $(BUILD_EXECUTABLE)
Мой Application.mk выглядит следующим образом:
NDK_TOOLCHAIN_VERSION:=clang
APP_STL:=stlport_static
APP_ABI := armeabi armeabi-v7a
APP_PLATFORM := android-17
Я предполагаю, что мне не хватает какого-либо флага компоновщика или какой-либо другой настройки, но я не смог понять, что происходит. Глядя на символы во время выполнения убсана, символы, похоже, существуют.
Примечание. Я также пытался использовать LOCAL_SANITIZE: = undefined вместо -fsanitize = undefined в моем Android.mk с тем же результатом.
В настоящее время мы не отправляем Ubsan Runtime в NDK: https://github.com/android-ndk/ndk/issues/183
На данный момент вы можете использовать -fsanitize=undefined -fsanitize-trap=undefined
вместо. Это не идеально, потому что вместо полезной диагностики вы просто получаете ловушку (SIGILL на ARM, наверняка, то же самое для других платформ), но лучше, чем ничего, пока мы не получим Ubsan Runtime в NDK.
Других решений пока нет …