首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android:当抛出异常时,链接到opencv会导致SIGBUS (信号SIGBUS:非法对齐)

Android:当抛出异常时,链接到opencv会导致SIGBUS (信号SIGBUS:非法对齐)
EN

Stack Overflow用户
提问于 2018-12-03 23:40:04
回答 1查看 469关注 0票数 2

我必须在android项目中使用opencv。直到最近我不得不使用c++ exception_ptr,一切都很好。从那时起,std::rethrow_exception的使用会导致SIGBUS (信号SIGBUS:非法对齐)。

我创建了一个很小的例子来说明这个问题。示例应用程序仅链接到opencv 3.4.4,但不使用任何opencv函数。如果您删除CMakeLists.txt中的opencv链接,该应用程序运行良好,不会崩溃。但是,如果添加它,当调用本机方法triggerException()时,应用程序就会崩溃。在我的实现中,如果按下按钮,示例应用程序将调用此方法。

native-lib.cpp:

代码语言:javascript
复制
#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

代码语言:javascript
复制
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创建的配置中添加了以下行。

代码语言:javascript
复制
externalNativeBuild {
    cmake {
        arguments '-DANDROID_TOOLCHAIN=clang',
                  '-DANDROID_STL=c++_shared'
        cppFlags "-std=c++1z -frtti -fexceptions"
    }
}

Stacktrace:

代码语言:javascript
复制
<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),无意中发现了以下代码片段:

代码语言:javascript
复制
#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的问题.

有没有人知道如何解决这个问题,或者下一步该做些什么?提前谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-12 13:37:22

Opencv是在使用c++ stl时用gnu运行时编译的。见每个应用程序一个STL。您需要使用gnustl (为此需要返回到ndk 15 )或使用c++ stl构建opencv。

为了用c++_static构建opencv,您可以尝试遵循opencv bugtracker跟踪器评语

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

紧接着是

制造&&制造安装

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53603609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档