gpt4 book ai didi

opencv - 安卓 : linking to opencv results in SIGBUS (signal SIGBUS: illegal alignment) when exception is thrown

转载 作者:太空宇宙 更新时间:2023-11-03 22:41:09 25 4
gpt4 key购买 nike

我必须在 android 项目中使用 opencv。一切正常,直到我最近不得不使用 c++ exception_ptr。此后,使用std::rethrow_exception导致SIGBUS(信号SIGBUS:非法对齐)。

我创建了一个最小示例来说明问题。示例应用程序仅链接到 opencv 3.4.4,但不使用任何 opencv 功能。如果您在 CMakeLists.txt 中删除指向 opencv 的链接,该应用程序可以正常运行并且不会崩溃。但是,如果您添加它,应用程序将在调用 native 方法 triggerException() 时立即崩溃。在我的实现中,如果按下按钮,示例应用程序将调用此方法。

native-lib.cpp:

#include <jni.h>
#include <string>
#include <exception>

/*
* code based on: https://en.cppreference.com/w/cpp/error/exception_ptr
*/

std::string handle_eptr2(std::exception_ptr eptr)
{
try {
if (eptr) {
std::rethrow_exception(eptr);
}
} catch (const std::exception &e) {
return "Caught exception \"" + std::string(e.what()) + "\"\n";
}

return "Something went wrong";
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_user_exceptiontest_MainActivity_triggerException(
JNIEnv *env,
jobject /* this */) {

std::exception_ptr eptr;
try {
std::string().at(1); // this generates an std::out_of_range
} catch(...) {
eptr = std::current_exception(); // capture
}

std::string res = handle_eptr2(eptr);

return env->NewStringUTF(res.c_str());
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

set(OPENCV_DIR $ENV{HOME}/lib/OpenCV-android-sdk/sdk )

include_directories(${OPENCV_DIR}/native/jni/include )

add_library( native-lib
SHARED
src/main/cpp/native-lib.cpp)

find_library( log-lib
log)

target_link_libraries(
native-lib
# Removing the following line will make everything work as expected (what() message is returned)
${OPENCV_DIR}/native/libs/${ANDROID_ABI}/libopencv_java3.so # <--- critical line

${log-lib})

build.gradle

为了使用异常和 c++17 支持,我将以下几行添加到由 android-studio 创建的配置中。

externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang',
'-DANDROID_STL=c++_shared'
cppFlags "-std=c++1z -frtti -fexceptions"
}
}

堆栈跟踪:

<unknown> 0x004c4e47432b2b01
___lldb_unnamed_symbol15856$$libopencv_java3.so 0x0000007f811c4a58
_Unwind_Resume_or_Rethrow 0x0000007f811c4fc8
__cxa_rethrow 0x0000007f81181e50
__gnu_cxx::__verbose_terminate_handler() 0x0000007f811b1580
__cxxabiv1::__terminate(void (*)()) 0x0000007f81181c54
std::terminate() 0x0000007f81181cc0
std::rethrow_exception(std::exception_ptr) 0x0000007f802db2cc
handle_eptr2(std::exception_ptr) native-lib.cpp:35
::Java_com_example_user_exceptiontest_MainActivity_triggerException(JNIEnv *, jobject) native-lib.cpp:58

在寻找解决方案时,我查看了 opencv 源代码 ( https://github.com/opencv/opencv/blob/master/modules/core/src/parallel.cpp ) 并偶然发现了这段代码:

#ifndef CV__EXCEPTION_PTR
# if defined(__ANDROID__) && defined(ATOMIC_INT_LOCK_FREE) && ATOMIC_INT_LOCK_FREE < 2
# define CV__EXCEPTION_PTR 0 // Not supported, details: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58938

如果这会改变 opencv 的行为,我会理解,但我不明白这会如何影响根本不使用 opencv 的代码。

编辑:还值得一提的是,如果我在 linux (x86_64) 桌面设置(clang、libc++、opencv3.4.4)中直接使用此代码(没有 jni),则链接到 opencv 没有任何影响。因此,我的结论是这是一个特定于 Android 的问题...

有没有人知道如何解决该问题或接下来要尝试什么?非常感谢!

最佳答案

当您使用 C++ STL 时,Opencv 是使用 gnu 运行时编译的。参见 One STL per app .您将需要使用 gnuSTL(为此您需要回到 ndk 15)或使用 c++ STL 构建 opencv。

为了使用 c++_static 构建 opencv,您可以尝试遵循 comment in opencv bugtracker

cmake -GNinja -DINSTALL_ANDROID_EXAMPLES=ON -DANDROID_EXAMPLES_WITH_LIBS=ON -DBUILD_EXAMPLES=ON -DBUILD_DOCS=OFF -DWITH_OPENCL=OFF -DWITH_IPP=ON -DCMAKE_TOOLCHAIN_FILE=${ANDROID_NDK}/build/cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN=clang "-DANDROID_STL=c++_static" -DANDROID_ABI=x86 -DANDROID_SDK_TARGET=18 ../opencv

紧随其后

make && make install

关于opencv - 安卓 : linking to opencv results in SIGBUS (signal SIGBUS: illegal alignment) when exception is thrown,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53603609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com