[Android][Stability] NativeCrash分析(一)-NativeCrash原理

一.基礎(chǔ)知識-編譯,鏈接,裝載

基礎(chǔ)的程序怎么來的,怎么到內(nèi)存運行的,參考如下:
[](https://blog.csdn.net/TaylorPotter/article/details/103778980

二.NativeCrash原理

Native 程序是指可以直接運行在操作系統(tǒng)上,并且處理器直接執(zhí)行機器碼的程序,比如 “/system/bin” “/system/lib” 目錄下的文件,這些應(yīng)用程序都是由GCC(c/c++)編譯生成,這些程序的崩潰統(tǒng)稱為Native Exception,比如空指針,非法指針,程序跑飛,內(nèi)存踩壞等。

Native Crash都是進程收到信號引起的.

2.1 信號的來源:

在這里插入圖片描述

盜圖如上,一個進程收到信號可以是系統(tǒng)發(fā)送的也可以是另一個級別的進程發(fā)送的
但都需要經(jīng)過內(nèi)核,相當于內(nèi)核需截獲信號,預(yù)處理或善后操作:


在這里插入圖片描述

信號注冊和發(fā)送詳細過程如下:


在這里插入圖片描述
  1. 信號發(fā)送或信號注冊的信息保存在目標進程的進程控制塊中;
  2. 在進程返回用戶態(tài)之前會檢查進程的控制塊signal的位圖信息,需要處理的信號需要找到制定的處理函數(shù)指針去處理
  3. signal處理處理函數(shù)可以在目標進程中自定義,內(nèi)核有默認處理信號的操作;
  4. 目標進程的signal處理函數(shù)處理完后會繼續(xù)交給內(nèi)核繼續(xù)處理,內(nèi)核做該進程的信號處理善后操作.

2.2 信號處理函數(shù)

絕大多數(shù)的用戶空間進程的入口是linker,在linux中即ld動態(tài)鏈接器.為什么這么說?
如果該程序需要動態(tài)鏈接共享庫,可執(zhí)行文件裝載進內(nèi)存后第一次進入用戶態(tài)當前cpu占寄存器上的指令地址是動態(tài)鏈接器的入口,需要先調(diào)用動態(tài)鏈接器解釋可執(zhí)行文件執(zhí)行,需要首先鏈接加載共享庫.

在android上,動態(tài)連接器即是linker,在linux上動態(tài)鏈接器即是ld動態(tài)連接器

如果該程序是一個靜態(tài)鏈接的可執(zhí)行文件,則在該可執(zhí)行文件加載入內(nèi)存后,第一次進入用戶態(tài)時當前cpu占寄存器上的指令地址是該可執(zhí)行文件的Entry point address.

當然大多數(shù)可可執(zhí)行文件需要動態(tài)鏈接,比如一個libc就太多可執(zhí)行文件需要用到.

2.3 Native程序注冊信號過程

2.3.1 Native進程裝載運行過程:

在這里插入圖片描述

1.如圖,大部分動態(tài)鏈接的可執(zhí)行文件,進入用戶空間入口是linker,linux上是ld動態(tài)鏈接器,android上是linker,
圖中.interp section中即是可執(zhí)行文件中保存動態(tài)鏈接器的地址,返回給startThread,在返回用戶空間時pc指針指的就是動態(tài)鏈接器的入口地址.
2.如果是靜態(tài)鏈接的可執(zhí)行程序,入口即是可執(zhí)行文件中指定的程序入口地址
3.大部分動態(tài)鏈接的可執(zhí)行文件不包含動態(tài)鏈接的共享庫,在裝載到內(nèi)存后發(fā)現(xiàn)依賴的so不在物理內(nèi)存中便會去通過linker試圖加載so至物理內(nèi)存然后映射到虛擬地址空間,通過重定位已獲取so的虛擬地址,以供程序使用.
4.從圖中可以看出,在一個程序的main方法之前還跑了一些其他的方法,其中.init區(qū)函數(shù)是程序員可控的,比如寫了一個全局的變量賦值為 new 一個對象,此時這個對象的初始化方法在.init區(qū),會在main方法前執(zhí)行.

2.3.2 Native程序注冊信號簡單過程:

在這里插入圖片描述

文末附詳細過程.

2.4 App進程注冊信號過程

2.4.1 應(yīng)用進程啟動過程

在這里插入圖片描述

2.4.2 zygote fork app process簡單過程

在這里插入圖片描述

從native角度來看,app進程都是可執(zhí)行文件app_process的進程映像


在這里插入圖片描述

2.4.3 App進程注冊信號簡單過程

在這里插入圖片描述

文末附詳細過程

2.5 Native Crash后處理過程

在這里插入圖片描述

圖中應(yīng)該還需畫出,當目標進程處理完信號(主要是日志的dump操作)之后內(nèi)核還會對該信號進行善后處理,如釋放進程資源,進程退出等.

debuggerd的主要操作過程:

在這里插入圖片描述

文末附詳細過程.

三.Debug材料及工具使用

https://blog.csdn.net/TaylorPotter/article/details/103785967

四.附錄-代碼詳細過程:

1. linker初始化詳細過程

在這里插入圖片描述

2. native進程啟動及信號注冊詳細流程
在這里插入圖片描述

3. App進程啟動及信號注冊處理詳細過程:
在這里插入圖片描述

4. Native Crash處理詳細流程:
在這里插入圖片描述

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容