前言
OpenAtom OpenHarmony(简称“OpenHarmony”)适配新的开发板时,启动流程init大概率会出现问题,其为内核直接拉起的第一个用户态进程,问题定位手段只能依赖代码走读和增加调试打印,初始化过程中系统崩溃的问题就更难定位了。如果能使用gdb调试init,会极大提高定位效率。本文将详细阐释二次启动的标准系统如何使用gdb调试init。
1. 编译出带debug信息的调试版本
将gdb打包到系统镜像中。init不正常的情况下,系统无法正常启动工作,无法使用hdc工具加载gdb工具,所以直接在制作镜像时,将其打包到系统镜像bin目录下。修改device\board\hihope\rk3568\cfg\BUILD.gn打包脚本如下,注意保证gdb工具已放置在此本目录下。
2. 调试版本镜像带符号,需要修改镜像配置文件,修改其大小限制,尤其是system.img,编译失败时不会提示实际镜像大小,需要修改到5G以上。
3. 编译调试版本,打开版本调试开关
./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处。
注意:A处的CloseStdio()需要注释掉。
考虑用gdb启动init第二阶段,init绝大部分处理流程都在这一阶段,从这里开始就可以用gdb调试了,init第一阶段处理相对而言流程简单一些,代码走读和调试打印基本就能解决问题。
在init主函数中去掉“不等于进程1就返回的处理”,因为用gdb起init第二阶段时,其进程非1。
init进程中不初始化Paramworkspace,前面pid=1的判断,在gdb调试init时条件不成立,所以此处增加判断init名就直接退出的处理。
做好了上述准备,就可以用gdb调试init:
把系统启动,改造后的init初始化第一阶段完成后,会停在shell下,此时使用下述命令启动init第二阶段:
gdb --args /bin/init --second-stage
为了调试init的子进程,还需要gdb下述命令
set follow-fork-mode child
总结
本文章针对OpenHarmony系统在调试init初始化流程时,缺少高效的问题定位手段这一痛点,引入了嵌入式系统开发的主流调试工具——gdb,详细描述了这一方法涉及到的版本编译、适配点修改以及调试命令操作等细节处理,指导开发者提高定位init问题的效率。
需要注意,当前gdb调试init方法有局限,不适用轻量级系统、小型系统和一次启动的标准系统。
为了帮助到大家能够更有效的学习OpenHarmony 开发的内容,下面特别准备了一些相关的参考学习资料:
OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy
《OpenHarmony源码解析》:https://qr18.cn/CgxrRy
- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……
系统架构分析:https://qr18.cn/CgxrRy
- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……