Android 開機啟動除錯,system_process除錯
下載,編譯,匯入,配置
作為開發者,經常會對Debug工程進行除錯,Android具有debug簽名的應用才可以被除錯,如果想除錯系統原始碼呢?
想要除錯原始碼,首先必須要有原始碼,並且保證裝置執行的原始碼和IED裡的原始碼是同一份.
下載和編譯AOSP原始碼,本人使用的ubuntu LTS 16.04系統, 磁碟剩餘空間至少要150G(如果編譯時,提示空間不夠,可以刪掉".repo" 目錄), 記憶體16G, 8G的記憶體,編譯死慢,除錯更是卡的動不了,牆裂建議用16G的記憶體!
注意編譯原始碼時,如果你是64位的機器,就編譯64位的目標版本,執行起來快!
編譯完成後執行如下程式碼:
soruce build/envsetup.sh mmm development/tools/idegen/ sudo ./development/tools/idegen/idegen.sh
注意請在原始碼目錄下執行,如果是按照官方的教程,應該是在 ~/WORKING_DIRECTORY 目錄下
"mmm development/tools/idegen/" 執行完成後會生成idegen.jar
"sodo ./development/tools/idegen/idegen.sh"則會在原始碼目錄下生成IEDA工程配置檔案:android.ipr,android.iml
android.ipr:儲存工程相關的設定,比如編譯器配置,入口,相關的libraries等
android.iml:主要是描述了modules,比如modules的路徑,依賴關係等,在匯入原始碼工程是,可以編輯該檔案,排除一些不使用的目錄檔案,這樣匯入會快很多,因為原始碼檔案實在是太多了,全部匯入,要花很長時間,可以排除的檔案為目錄為(我的機器的的配置):
<excludeFolder url="file://$MODULE_DIR$/.repo" /> <excludeFolder url="file://$MODULE_DIR$/external" /> <excludeFolder url="file://$MODULE_DIR$/external/bluetooth" /> <excludeFolder url="file://$MODULE_DIR$/external/chromium" /> <excludeFolder url="file://$MODULE_DIR$/external/emma" /> <excludeFolder url="file://$MODULE_DIR$/external/icu4c" /> <excludeFolder url="file://$MODULE_DIR$/external/jdiff" /> <excludeFolder url="file://$MODULE_DIR$/external/webkit" /> <excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" /> <excludeFolder url="file://$MODULE_DIR$/out/eclipse" /> <excludeFolder url="file://$MODULE_DIR$/out/host" /> <excludeFolder url="file://$MODULE_DIR$/out/target/common/docs" /> <excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates" /> <excludeFolder url="file://$MODULE_DIR$/out/target/product" /> <excludeFolder url="file://$MODULE_DIR$/prebuilt" /> <excludeFolder url="file://$MODULE_DIR$/abi" /> <excludeFolder url="file://$MODULE_DIR$/art" /> <excludeFolder url="file://$MODULE_DIR$/bionic" /> <excludeFolder url="file://$MODULE_DIR$/bootable" /> <excludeFolder url="file://$MODULE_DIR$/build" /> <excludeFolder url="file://$MODULE_DIR$/cts" /> <excludeFolder url="file://$MODULE_DIR$/dalvik" /> <excludeFolder url="file://$MODULE_DIR$/developers" /> <excludeFolder url="file://$MODULE_DIR$/development" /> <excludeFolder url="file://$MODULE_DIR$/device" /> <excludeFolder url="file://$MODULE_DIR$/docs" /> <excludeFolder url="file://$MODULE_DIR$/external" /> <excludeFolder url="file://$MODULE_DIR$/hardware" /> <excludeFolder url="file://$MODULE_DIR$/libcore" /> <excludeFolder url="file://$MODULE_DIR$/libnativehelper" /> <excludeFolder url="file://$MODULE_DIR$/ndk" /> <excludeFolder url="file://$MODULE_DIR$/out" /> <excludeFolder url="file://$MODULE_DIR$/pdk" /> <excludeFolder url="file://$MODULE_DIR$/prebuilt" /> <excludeFolder url="file://$MODULE_DIR$/prebuilts" /> <excludeFolder url="file://$MODULE_DIR$/sdk" /> <excludeFolder url="file://$MODULE_DIR$/system" />
只保留 framework(我們要除錯的大部分程式碼就在該包下)和package 系統自帶應用
然後:開啟Android Studio,點選File->Open,選擇剛才生成的android.ipr,等待匯入完成
匯入完成後,如果Android studio scanning file into index 每隔幾秒就執行一次,需要在android.iml 的
faceset 節點的 <configuration >裡下加入:
<option name="ALLOW_USER_CONFIGURATION" value="false" />
。。。。當匯入完成後還需要設定系統JDK和SDK等配置資訊,以便關聯原始碼和跳轉等
設定完成後,可以試著對系統應用進行除錯.此時系統應用都已經啟動,在程序列表裡直接選定某一個程序就可以除錯了,但是如何除錯system_process 程序呢?因為模擬器啟動後, system_process程序已經啟動了,如何再去斷點除錯呢?能不能讓system_process的開機的時候暫停了,或者說是等待偵錯程式連結,這樣我們就有機會進行除錯呢?先看個日誌資訊:
08-05 15:40:06.791 1550-1550/? I/System.out: Sending WAIT chunk
08-05 15:40:11.950 1550-1556/system_process I/zygote64: Debugger is active
08-05 15:40:12.003 1550-1550/system_process I/System.out: Debugger has connected
08-05 15:40:12.004 1550-1550/system_process I/System.out: waiting for debugger to settle...
08-05 15:40:13.205 1550-1550/system_process I/chatty: uid=1000 system_server identical 6 lines
08-05 15:40:13.405 1550-1550/system_process I/System.out: waiting for debugger to settle...
08-05 15:40:13.606 1550-1550/system_process I/System.out: debugger has settled (1441)
08-05 15:40:13.606 1550-1550/system_process W/zygote64: Got a deoptimization request on un-deoptimizable void android.os.Debug.waitForDebugger() at PC 0x728c321eb4ee
08-05 15:40:26.876 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:41:26.877 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:42:26.877 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:43:26.877 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:44:26.877 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:45:26.878 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:46:26.878 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:47:26.878 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:48:26.879 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:49:26.879 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:50:26.879 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:51:26.879 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:52:26.879 1383-1383/? I/qemu-props: skip starting adbd ...
08-05 15:53:26.880 1383-1383/? I/qemu-props: skip starting adbd ...
在我編輯文件 的時候,一直在等待連線偵錯程式,每分鐘檢查一次,我的除錯面板裡的程序:
⚠️注意:上面情況是我經過調整原始碼後的重新編譯才會出現的情況,正常情況啟動模擬器,是不是一隻等待除錯的!
如何開機除錯
正常情況下,如果不是開機除錯,則程序選擇面板裡,應該包含除了system_process程序之外的所有其他程序,包括Launcher, contact,calendar 等等程序,
現在我是處於開機除錯狀態,已經在system_process程序所在的SystemServer的 run()方法斷點,所有其他程序都必須等待system_process程序啟動完成之後再開始,system_process程序要啟動很多系統依賴的服務程序
我的模擬器也一直停留在開機狀態:
如何讓模擬器停在開機狀態呢?答案在於如何能讓模擬器等待連線偵錯程式,當模擬器連線上偵錯程式後,我們再下斷點,自然就可以斷點system_process程序了,system_process程序的程式碼SystemServer.
sytem_process程序有Zygote程序啟動,就是通過main()方法啟動的:
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
在 new SystemServer().run()方法的上面我麼可以加上下面這段程式碼:
java.io.File f = new java.io.File("/system/debug");
if(f.exists()){
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
android.os.Debug.waitForDebugger();
}
- 首先通過判斷/system/debug是否存在來判斷是否要等待偵錯程式連線.
- android.os.Debug.waitForDebugger()就是等待偵錯程式來連線,在偵錯程式連線上之前程式碼不會往下執行.
- 但是第一行程式碼就比較費解了,先來解析下什麼叫ddm,ddm就是Dalvik Debug Monitor的縮寫.
- android.ddm.DdmHandleAppName.setAppName就是要設定Java App在ddm裡的名稱.
如果不設定的話,你在DDMS裡看到的Name一欄就會有一個“?”,這個時候,eclipse找不到對應的工程,所以就沒法除錯了。
修改好原始碼後,重新編譯(需要等待2-3個小時,取決於你的機器的配置),最後還要說名一點,你需要在/system/ 目錄下建立對應的檔案debug,模擬器啟動後,預設是/system/是read-only 的,你無法修改和寫入,注意,啟動的時候,使用下面的啟動方式:
~/WORKING_DIRECTORY$ emulator -writable-system
啟動後,通過adb shell 進入模擬器,在模擬期的/system 目錄下建立debug檔案,然後用相同的方式重啟模擬器,就可以進行system_process的啟動除錯了!
參考連結: