2013-04-24 75 views
0

我寫在本地代碼的功能,想從什麼其他函數調用它,所以我決定在我的C代碼中使用java.lang.Thread.dumpStack在函數內部知道堆棧信息,但作用似乎不工作。有人知道其他可能的方式嗎?非常感謝!的Android NDK得到調用函數

下面

是代碼:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) 
{ 
    __android_log_print(ANDROID_LOG_INFO, "TIM", "JNI_OnLoad Called"); 

    JNIEnv *env = NULL; 

    if (vm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) 
    { 
      __android_log_print(ANDROID_LOG_INFO, "TIM", "GetEnv Failed"); 
      return JNI_ERR; 
    } 

    __android_log_print(ANDROID_LOG_INFO, "TIM", "GetEnv Called"); 

    // public static void dumpStack() 

    jclass cls2 = env->FindClass("java/lang/Thread"); 
    if(!cls2) 
    { 
     __android_log_print(ANDROID_LOG_INFO, "TIM", "FindClass Failed"); 
     return JNI_ERR; 
    } 

    __android_log_print(ANDROID_LOG_INFO, "TIM", "FinClass Called"); 


    jmethodID mid = env->GetStaticMethodID(cls2, "dumpStack", "()V"); 
    if(!mid) 
    { 
     __android_log_print(ANDROID_LOG_INFO, "TIM", "GetStaticMethodID loadLibrary Failed"); 
     return JNI_ERR; 
    } 

    __android_log_print(ANDROID_LOG_INFO, "TIM", "GetStaticMethodID Called"); 

    env->CallStaticVoidMethod(cls2, mid); 

    return JNI_VERSION_1_6; 
} 

,這是我得到的錯誤:

04-24 11:44:48.217: D/dalvikvm(4140): Trying to load lib /data/data/com.tim.myjni/lib/libmyjni.so 0x413486d8 
04-24 11:44:48.267: D/dalvikvm(4140): Added shared lib /data/data/com.tim.myjni/lib/libmyjni.so 0x413486d8 
04-24 11:44:48.267: I/TIM(4140): JNI_OnLoad Called 
04-24 11:44:48.277: I/TIM(4140): GetEnv Called 
04-24 11:44:48.277: I/TIM(4140): FinClass Called 
04-24 11:44:48.277: I/TIM(4140): GetStaticMethodID Called 
04-24 11:44:48.287: W/System.err(4140): java.lang.Throwable: stack dump 
04-24 11:44:48.348: W/System.err(4140):  at java.lang.Thread.dumpStack(Thread.java:496) 
04-24 11:44:48.348: W/System.err(4140):  at java.lang.Runtime.nativeLoad(Native Method) 
04-24 11:44:48.377: W/System.err(4140):  at java.lang.Runtime.loadLibrary(Runtime.java:368) 
04-24 11:44:48.377: W/System.err(4140):  at java.lang.System.loadLibrary(System.java:535) 
04-24 11:44:48.407: W/System.err(4140):  at com.tim.myjni.MainActivity.<clinit>(MainActivity.java:53) 
04-24 11:44:48.407: W/System.err(4140):  at java.lang.Class.newInstanceImpl(Native Method) 
04-24 11:44:48.417: W/System.err(4140):  at java.lang.Class.newInstance(Class.java:1319) 
04-24 11:44:48.417: W/System.err(4140):  at android.app.Instrumentation.newActivity(Instrumentation.java:1023) 
04-24 11:44:48.417: W/System.err(4140):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1870) 
04-24 11:44:48.417: W/System.err(4140):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980) 
04-24 11:44:48.417: W/System.err(4140):  at android.app.ActivityThread.access$600(ActivityThread.java:122) 
04-24 11:44:48.417: W/System.err(4140):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146) 
04-24 11:44:48.447: W/System.err(4140):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-24 11:44:48.447: W/System.err(4140):  at android.os.Looper.loop(Looper.java:137) 
04-24 11:44:48.467: W/System.err(4140):  at android.app.ActivityThread.main(ActivityThread.java:4340) 
04-24 11:44:48.467: W/System.err(4140):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-24 11:44:48.477: W/System.err(4140):  at java.lang.reflect.Method.invoke(Method.java:511) 
04-24 11:44:48.477: W/System.err(4140):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
04-24 11:44:48.477: W/System.err(4140):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
04-24 11:44:48.477: W/System.err(4140):  at dalvik.system.NativeStart.main(Native Method) 

回答

0

這是不是一個錯誤,這是堆棧跟蹤。它恰好被打印爲一個例外。

在線程的代碼是:

public static void dumpStack() { 
    new Throwable("stack dump").printStackTrace(); 
} 

這就是你所擁有的日誌中 - 請注意第一行:

W/System.err(4140): java.lang.Throwable: stack dump

+0

感謝您的解釋法登。看起來我正在打印一個Java調用堆棧,有沒有什麼方法可以打印本地代碼,比如說C調用堆棧? – user1921972 2013-04-25 09:40:51

+0

我不認爲在NDK中有這樣的公共功能。內部有Libutils中的'CallStack'類,你可以通過創建一個'CallStack'對象,調用'update()',然後'dump()'將它打印到日誌中。在最近版本的Android(> = Jellybean)上,你也可以使用'kill(getpid(),SIGQUIT)'使Dalvik轉儲它的線程;因爲你的線程處於「NATIVE」狀態,所以你會得到一個本地棧轉儲以及Dalvik跟蹤。您可能需要將其從/data/anr/traces.txt中取出 - 觀看logcat以獲取信息。 – fadden 2013-04-25 17:58:05

+0

再次感謝fadden,我非常感謝您的幫助。我不想讓我的APP崩潰,所以最好嘗試使用CallStack類。 – user1921972 2013-04-26 03:34:23