zoukankan      html  css  js  c++  java
  • Native code

    自己根据 https://github.com/zhuowei/libcorkscrew-ndk 上的库做了一个包装库并附带使用的例子(executable 分支),具体代码在自己的代码仓库里,名字叫 libbacktrace-ndk.tar。已经完美解决。但是它无法打印没有符号导出的函数(打印出来是 ???),但已经很全了。 如果要吹毛求疵打印call stack所有的函数,这时可以让程序崩溃(用static 变量控制崩溃的index,即调用几次后发生崩溃),根据打印出来的信息,再进行 ndk-stack 的crash log分析,得到某次(index)调用的完整调用栈。  还有另外一种更简便的方法,先用 ndk-stack 一直监听adb 的logcat输出,然后让程序崩溃一次(且仅一次),这时ndk-stack就已经进入crash打印模式(遇到 pc 001f4c18  /data/app-lib/com.csipsimple-2/libpjsipjni.so (unwind_backtrace+112) 即进行分析并打印callstack),以后任何时候调用libcorkscrew-ndk的dump_backtrace()的输出将被ndk-stack解析打印。

    http://stackoverflow.com/questions/7710151/native-code-how-to-get-function-call-stack-backtrace-programatically

    https://bitbucket.org/xg/android-game-base/src/c0d969d44a55/jni/NativeActivityJNI.cpp?fileviewer=file-view-default#cl-40

    https://bitbucket.org/xg/android-game-base/src/c0d969d44a55/src/com/gmail/whittock/tom/Util/NativeActivity.java?fileviewer=file-view-default#cl-91

    android-game-base/jni/NativeActivityJNI.cpp

    #include <jni.h>
    #include <stdlib.h>
    #include <signal.h>
    #include "NativeActivity.hpp"
    #include <android/log.h>
    
    #define DO_TRY
    #define DO_CATCH(loc)
    
    extern "C"
    {
    
    static struct sigaction old_sa[NSIG];
    
    static JNIEnv *g_sigEnv;
    static jobject g_sigObj;
    static jmethodID g_sigNativeCrashed;
    
    void android_sigaction(int signal, siginfo_t *info, void *reserved)
    {
        g_sigEnv->CallVoidMethod(g_sigObj, g_sigNativeCrashed);
        old_sa[signal].sa_handler(signal);
    }
    
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved)
    {
        JNIEnv *env = NULL;
        if (jvm->GetEnv((void **)&env, JNI_VERSION_1_2))
            return JNI_ERR;
    
        jclass cls = env->FindClass("com/gmail/whittock/tom/Util/NativeActivity");
    
        g_sigEnv = env;
        g_sigNativeCrashed = env->GetMethodID(cls, "onNativeCrashed", "()V");
    
        return JNI_VERSION_1_2;
    }
    
    JNIEXPORT jint JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnCreate(JNIEnv *env, jobject this_, jbyteArray savedState)
    {
        DO_TRY
        {
            // Try to catch crashes...
            g_sigObj = env->NewGlobalRef(this_);
            struct sigaction handler;
            memset(&handler, 0, sizeof(struct sigaction));
    
            handler.sa_sigaction = android_sigaction;
            handler.sa_flags = SA_RESETHAND;
            #define CATCHSIG(X) sigaction(X, &handler, &old_sa[X])
            CATCHSIG(SIGILL);
            CATCHSIG(SIGABRT);
            CATCHSIG(SIGBUS);
            CATCHSIG(SIGFPE);
            CATCHSIG(SIGSEGV);
            CATCHSIG(SIGSTKFLT);
            CATCHSIG(SIGPIPE);
    
            // Create the C++ activity proxy.
            NativeActivity *a = CreateNativeActivity();
    
            // Call onCreate with the savedState bytes.
            jbyte *stateBytes = NULL;
            jsize stateSize = 0;
            if (savedState != NULL)
            {
                stateBytes = env->GetByteArrayElements(savedState, 0);
                stateSize = env->GetArrayLength(savedState);
            }
            a->onCreate(stateBytes, stateSize);
            if (stateBytes)
                env->ReleaseByteArrayElements(savedState, stateBytes, JNI_ABORT);
    
            return (jint)a;
        }
        DO_CATCH("onCreate");
    }
    
    JNIEXPORT jbyteArray JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnSaveInstanceState(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY {
            NativeActivity *a = (NativeActivity*)handle;
    
            // Query app for instance data.
            void *data = NULL;
            int dataLen = 0;
            a->onSaveInstanceState(&data, &dataLen);
    
            // Write instance data out.
            jbyteArray outArray = NULL;
            if (data)
            {
                outArray = env->NewByteArray(dataLen);
                env->SetByteArrayRegion(outArray, 0, dataLen, (const jbyte*)data);
    
                a->onDeleteInstanceState(data);
            }
            return outArray;
        }
        DO_CATCH("onSaveInstanceState")
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnDestroy(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onDestroy();
    
            // Uninstall the signal handlers.
            #define REMOVESIG(X) sigaction(X, &old_sa[X], NULL)
            REMOVESIG(SIGILL);
            REMOVESIG(SIGABRT);
            REMOVESIG(SIGBUS);
            REMOVESIG(SIGFPE);
            REMOVESIG(SIGSEGV);
            REMOVESIG(SIGSTKFLT);
            REMOVESIG(SIGPIPE);
    
            env->DeleteGlobalRef(g_sigObj);
        }
        DO_CATCH("onDestroy");
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnPause(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onPause();
        }
        DO_CATCH("onPause");
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnResume(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onResume();
        }
        DO_CATCH("onResume");
    }
    
    JNIEXPORT jboolean JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnTouchEvent(JNIEnv *env, jobject this_, jint handle, jobject ev)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onTouchEvent();
        }
        DO_CATCH("onTouchEvent");
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnDrawFrame(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onDrawFrame();
        }
        DO_CATCH("onDrawFrame");
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnSurfaceChanged(JNIEnv *env, jobject this_, jint handle, jint w, jint h)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onSurfaceChanged(w, h);
        }
        DO_CATCH("onSurfaceChanged");
    }
    
    JNIEXPORT void JNICALL
    Java_com_gmail_whittock_tom_Util_NativeActivity_nativeOnSurfaceCreated(JNIEnv *env, jobject this_, jint handle)
    {
        DO_TRY
        {
            NativeActivity *a = (NativeActivity*)handle;
            a->onSurfaceCreated();
        }
        DO_CATCH("onSurfaceCreated");
    }
    
    }

    android-game-base/src/com/gmail/whittock/tom/Util/NativeActivity.java

    package com.gmail.whittock.tom.Util;
    
    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;
    
    import android.app.Activity;
    import android.util.Log;
    import android.content.Intent;
    import android.content.pm.ActivityInfo;
    import android.content.pm.PackageManager;
    import android.opengl.GLSurfaceView;
    import android.os.Bundle;
    import android.view.MotionEvent;
    
    public class NativeActivity extends Activity {
    
        private static final String NATIVE_STATE = "NATIVE_STATE";
        private static final String META_DATA_LIB_NAME = "LIB_NAME";
    
        private GLSurfaceView mGLView;
        private int mNativeHandle;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            try {
                ActivityInfo ai = getPackageManager().getActivityInfo(getIntent().getComponent(), PackageManager.GET_META_DATA);
                String libName;
                if (ai.metaData != null) {
                    libName = ai.metaData.getString(META_DATA_LIB_NAME);
                    System.loadLibrary(libName);
                }
                else
                {
                    throw new RuntimeException("Can't get meta data");
                }
            } catch (PackageManager.NameNotFoundException e) {
                throw new RuntimeException("Error getting activity info", e);
            }
    
            mGLView = new NativeGLSurfaceView(this);
            setContentView(mGLView);
    
            byte[] array = null;
            if (savedInstanceState != null)
                array = savedInstanceState.getByteArray(NATIVE_STATE);
            mNativeHandle = nativeOnCreate(array);
            Log.e("GameBase", "Post create: " + mNativeHandle);
    
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void onSaveInstanceState(Bundle outState) {
            byte[] array = nativeOnSaveInstanceState(mNativeHandle);
            if (array != null)
                outState.putByteArray(NATIVE_STATE, array);
        }
    
        @Override
        public void onPause() {
            super.onPause();
            mGLView.onPause();
            nativeOnPause(mNativeHandle);
        }
    
        @Override
        public void onResume() {
            super.onResume();
            mGLView.onResume();
            Log.e("GameBase", "Pre resume: " + mNativeHandle);
            nativeOnResume(mNativeHandle);
        }
    
        public boolean onTouchEvent(MotionEvent event) {
            return nativeOnTouchEvent(mNativeHandle, event);
        }
    
        public void onDrawFrame(GL10 gl) {
            nativeOnDrawFrame(mNativeHandle);
        }
    
        public void onSurfaceChanged(GL10 gl, int w, int h) {
            nativeOnSurfaceChanged(mNativeHandle, w, h);
        }
    
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            nativeOnSurfaceCreated(mNativeHandle);
        }
    
        public void onNativeCrashed() {
            // http://stackoverflow.com/questions/1083154/how-can-i-catch-sigsegv-segmentation-fault-and-get-a-stack-trace-under-jni-on-a
            new RuntimeException("crashed here (native trace should follow after the Java trace)").printStackTrace();
            startActivity(new Intent(this, CrashHandler.class));
        }
    
        private native int nativeOnCreate(byte[] savedState);
    
        private native byte[] nativeOnSaveInstanceState(int handle);
    
        private native void nativeOnDestroy(int handle);
    
        private native void nativeOnPause(int handle);
    
        private native void nativeOnResume(int handle);
    
        private native boolean nativeOnTouchEvent(int handle, MotionEvent ev);
    
        private native void nativeOnDrawFrame(int handle);
    
        private native void nativeOnSurfaceChanged(int handle, int w, int h);
    
        private native void nativeOnSurfaceCreated(int handle);
    
    }
    
    class NativeGLSurfaceView extends GLSurfaceView {
        private NativeActivity mNativeActivity;
        private NativeRenderer mRenderer;
    
        public NativeGLSurfaceView(NativeActivity nativeActivity) {
            super(nativeActivity);
            mRenderer = new NativeRenderer(nativeActivity);
            mNativeActivity = nativeActivity;
            setRenderer(mRenderer);
        }
    
        public boolean onTouchEvent(final MotionEvent event) {
            return mNativeActivity.onTouchEvent(event);
        }
    }
    
    class NativeRenderer implements GLSurfaceView.Renderer {
    
        private NativeActivity mNativeActivity;
    
        public NativeRenderer(NativeActivity nativeActivity) {
            mNativeActivity = nativeActivity;
        }
    
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            mNativeActivity.onSurfaceCreated(gl, config);
        }
    
        public void onSurfaceChanged(GL10 gl, int w, int h) {
            mNativeActivity.onSurfaceChanged(gl, w, h);
        }
    
        public void onDrawFrame(GL10 gl) {
            mNativeActivity.onDrawFrame(gl);
        }
    }
  • 相关阅读:
    Asible——inventory与大项目管理
    Asible——template
    Ansible——文件管理
    Ansible——处理任务失败
    Ansible——handlers与notify
    ubuntu 16.04 LTS 开发环境的安装及常用软件
    curl 命令详解
    VMware虚拟机三种网络模式详解
    ubantu 16.04 安装有道词典
    OneNote 使用汇总
  • 原文地址:https://www.cnblogs.com/welhzh/p/4922476.html
Copyright © 2011-2022 走看看