TroubleShoot
生活随笔
收集整理的這篇文章主要介紹了
TroubleShoot
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Troubleshooting
? ?在開發(fā)階段,logging讓你決定和展示有利于解決問題關(guān)于應(yīng)用程序的狀態(tài)的信息。
通過logging的展示的信息對于Debugging很重要但是這是不夠的,但是
應(yīng)該知道錯誤發(fā)生在哪里。當(dāng)面對這無法預(yù)期的錯誤時(shí),錯誤
定位成為了一個(gè)拯救者。知道了正確的工具和技術(shù)使你能迅速的解決問題。
? ?棧追蹤分析:
為了觀察棧,你將安裝一個(gè)bug在hello-jni實(shí)例應(yīng)用程序中將引發(fā)程序
崩潰。使用Eclipse,打開著hello-jni.c的源文件。修改本地函數(shù)的
內(nèi)容如下:
? ?static jstring func1( JNIEnv* env )
{
/* BUG BEGIN */
env = 0;
/* BUG END */
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return func1(env);
}
通過設(shè)置JNIEnv的接口指針的值為0,你將觸發(fā)這個(gè)崩潰。現(xiàn)在建立
和運(yùn)行這個(gè)應(yīng)用程序。當(dāng)應(yīng)用程序開始,點(diǎn)擊Call本地方法來觸發(fā)這
本地的功能。這應(yīng)用程序崩潰,和一個(gè)棧的幾率被展示在logcat中
如下:
? ?帶有崩潰信號的開始行指示這棧的調(diào)用。#00的開始行是崩潰發(fā)生的
。接下的一行,#01,是上一個(gè)函數(shù)的調(diào)用,等等。在這PC的后面這
數(shù)子是代碼的地址。正如在棧記錄所看到的,這本地代碼的崩潰在地址
000003c處,和上一個(gè)函數(shù)調(diào)用時(shí)stringFromJNI本地函數(shù)。這個(gè)000003c
地址本身可能不會告訴你太多,但是使用正確的工具這個(gè)地址能夠
被用來發(fā)現(xiàn)真正的文件盒crash發(fā)生的行。Android NDK帶有ndk-stack
工具能夠把棧記錄到真正文件的名字和行號。在命令行,進(jìn)入項(xiàng)目根目錄
,使用
? ?adb locat|ndk-stack -sym 0bj/local/armabi
這ndk-stack工具將翻譯棧,如下。地址得到翻譯到j(luò)ni/hello-jni.c在
源文件33行。這些信息使錯誤定位更加容易。通過簡單放置一個(gè)斷點(diǎn)在
地址上你能夠阻止應(yīng)用程序和監(jiān)聽?wèi)?yīng)用程序的狀態(tài)。
? ?JNI的擴(kuò)展檢測:
默認(rèn)情況下,JNI函數(shù)做非常少的錯誤檢測。錯誤經(jīng)常導(dǎo)致程序崩潰。Andoid
提供一個(gè)擴(kuò)展的檢測模式對于JNI調(diào)用,如CheckJNI。當(dāng)開啟下,JavaVM
和JNIENV接口指針轉(zhuǎn)到了函數(shù)表來執(zhí)行一個(gè)擴(kuò)展水平的錯誤檢測在調(diào)用
真正的實(shí)現(xiàn)前。CheckJNI能夠偵測接下的問題:
? ?設(shè)法分配一個(gè)負(fù)數(shù)長度的數(shù)組
? ?Bad或NULL指針被傳遞給JNI函數(shù)
? ?當(dāng)傳遞給類名時(shí),語法錯誤
? ?當(dāng)在critical部分是,JNI調(diào)用
? ?錯誤的參數(shù)當(dāng)傳遞到NEWDirectByeBuffer
? ?當(dāng)一個(gè)異常發(fā)生時(shí)JNI調(diào)用
? ?JNIEnv接口指針被用作錯誤線程
? ?Field類型和set<Type>Fiel函數(shù)不搭配
? ?函數(shù)類型和Call<Type>Method函數(shù)不搭配
? ?DeleteGlobalRef/DeleteLocalRef調(diào)用有錯誤引用類型
? ?錯誤的釋放模式被傳遞到Release<Type>ArrayElement函數(shù)
? ?不兼容的錯誤類型返回從本地方法
? ?傳遞到一個(gè)JNI調(diào)用無效的UTF-8序列。
默認(rèn)情況下,在模擬器上CheckJNI模式開啟的,但是并不在常用的
Andoid設(shè)備上,由于它在系統(tǒng)性能的影響。
? ?開啟ChckJNI:
? ?在一個(gè)regular設(shè)備上,使用命令行,你能夠開啟CheckJNI模式通過
使用:adb shell setprop debug.checkjni 1
? ?這并不影響著運(yùn)行的應(yīng)用程序但是任何應(yīng)用程序開啟向?qū)?br /> CheckJni開啟。CheckJNI狀態(tài)被展示在logcat中,如下:
? ?jstring
? ?Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
? ?jobject thiz )
? ?{
? ? ? ?jintArray javaArray = (*env)->NewIntArray(env, -1);
? ? ? ?return (*env)->NewStringUTF(env, "Hello from JNI !");
? ?}
創(chuàng)建了一個(gè)負(fù)長度的整形數(shù)組。建立和運(yùn)行應(yīng)用程序在模擬器上。當(dāng)
應(yīng)用程序開啟,點(diǎn)擊Call本地按鈕來觸發(fā)本地方法。如下,CheckJNI將
展示一個(gè)警告信息在logcat和終止執(zhí)行。
? ?
? ?在開發(fā)階段,logging讓你決定和展示有利于解決問題關(guān)于應(yīng)用程序的狀態(tài)的信息。
通過logging的展示的信息對于Debugging很重要但是這是不夠的,但是
應(yīng)該知道錯誤發(fā)生在哪里。當(dāng)面對這無法預(yù)期的錯誤時(shí),錯誤
定位成為了一個(gè)拯救者。知道了正確的工具和技術(shù)使你能迅速的解決問題。
? ?棧追蹤分析:
為了觀察棧,你將安裝一個(gè)bug在hello-jni實(shí)例應(yīng)用程序中將引發(fā)程序
崩潰。使用Eclipse,打開著hello-jni.c的源文件。修改本地函數(shù)的
內(nèi)容如下:
? ?static jstring func1( JNIEnv* env )
{
/* BUG BEGIN */
env = 0;
/* BUG END */
return (*env)->NewStringUTF(env, "Hello from JNI !");
}
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
jobject thiz )
{
return func1(env);
}
通過設(shè)置JNIEnv的接口指針的值為0,你將觸發(fā)這個(gè)崩潰。現(xiàn)在建立
和運(yùn)行這個(gè)應(yīng)用程序。當(dāng)應(yīng)用程序開始,點(diǎn)擊Call本地方法來觸發(fā)這
本地的功能。這應(yīng)用程序崩潰,和一個(gè)棧的幾率被展示在logcat中
如下:
? ?帶有崩潰信號的開始行指示這棧的調(diào)用。#00的開始行是崩潰發(fā)生的
。接下的一行,#01,是上一個(gè)函數(shù)的調(diào)用,等等。在這PC的后面這
數(shù)子是代碼的地址。正如在棧記錄所看到的,這本地代碼的崩潰在地址
000003c處,和上一個(gè)函數(shù)調(diào)用時(shí)stringFromJNI本地函數(shù)。這個(gè)000003c
地址本身可能不會告訴你太多,但是使用正確的工具這個(gè)地址能夠
被用來發(fā)現(xiàn)真正的文件盒crash發(fā)生的行。Android NDK帶有ndk-stack
工具能夠把棧記錄到真正文件的名字和行號。在命令行,進(jìn)入項(xiàng)目根目錄
,使用
? ?adb locat|ndk-stack -sym 0bj/local/armabi
這ndk-stack工具將翻譯棧,如下。地址得到翻譯到j(luò)ni/hello-jni.c在
源文件33行。這些信息使錯誤定位更加容易。通過簡單放置一個(gè)斷點(diǎn)在
地址上你能夠阻止應(yīng)用程序和監(jiān)聽?wèi)?yīng)用程序的狀態(tài)。
? ?JNI的擴(kuò)展檢測:
默認(rèn)情況下,JNI函數(shù)做非常少的錯誤檢測。錯誤經(jīng)常導(dǎo)致程序崩潰。Andoid
提供一個(gè)擴(kuò)展的檢測模式對于JNI調(diào)用,如CheckJNI。當(dāng)開啟下,JavaVM
和JNIENV接口指針轉(zhuǎn)到了函數(shù)表來執(zhí)行一個(gè)擴(kuò)展水平的錯誤檢測在調(diào)用
真正的實(shí)現(xiàn)前。CheckJNI能夠偵測接下的問題:
? ?設(shè)法分配一個(gè)負(fù)數(shù)長度的數(shù)組
? ?Bad或NULL指針被傳遞給JNI函數(shù)
? ?當(dāng)傳遞給類名時(shí),語法錯誤
? ?當(dāng)在critical部分是,JNI調(diào)用
? ?錯誤的參數(shù)當(dāng)傳遞到NEWDirectByeBuffer
? ?當(dāng)一個(gè)異常發(fā)生時(shí)JNI調(diào)用
? ?JNIEnv接口指針被用作錯誤線程
? ?Field類型和set<Type>Fiel函數(shù)不搭配
? ?函數(shù)類型和Call<Type>Method函數(shù)不搭配
? ?DeleteGlobalRef/DeleteLocalRef調(diào)用有錯誤引用類型
? ?錯誤的釋放模式被傳遞到Release<Type>ArrayElement函數(shù)
? ?不兼容的錯誤類型返回從本地方法
? ?傳遞到一個(gè)JNI調(diào)用無效的UTF-8序列。
默認(rèn)情況下,在模擬器上CheckJNI模式開啟的,但是并不在常用的
Andoid設(shè)備上,由于它在系統(tǒng)性能的影響。
? ?開啟ChckJNI:
? ?在一個(gè)regular設(shè)備上,使用命令行,你能夠開啟CheckJNI模式通過
使用:adb shell setprop debug.checkjni 1
? ?這并不影響著運(yùn)行的應(yīng)用程序但是任何應(yīng)用程序開啟向?qū)?br /> CheckJni開啟。CheckJNI狀態(tài)被展示在logcat中,如下:
? ?jstring
? ?Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
? ?jobject thiz )
? ?{
? ? ? ?jintArray javaArray = (*env)->NewIntArray(env, -1);
? ? ? ?return (*env)->NewStringUTF(env, "Hello from JNI !");
? ?}
創(chuàng)建了一個(gè)負(fù)長度的整形數(shù)組。建立和運(yùn)行應(yīng)用程序在模擬器上。當(dāng)
應(yīng)用程序開啟,點(diǎn)擊Call本地按鈕來觸發(fā)本地方法。如下,CheckJNI將
展示一個(gè)警告信息在logcat和終止執(zhí)行。
? ?
總結(jié)
以上是生活随笔為你收集整理的TroubleShoot的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Debugging
- 下一篇: 新的C库Bionic的介绍