Android NDK C ++异常抛出SIGSEGV和__gnu_cxx :: __ verbose_terminate_handler

时间:2014-08-05 02:09:03

标签: android c++ android-ndk

我想在我的std::exception代码中抛出JNI的子类,代码是使用swig包装的,但由于生成的代码相当简单,因此它并不真正相关:

void function_that_throws_exception() {
    ...
    throw MyNativeException("Error");
}

try {
    function_that_throws_exception();
} catch(MyNativeException &_e) {
    jclass excep = jenv->FindClass("x/y/zMyNativeException");
    if (excep)
        jenv->ThrowNew(excep, (&_e)->what());
    return 0;
}

我已将-fexception添加到标志中,但当用户代码抛出异常时,vm仍然中止,catch块中的代码未执行。

我已经测试了不同的cpp实现,gnustl_static引发了__gnu_cxx::__verbose_terminate_handler,看起来没有处理异常, stlport_static来电abort()

国旗:

Android.mk中的

LOCAL_CPP_FEATURES += exceptions

Application.mk中的

APP_CPPFLAGS += -fexceptions APP_CFLAGS += -fexceptions

我还尝试强制重建stlport和libcxx,并使用gcc-4.6gcc-4.8clang

更新

即使这个简单的代码也会中止

try
{
    throw new std::exception();
} catch (std::exception &e) {
}

如果我使用std::set_terminate设置终止函数,我的函数会被调用,它显然没有被捕获

更新

简单代码没有" new"确实有效,所以我怀疑我的例外有问题:

class MyNativeException : public std::exception
{
public:
    explicit MyNativeException(const char *msg) : message(msg) {}
    virtual ~MyNativeException() throw() {}
    virtual const char *what() const throw() { return message.c_str(); }
protected:
    const std::string message;
};

我把它扔掉: throw MyNativeException("message")

更新 确定这个异常定义确实有效:

class MyNativeException
{
public:
    MyNativeException(const char *msg) : message(msg) {}
    ~MyNativeException() {}
    const char *what() { return message.c_str(); }
private:
    const std::string message;
};

之前的错误是什么?

1 个答案:

答案 0 :(得分:3)

您的问题与将C ++与Java混淆有关。

throw new std::exception();

上面的这一行在Java中可能都很好,但在C ++中是一个不同的故事。

  1. 您正在从免费商店分配内存以创建对象。

  2. 但最重要的是,C ++中的new会返回一个指向动态分配内存的指针,您必须使用delete释放该内存。它与Java中的new不同。

  3. 因此,C ++中的代码行抛出一个指针值,而不是一个对象。不幸的是,你没有发现这个问题,因为在C ++中你几乎可以抛出任何东西 - std::exception对象,int,指针值等。

    如果你有一个抓住指针值的catch块,那么你会看到这个。

    例如:

    try
    {
       throw new std::exception();
    } 
    catch (std::exception *e) 
    {
       delete e;
    }
    

    但要轻松纠正你的尝试:

    try
    {
       throw std::exception();
    } 
    catch (std::exception &e) 
    {
    }
    

    要确认,这是一个小而完整的程序,它抛出异常并捕捉到这个:

    #include <exception>
    #include <string>
    #include <iostream>
    
    class MyNativeException : public std::exception
    {
        public:
             explicit MyNativeException(const char *msg) : message(msg) {}
             virtual ~MyNativeException() throw() {}
             virtual const char *what() const throw() { return message.c_str(); }
        protected:
             const std::string message;
    };
    
    int main()
    {
        try
        {
            throw MyNativeException("abc123");
        }
        catch (std::exception& e)
        {
            std::cout << e.what();
        }
    }
    

    输出: abc123

    我上了你的课,实际上抛出了你声称没有被抓住的例外。上面的代码中的例外确实被捕获,因此您的问题的唯一结论是您要么

    1. 不会抛出您声称被抛出的异常,或

    2. 你投掷错误(正如new的问题所指出的那样)或

    3. 您的编译器已损坏,或者您需要设置一个开关以启用异常处理。