【发布时间】:2016-04-17 20:43:06
【问题描述】:
注意 这个问题现在已经解决了 - 请参阅下面的答案 - 除非有人删除这篇文章,否则它只会留在这里只是为了记录我自己的愚蠢,我猜......仍然,使 C++ 异常在 Android JNI 代码中工作的所有步骤和配置在下面都是正确的,所以也许它偶尔会帮助某人 - Greg
我正在阅读有关此问题的所有可能材料,并且无法在静态构建的本机库中使我的 C++ 异常正常工作...知道我缺少什么吗?
Application.mk,如下所示,我尝试了 gnustl_static 和 stlport_static,但没有任何效果。我什至强制重建 stlport_static...
NDK_TOOLCHAIN_VERSION= 4.9
APP_PLATFORM := android-10
#APP_STL := gnustl_static
APP_STL := stlport_static
APP_CPPFLAGS += -fexceptions
APP_CPPFLAGS += -frtti
# STLPORT_FORCE_REBUILD := true
ifeq ($(NDK_DEBUG),1)
APP_OPTIM := debug
APP_ABI := x86
else
APP_OPTIM := release
APP_ABI := mips armeabi armeabi-v7a x86
endif
我正在尝试的代码:
//-----------------------------------------------------------------------
// Generic external error exception
struct ExternalException : public std::exception
{
public:
explicit ExternalException(const std::string &what)
: message(what) {}
virtual ~ExternalException() throw() {}
const char *what() const throw() { return message.c_str(); }
protected:
const std::string message;
};
然后在别处:
try
{
ret = SomeFunction();
}
catch (...)
{
ret = -1;
}
上面catch (ExternalException& e) {...}我也试过了,也没用。
SomeFunction() 在某个错误条件下调用:
throw ExternalException(what);
然后应用程序就会崩溃。当我分析堆栈跟踪时,我看到异常 Unwind...() 调用什么都不做,然后它落入终止函数。
我想把我的头撞到墙上......这里有什么问题???
仅供参考,以下是我的本地编译器选项:
LOCAL_CFLAGS += -Wno-write-strings -gdwarf-2
LOCAL_CFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections -fvisibility=hidden
更新
这是捕获的堆栈跟踪的一部分,这是在 Nexus 6P 设备上使用 armeabi-v7a 构建的。以前我在 x86 模拟器上测试过调试版本,完全相同的问题。接下来会尝试使用不同的 C/CPP 标志进行测试,也许那里有冲突?
********** Crash dump: **********
Build fingerprint: 'google/angler/angler:6.0.1/MMB29P/2473553:user/release-keys'
pid: 12307, tid: 12352, name: AsyncTask #4 >>> com.hyperionics.avar <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Stack frame #00 pc 00042374 /system/lib/libc.so (tgkill+12)
Stack frame #01 pc 0003ff81 /system/lib/libc.so (pthread_kill+32)
Stack frame #02 pc 0001c73f /system/lib/libc.so (raise+10)
Stack frame #03 pc 000198f1 /system/lib/libc.so (__libc_android_abort+34)
Stack frame #04 pc 000174b0 /system/lib/libc.so (abort+4)
Stack frame #05 pc 002ac143 /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine __gabixx::__default_terminate() at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:75
Stack frame #06 pc 002ac14d /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine __gabixx::__terminate(void (*)()) at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:84
Stack frame #07 pc 002ac1a5 /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine std::terminate() at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/terminate.cc:110
Stack frame #08 pc 002ab80f /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine __cxxabiv1::call_terminate(_Unwind_Control_Block*) at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/helper_func_internal.cc:54
Stack frame #09 pc 002ab21d /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine throwException at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/cxxabi.cc:271
Stack frame #10 pc 002ab2e1 /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine __cxa_throw at /tmp/ndk-user/tmp/build-stlport/ndk/sources/cxx-stl/gabi++/src/cxxabi.cc:335
Stack frame #11 pc 00045e58 /data/app/com.hyperionics.avar-1/lib/arm/libHyperionics_avar.so: Routine IOError(std::string const&, std::string const&) at C:\android\TtsNativeLib/jni/mylib/error.h:128 (discriminator 4)
格雷格
【问题讨论】:
-
我无法重现您的结果。您确定不会显式或隐式抛出任何其他异常吗?在所有 CPU 架构上都会发生这种情况吗?我为
armeabi构建了库并在 Nexus 4 上对其进行了测试。我还将您的异常类型中的String替换为std::string,因为我不是String应该是的样子。 -
@Michael,感谢您尝试这个!抱歉字符串问题,它只是 std::string 的 typedef。我将在我的帖子中更正代码以减少混乱。我昨天的测试是在 x86 模拟器中进行的,将在 x86 和 arm 上尝试调试和发布版本,看看是否有任何区别。
-
@Michael - armeabi-v7a、Nexus 6P 设备上的同样问题,这次发布版本。将捕获的堆栈跟踪添加到我的问题帖子中。您能否发给我或发布您的示例代码和确切的标志,一切 - 为您工作的示例?也许我的 CFLAGS 或 CPPFLAGS 以某种方式发生冲突......
-
以下是相关部分:pastebin.com/pgbyFVbD
IOError长什么样子? -
@Michael 谢谢!确实,这个简单的例子有效,我的大图书馆没有......我会更加绞尽脑汁,分析结构等。我堆栈跟踪上的 IOError() 只是一个行内联函数,它调用: throw ExternalException(what); (最初它是一个带有文件名参数的不同异常类,为此测试进行了简化)。
标签: android c++ exception java-native-interface try-catch