OpenHarmony系統使用gdb除錯init

OpenHarmony開發者發表於2023-01-10

前言

OpenAtom OpenHarmony(簡稱“OpenHarmony”)適配新的開發板時,啟動流程init大機率會出現問題,其為核心直接拉起的第一個使用者態程式,問題定位手段只能依賴程式碼走讀和增加除錯列印,初始化過程中系統崩潰的問題就更難定位了。如果能使用gdb除錯init,會極大提高定位效率。本文將詳細闡釋二次啟動的標準系統如何使用gdb除錯init。

1. 編譯出帶debug資訊的除錯版本

將gdb打包到系統映象中。init不正常的情況下,系統無法正常啟動工作,無法使用hdc工具載入gdb工具,所以直接在製作映象時,將其打包到系統映象bin目錄下。修改device\board\hihope\rk3568\cfg\BUILD.gn打包指令碼如下,注意保證gdb工具已放置在此本目錄下。

圖片

  1. 除錯版本映象帶符號,需要修改映象配置檔案,修改其大小限制,尤其是system.img,編譯失敗時不會提示實際映象大小,需要修改到5G以上。

圖片

  1. 編譯除錯版本,開啟版本除錯開關

./build.sh --product-name=XXX --gn-args="is_debug=true use_unstripped_as_runtime_outputs=true"

上述debug版本只能除錯普通功能而不能除錯init,還需要對init服務的原始碼進行部分適配修改,init功能除錯正常後,需將原始碼恢復。

首先,在init掛載好system、vendor等映象,並將根目錄切換到system映象後,在啟動第二階段init時,切換到shell下,停止init初始化流程,見下圖B處。原始碼詳見base\startup\init\ services\init\standard\init.c。

圖片

注意:A處的CloseStdio()需要註釋掉。

考慮用gdb啟動init第二階段,init絕大部分處理流程都在這一階段,從這裡開始就可以用gdb除錯了,init第一階段處理相對而言流程簡單一些,程式碼走讀和除錯列印基本就能解決問題。

在init主函式中去掉“不等於程式1就返回的處理”,因為用gdb起init第二階段時,其程式非1。原始碼詳見base\startup\init\services\init\main.c。

圖片

init程式中不初始化Paramworkspace,前面pid=1的判斷,在gdb除錯init時條件不成立,所以此處增加判斷init名就直接退出的處理。原始碼詳見base\startup\init\services\param\base\param_base.c。

圖片

做好了上述準備,就可以用gdb除錯init:

把系統啟動,改造後的init初始化第一階段完成後,會停在shell下,此時使用下述命令啟動init第二階段:

gdb --args /bin/init --second-stage

為了除錯init的子程式,還需要gdb下述命令

set follow-fork-mode child

圖片

總結

本文章針對OpenHarmony系統在除錯init初始化流程時,缺少高效的問題定位手段這一痛點,引入了嵌入式系統開發的主流除錯工具——gdb,詳細描述了這一方法涉及到的版本編譯、適配點修改以及除錯命令操作等細節處理,指導開發者提高定位init問題的效率。

需要注意,當前gdb除錯init方法有侷限,不適用輕量級系統、小型系統和一次啟動的標準系統。

圖片

相關文章