Android Native crash 具有上下文不全、出錯(cuò)信息模糊、難以捕捉等特點(diǎn),比 java crash 更難修復(fù)。
程序崩潰
- Unix-like系統(tǒng)中,崩潰都是編程錯(cuò)誤或者硬件錯(cuò)誤相關(guān)的,如除零、段地址錯(cuò)誤等。
- 異常發(fā)生時(shí),CPU通過(guò)異常中斷的方式,觸發(fā)異常處理流程。不同的處理器,有不同的異常中斷類型和中斷處理方式。
- linux把這些中斷處理,統(tǒng)一為信號(hào)量。
- 信號(hào)機(jī)制是進(jìn)程之間相互傳遞消息的一種方法,信號(hào)全稱為軟中斷信號(hào)。
常見(jiàn)信號(hào)量

1.png
指針使用不當(dāng):
- 空指針。
- (char*)malloc(len + 1)),申請(qǐng)空間大小時(shí),要加1,并且最后一個(gè)字節(jié)值置為0,表示字符串結(jié)尾。動(dòng)態(tài)申請(qǐng)的內(nèi)存,用完后要及時(shí)free掉,避免內(nèi)存泄露
- msg = strcat(msg, "\r\n"),使用此方法時(shí),msg的大小要足夠大,能夠容納下,自身長(zhǎng)度加上追加內(nèi)容的長(zhǎng)度
局部引用與全局引用:
JNI WARNING: 0x40538d98 is not a valid JNI reference 這個(gè)錯(cuò)誤比較好解決。用NewGlobalRef將其轉(zhuǎn)換成全局引用
FindClass僅返回局部引用, 需將其轉(zhuǎn)換成全局引用:
jclass stringClass = (*env)->FindClass(env, "java/lang/String");
strClass = (*env)->NewGlobalRef(env, stringClass);
NewStringUTF僅返回局部引用.需將其轉(zhuǎn)換成全局引用:
jstring coding = (*env)->NewStringUTF(env, "utf-8");
strencoding = (*env)->NewGlobalRef(env, coding);
ndk-stack
ndk-stack 工具讓您可以在堆疊追蹤出現(xiàn)在adb logcat的輸出中時(shí)過(guò)濾它們。 它還可以從源代碼將共享庫(kù)中的任意地址替換為對(duì)應(yīng)的 <source-file>:<line-number> 值,從而更容易找出問(wèn)題所在。
adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi
您也可以使用 -dump 選項(xiàng)將 logcat 指定為輸入文件。例如:
adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt
nm查看符號(hào)表
列出.o .a .so中的符號(hào)信息,包括諸如符號(hào)的值,符號(hào)類型及符號(hào)名稱等,可以用于調(diào)試native方法找不到的問(wèn)題。
nm -D hello.so
| 參數(shù) | 描述 |
|---|---|
| A | Global absolute 符號(hào) |
| a | Local absolute 符號(hào) |
| B | Global bss 符號(hào) |
| b | Local bss 符號(hào) |
| D | Global data 符號(hào) |
| d | Local data 符號(hào) |
| f | 源文件名稱符號(hào) |
| T | Global text 符號(hào) |
| t | Local text 符號(hào) |
| U | 未定義符號(hào) |
參考:
https://zhuanlan.zhihu.com/p/27834417?group_id=868422576001671168
https://developer.android.com/ndk/guides/ndk-stack.html
http://www.cnblogs.com/wangkangluo1/archive/2012/07/02/2572438.html