简体   繁体   中英

Android NDK C++ exception throws SIGSEGV and __gnu_cxx::__verbose_terminate_handler

I want to throw a subclass of std::exception in my JNI code, the code is wrapped using swig but it's not really relevant since the generated code is rather simple:

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

I've added -fexception to flags but the vm still aborts when the user code throws the exception, the code in catch block is not executed.

I've tested different cpp implementations, gnustl_static raises __gnu_cxx::__verbose_terminate_handler , looks like the exception is not handled, stlport_static calls abort()

flags:

in Android.mk : LOCAL_CPP_FEATURES += exceptions

in Application.mk : APP_CPPFLAGS += -fexceptions APP_CFLAGS += -fexceptions

I've also tried force rebuild of stlport and libcxx, and using gcc-4.6 , gcc-4.8 and clang

UPDATE

even this simple code aborts

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

and if I set a termination function with std::set_terminate , my function get called, it's obviously not catched

UPDATE

simple code without "new" does work, so I suspect something is wrong with my exception:

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

I throw it using: throw MyNativeException("message")

UPDATE ok this exception definition does work:

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

what's wrong in the previous?

Your issue has to do with confusing C++ with Java.

throw new std::exception();

That line above may be all well and good in Java, but is a different story in C++.

  1. You are allocating memory from the free-store to create an object.

  2. But most important, new in C++ returns a pointer that points to dynamically allocated memory that you must free using delete . It is not the same as new in Java.

So that line of code in C++ is throwing a pointer value, not an object. Unfortunately for you, you didn't detect this problem, since in C++ you can throw practically anything -- a std::exception object, an int, a pointer value, etc.

If you had a catch block that caught the pointer value, then you would see this.

For example:

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

But to easily correct your attempt:

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

To confirm, here is a small, but full program that throws the exception and catches this:

#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();
    }
}

Output: abc123

I took your class and actually threw the exception you're claiming doesn't get caught. The exception in the code above does get caught, therefore the only conclusion to your issue is that you're either

  1. Not throwing the exception you claim is being thrown, or

  2. You're throwing it incorrectly (as pointed out by the issue with new ), or

  3. Your compiler is broken, or there is a switch you need to set to enable exception handling.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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