android init 程序原始碼除錯探索

2021-10-06 01:34:54 字數 3713 閱讀 9496

android 系統native程序有很多,其中比較重要的有init,zygote,installd,dex2oat等,native程序的除錯是困難的,尤其是除錯其初始化過程,原因是沒有整合化除錯環境,雖然gdb是可能的,但是對使用者不具有易用性。android studio 隨能除錯so,但對native可執行檔案無能為力。作為對比,visual studio作為宇宙最強ide,除錯windows可執行檔案的能力可以說是甩開android studio幾條街。筆者經過研究,找到了媲美windows上的無縫除錯方法。

先上除錯效果(init 程序屬性系統初始化):

先說配置環境:windows 10 + vs2017 + visualgdb5.4 + vmware15pro + ubuntu1604 + nexus5x + aosp_android-6.0.1_r67

再說為什麼選擇visualgdb,相比android studio,以及vscode,vs + visualgdb支援除錯的彙編檢視,這是除錯底層問題的有力特性。雖然visualgdb不直接支援除錯aosp,但經過研究和細心配置,是可以做到的。

再說原理:首先visualgdb支援android native程序的開發和除錯,其原理是ndk用來交叉編譯,除錯時會通過adb上傳gdbserver,gdbserver啟動程序後等待客戶端連線,visualgdb連線gdbserver,其內部使用執行於windows上的gdb進行遠端除錯。我們只用它的除錯能力,不用它來編譯,編譯使用vmware15pro + ubuntu1604。總結來說我們使用visualgdb的三項能力來達到比肩vs在windows平台的除錯體驗。

第一,建立linux工程,使用自定義構建工具。構建可在配置中定義,不過因工作量不大,也可手動在ubuntu上執行命令

第二,原始碼和彙編級遠端除錯android系統的native程序的能力。其中包括條件斷點,步進,步入,呼叫棧,變數監視,記憶體檢視等

第三,原始碼導航能力,樹形檔案結構,f12轉到定義等。(原始碼同步不太好使,不過影響不大)

注意:vs在乙個解決方案內建立兩個工程,乙個是linux工程,用於對映原始碼目錄的檢視,用於查閱原始碼,打除錯斷點等,另乙個android工程用於除錯。二者不可能合為乙個工程,二者只有以這種方式才能很好的配合。

除錯android的初始化程序如init,zygote等,最理想的情形是真機正在初始化時的情形。由於init是使用者態首個程序,直接除錯是不可能的,因為adbd還沒有啟動,但理論上可以做到,因為著名的root程式magisk原理是替換init,然後啟動原始init。這個工作量略大,筆者沒有研究這種方式,而是在乙個已完成啟動的系統上啟動另乙個編譯的init程序來除錯,雖然init的執行環境改變了,但是仍然是很有價值的除錯方式,因為你可以配置你自己的init執行環境。

對於zygote,這裡情況就好多了,因為zygote是在adbd啟動之後執行的,並且zygote可以動態停止和執行(sart zygote,stop zygote,相當於軟重啟),可以做到除錯時與執行時環境幾乎完全相同。其他程序dex2oat之類的更簡單了,是按需啟動,隨時啟動停止,絲毫不影響系統執行。

下面說說配置過程:

先要看硬體型號(美版或國際版等)然後在找出可刷rom,並確定版本號,

見:然後 根據版本號,確定原始碼標籤,     見:

然後 根據版本號,獲取對應的驅動,見:

3.  安裝ubuntu1604,和編譯aosp就不說了。再此提一些技巧解決問題,關於ubuntu中aosp空間規劃不好的,可以掛載物理硬碟,快捷方式out目錄到別的空間等方式解決。ubuntu我在本地分了300g,另外掛程式載了800g物理硬碟,東西太多。編譯aosp

source build/envsetup.sh

lunch aosp_bullhead-eng

make -j4

4.  首次編譯完android-6.0.1_r67後,修改要除錯的程式或模組的優化標誌增加 -o0,關閉優化,對於init位置為:

system/core/init/android.mk:19  ,   然後重新單獨編譯init ,因為init是靜態編譯的,所以不涉及其他模組用命令:

source build/envsetup.sh

lunch aosp_bullhead-eng

mmm system/core/init

5. 在vs + visualgdb 端 新建工程,流程如下:

vs:檔案:新建:專案:已安裝:visualgdb:linux project wizard:

名稱:and600

確定:(project type)

import a project:import a project built with other tools

next:(linux computer selection)

build the project under linux over network:

remote computer: ***@192.168.111.139

next:[mismatching env...... just default (fix)]:source code location:

the sources are already on 192.168.111.139:

source directory: /home/***/src-android-local/android-6.0.1_r67

next:source code access:

upload modified sources to 192.168.111.139 on each build

next:building and debugging:

i don't know the main executable yet. ask me later when istart debugging

finish

等待完成,注意由於原始碼太大,請限定子目錄,去除prebuild,extral 等不必要的目錄,筆者保留的目錄包括:

abi;art;bionic;bootable;build;codedb;dalvik;frameworks;libcore;libnativehelper;system;tools;*

這樣總同步檔案大概2g多一點。

然後建立除錯工程:

解決方案:新增到解決方案

建立名為init的android控制台工程,保證此工程是除錯無問題的(當無法打斷點時,重啟手機有效),這裡巧妙的使用的與要除錯的android程序init同名的工程。拷貝編譯好的帶符號的init檔案到and_dbg601\init\obj\local\arm64-v8a,路徑為:android-6.0.1_r67/out/target/product/bullhead/root/init

/home/***/ext800/src-android-local/android-6.0.1_r67    d:\debug\and_dbg601\and601c

6.    在除錯工程中設定init啟動引數--second-stage,在原始碼工程中開啟檔案d:\debug\and_dbg601\and601c\system\core\init\init.cpp

最後f5 啟動除錯,於是本文開頭的那個除錯場景就出現了。

Android Init程序詳解

init是乙個由核心啟動的使用者級程序init是linux系統中使用者空間的第乙個程序。由於android是基於linux核心的,所以init也是android系統中使用者空間的第乙個程序。adb shell ps中init的pid為1,ppid為01.解析指令碼init.rc 2.根據init.r...

android init 程序分析 (1 簡介)

init是核心 kernel 初始化完成後啟動的第乙個程序。程序id為1。init的源 在system core init 目錄。參考 android的init過程分析 android的init過程詳解 一 android的init過程 二 初始化語言 init.rc 解析 android研究 an...

AbstractCollection原始碼分析

abstractcollection抽象類提供了collection的骨架實現,collection分析請看 這裡直接看它的 是如何實現的.public abstract iterator iterator 該方法沒有實現.public abstract int size 該方法沒有實現.publi...