我试图在Android的本机库中进行异常处理(由JNI连接到主Java程序)。
问题是:如果我启用异常(这很简单,因为ndk-r5),我失去了从回溯中推断出崩溃原因的能力。即当使用异常时,崩溃回溯仅包含2行,这不足以理解上下文。
我已经搜索了很多,但看起来没有人遇到过这个问题,或者只是没有考虑过回溯问题。
希望他们能够在新版本中修复它,但是从ndk-r5c到r10b,Android从2.3到4.4都是一样的。试过gcc和clang。
虽然它可能与我们的旗帜或来源或其他东西有关
但它最容易在最简单的情况下重现:
1.采用原始NDK样本,位图等离子体
2.在JNI中,将plasma.c重命名为plasma.cpp(所以,它现在是C ++)
3.添加APP_CPPFLAGS + = -fexceptions
4.添加APP_STL:= gnustl_static(此步骤不是必需的)
5.在消息来源中,放置一些故意崩溃的代码
6.编译(最近尝试过gcc 4.6,ndk-r9和ndk-r10b)并运行
此时,日志中仍然有漂亮的回溯(10件物品)。但是如果:
7.将try {}块放在某个地方(甚至不在崩溃点附近)!
此后,回溯只有2行。请注意,我甚至没想过扔!
我的问题是:任何人都可以在同一个版本中同时获得两件事(例外和体面的崩溃回溯)吗?
详情:我添加了2个功能
extern void crash(){
int a;
static volatile int* crash = 0;
*crash = 5;
}
extern void nocrash(){
}
然后,在fill_plasma函数内部:
crash();
// try{
nocrash();
// }catch(const std::exception& e){}
所以,使用此代码,回溯是可以的。取消注释尝试 - > 2行回溯。
我试图分析反汇编以了解可能的不同之处,但编译器只在函数末尾添加代码,在这种情况下从不调用(无抛出)。 / p>
为什么我需要例外:我们想要摆脱大量的错误检查代码。此代码在宏中,在具有良好异常支持的平台上表现不同(因此,库的C ++用户可以在几乎每行之后编写他们的代码而无需进行错误检查)。
为什么我需要在逻辑删除中使用标准回溯:我们的代码是更大解决方案的一部分。它在整个其他网站上进行了测试。如果他们遇到了崩溃,他们会收集所有标准日志以及他们在崩溃前所做的一些描述
在最坏的情况下,没有复制。无法使用gdb。
我虽然使用一些第三方库来获取回溯(比如google breakhpad),但是我必须设置信号处理程序(不确定它是否适合系统的其他部分),以及它们(例如breakpad)转储二进制信息到其他位置(不确定我们是否可以强制这些远程测试人员收集此文件)。
任何想法,例如尝试一些不同的编译器标志,或者我可能犯了什么错误?