Android ndk Android NDK在函数中获取调用堆栈信息

Android ndk Android NDK在函数中获取调用堆栈信息,android-ndk,Android Ndk,我正在用本机代码编写一个函数,希望从函数内部了解其他函数如何调用它,因此我决定在我的c代码中使用java.lang.Thread.dumpStack,但似乎不起作用。有人知道其他可能的方法吗?多谢 代码如下: JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { __android_log_print(ANDROID_LOG_INFO, "TIM", "JNI_OnLoad Called"); JNIEn

我正在用本机代码编写一个函数,希望从函数内部了解其他函数如何调用它,因此我决定在我的c代码中使用
java.lang.Thread.dumpStack
,但似乎不起作用。有人知道其他可能的方法吗?多谢

代码如下:

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)
04-24 11:44:48.217:D/dalvikvm(4140):尝试加载lib/data/data/com.tim.myjni/lib/libmyjni.so 0x413486d8
04-24 11:44:48.267:D/dalvikvm(4140):添加了共享lib/data/data/com.tim.myjni/lib/libmyjni.so 0x413486d8
04-24 11:44:48.267:I/TIM(4140):调用JNI_OnLoad
04-24 11:44:48.277:I/TIM(4140):呼叫了GetEnv
04-24 11:44:48.277:I/TIM(4140):调用FinClass
04-24 11:44:48.277:I/TIM(4140):调用了GetStaticMethodID
04-24 11:44:48.287:W/System.err(4140):java.lang.Throwable:堆栈转储
04-24 11:44:48.348:W/System.err(4140):位于java.lang.Thread.dumpStack(Thread.java:496)
04-24 11:44:48.348:W/System.err(4140):位于java.lang.Runtime.nativeLoad(本机方法)
04-24 11:44:48.377:W/System.err(4140):位于java.lang.Runtime.loadLibrary(Runtime.java:368)
04-24 11:44:48.377:W/System.err(4140):位于java.lang.System.loadLibrary(System.java:535)
04-24 11:44:48.407:W/System.err(4140):位于com.tim.myjni.MainActivity。(MainActivity.java:53)
04-24 11:44:48.407:W/System.err(4140):位于java.lang.Class.newInstanceImpl(本机方法)
04-24 11:44:48.417:W/System.err(4140):位于java.lang.Class.newInstance(Class.java:1319)
04-24 11:44:48.417:W/System.err(4140):位于android.app.Instrumentation.newActivity(Instrumentation.java:1023)
04-24 11:44:48.417:W/System.err(4140):在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1870)
04-24 11:44:48.417:W/System.err(4140):位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980)
04-24 11:44:48.417:W/System.err(4140):在android.app.ActivityThread.access$600(ActivityThread.java:122)
04-24 11:44:48.417:W/System.err(4140):位于android.app.ActivityThread$H.handleMessage(ActivityThread.java:1146)
04-24 11:44:48.447:W/System.err(4140):位于android.os.Handler.dispatchMessage(Handler.java:99)
04-24 11:44:48.447:W/System.err(4140):位于android.os.Looper.loop(Looper.java:137)
04-24 11:44:48.467:W/System.err(4140):位于android.app.ActivityThread.main(ActivityThread.java:4340)
04-24 11:44:48.467:W/System.err(4140):位于java.lang.reflect.Method.invokenactive(本机方法)
04-24 11:44:48.477:W/System.err(4140):位于java.lang.reflect.Method.invoke(Method.java:511)
04-24 11:44:48.477:W/System.err(4140):位于com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-24 11:44:48.477:W/System.err(4140):位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-24 11:44:48.477:W/System.err(4140):在dalvik.System.NativeStart.main(本机方法)

这不是错误,这是堆栈跟踪。它只是碰巧像一个例外一样被打印出来

线程中的代码是:

public static void dumpStack() {
    new Throwable("stack dump").printStackTrace();
}
这就是日志中的内容--注意第一行:


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

谢谢您的解释。看起来我正在打印一个Java调用堆栈,是否有任何方法可以打印本机代码,比如说,C调用堆栈?我不认为有一个公共函数可以从NDK打印。在libutils内部有
CallStack
类,您可以通过创建
CallStack
对象,调用
update()
,然后
dump()
将其打印到日志中来使用它。在最新版本的Android(>=Jellybean)上,您还可以使用
kill(getpid(),SIGQUIT)
使Dalvik转储其线程;由于您的线程将处于
NATIVE
状态,因此您将获得一个本机堆栈转储以及Dalvik跟踪。您可能需要从/data/anr/traces.txt中获取这些信息——请观看logcat以获取信息。再次感谢fadden,我非常感谢您的帮助。我不想让我的应用程序崩溃,所以最好尝试使用CallStack类。更清楚的是,使用
SIGQUIT
杀死你的进程只是发送一个信号,该信号被Dalvik中的信号处理程序捕获,它暂停VM,转储所有线程堆栈,然后继续。你的应用程序不会真的死掉。
kill()
系统调用可能命名错误。