2016-01-13 32 views
1

注意現在已解決此問題 - 請參閱下面的答案 - 除非有人刪除此帖,否則它將留在此處僅記錄我自己的愚蠢,我猜...儘管如此,所有的步驟和配置,使Android的JNI代碼工作的C++異常下面是正確的,所以也許它會偶爾幫助別人 - 格雷格Android JNI代碼中的C++異常 - 再次

我正在閱讀有關此問題的所有可能的材料,不能讓我的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 

更新

這裏是堆棧跟蹤的一部分捕獲,這是與armeabi-V7A建立在Nexus 6P設備。以前我在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) 

格雷格

+0

我無法重現您的結果。你確定你沒有明確地或暗示地拋出任何其他例外嗎?這在所有的CPU架構上都會發生嗎?我爲'armeabi'構建了庫,並在Nexus 4上對其進行了測試。我還用'std :: string'替換了您的異常類型中的'String',因爲我不是'String'應該是什麼。 – Michael

+0

@Michael,謝謝你的嘗試!對於String問題抱歉,它只是std :: string的一個typedef。我會更正我的文章中的代碼,以減少混淆。我昨天的測試是在x86模擬器中,將在x86和arm上嘗試調試和發佈版本,以查看是否有任何區別。 – gregko

+0

@Michael - armeabi-v7a,Nexus 6P設備上的同樣問題,這次發佈版本。將捕獲的堆棧跟蹤添加到我的問題帖子中。你能寄給我還是寄出你的樣品代碼和確切的標誌,一切 - 爲你工作的樣品?也許我的CFLAGS或CPPFLAGS會以某種方式發生衝突...... – gregko

回答

1

道歉,所有作品的權利。這是我的編程錯誤,顯然在晚上工作,我不是最好的。

簡而言之,問題是什麼:在我對SomeFunction()的調用中,我實際上有參數,而例外是創建這些參數,而不是函數內部。只要我「嘗試{」指令必須動起來...這是這樣的:

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

所以,很顯然我沒能趕上在CreatePackedStream()例外,因爲它不是內嘗試{} .. 。但是我感到困惑的是,堆棧跟蹤指向ret = SomeFunction(pout)行,然後纔去到CreatePackedStream()。現在看代碼,還有我的堆棧痕跡,這是非常明顯的,再次爲我的笨拙抱歉!

Greg