Android NDK C异常引发SIGSEGV和__gnu_cxx :: __ verbose_terminate_handler

Android NDK C异常引发SIGSEGV和__gnu_cxx :: __ verbose_terminate_handler,第1张

概述我想在我的JNI代码中抛出std::exception的子类,该代码使用swig进行了包装,但由于生成的代码非常简单,因此它实际上并不相关:voidfunction_that_throws_exception(){...throwMyNativeException("Error");}try{function_that_throws_exception();}catch(M

我想在我的JNI代码中抛出std :: exception的子类,该代码使用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 =例外

在Application.mk中:
APP_CPPFLAGS = -fexceptions
APP_CFLAGS = -fexceptions

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

更新

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

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;};

我用它扔:
抛出MyNativeException(“ message”)

更新
好的,此异常定义确实起作用:

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

以前有什么问题?

解决方法:

您的问题与C与Java混淆有关.

抛出新的std :: exception();

上面的那一行在Java中可能很好,但是在C中则是另一回事.

>您正在从免费存储区中分配内存以创建对象.
>但最重要的是,C语言中的new函数返回一个指针,该指针指向必须使用delete释放的动态分配的内存.它与Java中的新增功能不同.

因此,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

我参加了您的课程,实际上抛出了您声称没有被捕获的异常.上面代码中的异常确实被捕获,因此,您遇到的问题的唯一结论是您要么

>不抛出您声称正在抛出的异常,或者
>您错误地抛出了它(如new问题所指出的那样),或者
>您的编译器已损坏,或者您需要设置一个开关来启用异常处理.

总结

以上是内存溢出为你收集整理的Android NDK C异常引发SIGSEGV和__gnu_cxx :: __ verbose_terminate_handler全部内容,希望文章能够帮你解决Android NDK C异常引发SIGSEGV和__gnu_cxx :: __ verbose_terminate_handler所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1078220.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存