繁体   English   中英

当静态使用第 3 方库时,在 Android 中从 .so 引发异常时的 SIGABRT

[英]SIGABRT when exception is thrown from .so in Android when 3rd party lib is used statically

我有一个依赖于 OpenCV 的原生 Android、SDK 样式库。

为了避免用户使用库和他们自己使用 OpenCV 时的冲突,我想将 OpenCV 静态编译到我的库中并隐藏它的符号。

我静态编译了 OpenCV(3.4.13 world模块)并使用它,以及它在我的库中的第 3 方库。

当我尝试使用我的库时,它会引发异常,即使用户捕获了异常, SIGABRT也会导致应用程序终止。

这是来自 logcat 的堆栈跟踪


A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 24115 (.test), pid 24115 (.test)
...
A/DEBUG: backtrace:
A/DEBUG:       #00 pc 0000000000051948  /apex/com.android.runtime/lib64/bionic/libc.so (abort+168) (BuildId: 931371c1098ffd5adc489b9ff4da8e82)
A/DEBUG:       #01 pc 00000000000b2ba0  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libc++_shared.so (BuildId: ece72a2ebc3774a1be9fd21271258acd3bcdfaa7)
A/DEBUG:       #02 pc 00000000000aec8c  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libc++_shared.so (__gxx_personality_v0+348) (BuildId: ece72a2ebc3774a1be9fd21271258acd3bcdfaa7)
A/DEBUG:       #03 pc 00000000004dd2dc  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG:       #04 pc 00000000004dd7e4  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG:       #05 pc 0000000000170600  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libmylib.so (mylib::TestClass::TestClass(char const*, char const*)+908) (BuildId: 790f2880373cb985055ab9b7b2efc48b1afb82fd)
A/DEBUG:       #06 pc 000000000000c5d0  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG:       #07 pc 000000000000c3b8  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG:       #08 pc 000000000000c308  /data/app/~~gc4ZOfzcr7C0hRfmsieCtQ==/com.example.test-sx2ESCfGCsi3lXPZWnk9nA==/base.apk!libJnilibrary.so (Java_com_example_lib_Engine_cxxInit+56) (BuildId: 7f3605ea8cb95dc87864e3df22f6b77b46c2e592)
A/DEBUG:       #09 pc 00000000002d7644  /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: 2b417e2566f5eb686666666b6ee952ea)

(如果 JNI 库使用c++_static也会发生这种情况,但在这种情况下,它上面的__gxx_personality_v0和 1 来自libJnilibrary.so

如果我将 OpenCV 编译为共享库并将我的库链接到它,那么一切正常。

我以前在我的库中遇到过异常问题,请参阅我提出的这个问题。 我通过使用c++_static STL 编译所有内容来解决它。 问题看起来与类似,确实我错过了key function ,但即使添加了它,问题仍然存在。

我使用llvm-readelf -CWs查看了符号,并注意到当动态链接 OpenCV 时,除了 OpenCV 符号外,输出还包含一些静态使用 OpenCV 时不存在的 ndk 和 cxxabi 符号。 我不知道它是否相关,但例如

110: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND std::uncaught_exception()
...
201: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  UND vtable for __cxxabiv1::__vmi_class_type_info
...
231: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND std::__ndk1::to_string(unsigned int)

(使用静态构建的 OpenCV 时,所有这些都缺失)

我正在使用 ndk 版本21e (我目前不能使用更高版本,因为另一个库使用Bazel ,它目前最多支持 21)

OpenCV 使用以下标志构建

cmake -DCMAKE_BUILD_TYPE=Release -DINSTALL_ANDROID_EXAMPLES=OFF -DANDROID_EXAMPLES_WITH_LIBS=OFF -DANDROID_ABI="arm64-v8a" 
-DBUILD_EXAMPLES=OFF -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF -DBUILD_ANDROID_PROJECTS=OFF -DBUILD_ANDROID_EXAMPLES=OFF -DANDROID_ARM_NEON=1 
-DANDROID_STL=c++_static -DANDROID_PLATFORM=android-21 -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake" 
-DBUILD_SHARED_LIBS=OFF -DBUILD_FAT_JAVA_LIB=OFF -DBUILD_JAVA=OFF -DINSTALL_CREATE_DISTRIB=ON -DINSTALL_ANDROID_EXAMPLES=OFF -DBUILD_opencv_objdetect=OFF
-DBUILD_opencv_video=ON -DBUILD_opencv_videoio=ON -DBUILD_opencv_features2d=ON -DBUILD_opencv_flann=OFF -DBUILD_opencv_highgui=ON -DBUILD_opencv_ml=OFF 
-DBUILD_opencv_photo=OFF -DBUILD_opencv_python=OFF -DBUILD_opencv_shape=OFF -DBUILD_opencv_stitching=OFF -DBUILD_opencv_superres=OFF -DBUILD_opencv_ts=OFF 
-DBUILD_opencv_videostab=OFF -DBUILD_ANDROID_PROJECTS=OFF -DBUILD_opencv_world=ON -DBUILD_opencv_dnn=OFF -DBUILD_opencv_core=ON -DBUILD_opencv_imgcodecs=ON 
-DBUILD_opencv_imgproc=ON -DBUILD_opencv_calib3d=ON -GNinja -DCMAKE_INSTALL_PREFIX=../install -DBUILD_ZLIB=1 -DWITH_PROTOBUF=OFF -DWITH_QUIRC=OFF ..

我的库是使用带有这些 CMake 标志的 Gradle 和 Android Studio 编译的

externalNativeBuild {
    cmake {
        cppFlags "-std=c++17 -static-openmp -fopenmp -fexceptions -frtti -Wno-unused-command-line-argument -Wl,-s"
        cppFlags "-Wl,--exclude-libs,libc++_static.a -Wl,--exclude-libs,libc++abi.a"
        arguments "-DANDROID_STL=c++_static", "-DANDROID_ARM_NEON=TRUE"
    }
}

这个问题最终与第 3 方或类似的事情无关。

我使用的是 NDK 版本r21e 将 NDK 升级到r24解决了这个问题。

似乎当将OpenCV链接为共享对象时,它通过导入或包含一些丢失/有问题的符号来掩盖实际的 NDK 错误,当我们停止使用它时,出现了错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM