[What]Yocto Project --> 问题排查

参考书籍:Embedded Linux System with the Yocto Project

  • 书籍比实际的yocto版本要低,所以yocto的详细命令需要参考其对应版本手册

运行环境:

  • ubuntu18.04 amd64
  • yocto 2.5.1

整理在遇到问题时该如何排查。

日志

bitbake 会将以下信息写入日志文件:

  • 在可执行 metadata 中的调试信息
  • 任务或其它代码执行过程中的输出
  • 任务或其他代码执行过程中的错误输出
    • 在构建过程中,有错误或警告也会在 shell 中直接给出

日志文件

日志文件默认存放位置:

LOG_DIR = "${TMPDIR}/log"

在此文件夹的 cooker 中,会根据目标机架构的不同进行细分为多个文件夹。

  • 文件是以 UTC 时间为名称(这是为了不同时区的远程协作)

这里面有一个 console-latest.log 用于标记在控制台的输出:

WARNING: Host distribution "ubuntu-18.04" has not been validated with this version of the build system; you may possibly experience unexpected failures. It is recommended that you use a tested distribution.
NOTE: Resolving any missing task queue dependencies

Build Configuration:
# bitbake 的版本号
BB_VERSION           = "1.38.0"
# 构建目标板的主机系统
BUILD_SYS            = "x86_64-linux"
# 构建 ID
NATIVELSBSTRING      = "universal"
# 目标板系统
TARGET_SYS           = "i586-poky-linux"
# 目标板架构
MACHINE              = "qemux86"
# 发行版名称
DISTRO               = "poky"
# 发行版版本
DISTRO_VERSION       = "2.5.1"
# 目标架构更细节参数
TUNE_FEATURES        = "m32 i586"
# 是否包含 FPU 单元
TARGET_FPU           = ""
# 分支及其 commit id
meta                 
meta-poky            
meta-yocto-bsp       
meta-nano            = "learn:51872d3f99e38f9d883ab0a8782ceecb41822fd0"

NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 6129 tasks of which 6129 didn't need to be rerun and all succeeded.

对于在构建过程中,如果某个任务出现了错误,会在控制台提示错误信息,并且更详细的信息也会写入其提示的路径中。

使用日志调试输出

bitbake 提供了一些日志输出方法,便于 recipe 的调试:

  • plain:最为平常的输出,不会在控制台输出
    • python : bb.plain("plain message")
    • shell : bbplain <message>
  • debug:带等级输出(1~3)
    • bitbake 在启动时设置默认等级,debug 只有大于或等于此等级时才在控制台输出
      • bitbake -D <target> : 等级1
      • bitbake -DD <target> : 等级2
      • bitbake -DDD <target> : 等级3
    • python : bb.debug(1, "hello world")
    • shell : bbdebug <level> <message>
  • note:用于提示信息输出,会在控制台输出
    • python : bb.note("note message")
    • shell : bbnote <message>
  • warn:警告信息,会在控制台输出,bitbake 并不会停止构建
    • python : bb.warn("warning")
    • shell : bbwarn <message>
  • error:错误信息,会在控制台输出,bitbake 并不会停止构建
    • python : bb.error("error message")
    • shell : bberror <message>
  • fatal:严重错误,会在控制台输出,bitbake 会停止构建
    • python : bb.fatal("fatal message")
    • shell : bbfatal <message>

错误提示使用 warnerror 就可以了,这可以保证在显示错误的同时其他 task 依然可以运行。

查看日志过程

在每个 recipe 的构建输出目录中,都有一个 temp 文件夹。

里面包含 log.do_xxxrun.do_xxx 文件,分别表示日志输出和实际的运行脚本,从这里可以看到详细的构建过程。

任务执行

查看

当不确定一个 recipe 将要被执行哪些任务时,可以使用命令 listtasks 来查看:

  • bitbake <recipe name> -c listtasks

但是这个输出并没有按照执行顺序而标记出来,对于执行顺序,可以使用 grep 截取 addtask 关键词:

cec@box:~/github/poky/meta/classes$ grep "addtask" ./base.bbclass -r -n
134:addtask fetch
152:addtask unpack after do_fetch
296:addtask configure after do_patch
315:addtask compile after do_configure
325:addtask install after do_compile
338:addtask build after do_populate_sysroot
683:addtask cleansstate after do_clean
687:addtask cleanall after do_cleansstate

执行指定任务

当执行一个 recipe 的过程中出现错误后,需要对应修改某部分,然后可以只执行对应任务来快速验证。

  • bitbake <recipe name> -c <task name>
#仅执行 compile 任务
bitbake busybox -c compile

执行输出脚本

bitbake 会将运行过的命令存在文件中,这样可以检查执行顺序是否正常。

这些文件和任务日志文件都存在变量 T 所制定的位置:

T = "${WORKDIR}/temp"

文件名称是 run.do_<taskname>.<pid>

  • 文件如果不带 pid ,则是另一个文件的符号链接
  • lod.task_order 文件列出了最近被执行过的任务

元数据分析

除了上面说的查看 recipe 的任务,还可以查看当前构建环境所使用的变量的值:

# 输出 bitbake 默认的环境变量设置
bitbake -e > <file>
# 输出对应 recipe 的设置
bitbake -e <recipe> > <file>

上面之所以要将输出定向到文件,是因为其输出实在是太多了,不仅仅输出变量还会输出功能函数。

为了只输出环境变量,可以将下面这个 task 加入一个 class 文件:

addtask	showvars
do_showvars[nostamp]	=	“1”
python	do_showvars()	{
                #	emit	only	the	metadata	that	are	variables	and	not	functions
                isfunc	=	lambda	key:	bool(d.getVarFlag(key,	‘func’))
                vars	=	sorted((key	for	keyin	bb.data.keys(d)	\
                            if	not	key.startswith(‘__’)))
                for	var	in	vars:
                        if	notisfunc(var):
                            try:
                            val	=	d.getVar(var,	True)
                            except	Exception	as	exc:
                            bb.plain(‘Expansion	of	%s	threw	%s:	%s’	%	\
                            (var,	exc.__class__.__name__,	str(exc)))
                            bb.plain(‘%s=”%s”’	%	(var,	val))
}

使用下面命令:

bitbake <recipe> -c showvars

开发环境的 shell

在 bitbake 构建过程中,会创建一个交叉编译环境(沙盒)。

在确保已经安装 tmux 后,就可以启动沙盒:

bitbake <target> -c devshell

在此环境中就包含了构建过程中的工具炼可使用。

图形化依赖显示

bitbake 可以生成 DOT 文件让 graphviz 图形化解析:

# 生成所有依赖
bitbake -g <recipe / target>

# 生成依赖并忽略某个包
bitbake -g <target> -I <ignore_recipe>

# 直接生成自带的图形化依赖
bitbake -g -u taskexp <recipe / target>

会生成以下依赖文件:

  • pn-buildlist:这不是 DOT 文件,但是描述了构建过程中调用包的顺序
  • pn-depends.dot :包依赖
  • package-depends.dot : 与 pn-depends.dot 一样,只是更易于观看
  • task-depends.dot:任务依赖
# 精简输出
tred recipe-depends.dot > recipe-depends-notrans.dot

# 生成图片
dot -Tpng recipe-depends-notrans.png recipe-depends-notrans.dot

调试层

bitbake-layers 提供了分析层的方法:

  • bitbake-layers show-layers :当前构建环境所使用的层
  • bitbake-layers show-recipes:当前构建环境所使用的 recipe
  • bitbake-layers show-overlayed:显示哪些 recipe 被其它 recipe 所覆盖
  • bitbake-layers show-appends:显示哪些 recipe 具有附加文件
  • bitbake-layers show-cross-depends:recipe 的依赖关系
  • bitbaky-layers flatten <dir>:将层扁平化输出到文件夹

清除构建输出

在修改了 recipe 后,务必运行清除命令后再构建:

# 清除构建输出和缓存文件
bitbake -c cleansstate <recipe_name>
bitbake <recipe_name>
Last Updated 2019-10-13 日 16:28.
Render by hexo-renderer-org with Emacs 26.1 (Org mode 9.1.14)