【问题标题】:C++ exceptions in Android JNI code - againAndroid JNI 代码中的 C++ 异常 - 再次
【发布时间】: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/pgbyFVbDIOError 长什么样子?
  • @Michael 谢谢!确实,这个简单的例子有效,我的大图书馆没有......我会更加绞尽脑汁,分析结构等。我堆栈跟踪上的 IOError() 只是一个行内联函数,它调用: throw ExternalException(what); (最初它是一个带有文件名参数的不同异常类,为此测试进行了简化)。

标签: android c++ exception java-native-interface try-catch


【解决方案1】:

抱歉,一切正常。这是我的编程错误,显然是在晚上工作时我状态不佳。

简而言之,问题出在哪里:在调用 SomeFunction() 时,我实际上有参数,但例外是在创建这些参数时,而不是在函数内部。只是我的'try {'指令必须向上移动......就像:

Ptr<OutPackedStream> pout = CreatePackedStream(fname.c_str());
try
{
    ret = SomeFunction(pout);
}
catch (...)
{
    ret = -1;
}

所以很明显我无法在 CreatePackedStream() 中捕获异常,因为它不在 try{} 中......但让我感到困惑的是堆栈跟踪指向 ret = SomeFunction(pout) 行,然后才转到 @ 987654323@。现在查看代码,以及我的堆栈跟踪,这非常明显,再次为我的笨拙感到抱歉!

格雷格

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    相关资源
    最近更新 更多