Android NDK c++异常抛出SIGSEGV和__gnu_cxx::__verbose_terminate_ha
Android NDK C++ exception throws SIGSEGV and __gnu_cxx::__verbose_terminate_handler
我想在我的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
的标志,但虚拟机仍然中止时,用户代码抛出异常,在catch
块代码不执行。
我已经测试了不同的cpp实现,gnustl_static
引发__gnu_cxx::__verbose_terminate_handler
,看起来异常没有处理,stlport_static
调用abort()
标记:
in Android.mk
:LOCAL_CPP_FEATURES += exceptions
in 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;
};
我使用: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;
};
前面有什么问题?
你的问题与混淆c++和Java有关。
throw new std::exception();
上面这行在Java中可能很好,但在c++中则是另一回事。
-
你正在从free-store分配内存来创建一个对象。
-
但最重要的是,c++中的
new
返回一个指针,该指针指向动态分配的内存,必须使用delete
释放。与Java中的new
不一样
所以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
问题所指出的那样),或你的编译器坏了,或者你需要设置一个开关来启用异常处理
- xmake总是报告:错误:无法获取cxx的程序,为什么
- 使用 Powershell 命令将 cpp 文件的文件夹编译为 GNU 的 g++
- 如何使用 gnu gcc 标志 -mpc32、-mpc64 和 -mpc80?
- 在 Julia 中使用 boost 库和 Windows 上的 Cxx.jl
- Cxx.jl 在 Julia Complex 和 std::complex 之间进行转换
- 仅为C++文件(.h、.cpp、.cxx、.c)生成标记文件
- 在为 iOS 构建 aws-sdk-cpp 时,cmake 上的 CXX 编译器错误已损坏
- c++ 链接器错误"针对'.rodata.str1.1'的重新定位R_X86_64_32"链接 CXX 共享库 libsrt.so
- 防止 GNU Make 在每次构建时生成 protobuf 代码
- 为什么 C++ 编译器在"c:program filesgnu emacsinclude"中查找包含文件?
- 使用CMake ExternalProject_Add构建mongo cxx驱动程序
- 有没有适用于Windows.lib文件的GNU二进制文件描述符(BFD)
- 监视GNU Radio中的缓冲区
- CMake 识别 MSVC(C 和 CXX),但仍抛出"未找到 CMAKE_*_COMPILER"
- GNU C++: unique_ptr.h 没有这样的文件或目录
- MinGW在Cygwin上.关于链接GNU科学图书馆的一些问题
- 与libc相比,Gnu科学图书馆的性能较差
- GNU 在看到其他同名文件时重用源文件
- Julia Cxx 在模块中打包不同的行为
- 检查工作正常的 CXX 编译器:/cygdrive/c/cygwin64/bin/clang++ -- 已损坏