みつきんのメモ

組み込みエンジニアです。Interface誌で「My オリジナルLinuxの作り方」連載中

Yocto Chromiumをビルドする時に何回やってもリンカでSegmentation faultする時の対応

はじめに

YoctoでChromiumをビルドする時に下記のようにエラーで終了する。

... (snip) ...

nterface.o
| ninja: build stopped: subcommand failed.
| WARNING: exit code 1 from a shell command.
| 
ERROR: Task (/home/mickey/work/yocto/rpi-gatesgarth/poky/meta-browser/meta-chromium/recipes-browser/chromium/chromium-x11_89.0.4389.90.bb:do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 3513 tasks of which 3512 didn't need to be rerun and 1 failed.

Summary: 1 task failed:
  /home/mickey/work/yocto/rpi-gatesgarth/poky/meta-browser/meta-chromium/recipes-browser/chromium/chromium-x11_89.0.4389.90.bb:do_compile
Summary: There was 1 ERROR message shown, returning a non-zero exit code

試しにリトライしても、meta-clangのブランチを変えても、キャッシュを消しても同じところでエラーになる。

エラーの詳細を調べる

ログファイルの特定

こういうケースではどのログファイルを参照するかをまず、調べる必要がある。そのためにtmp/log/cooker/raspberrypi4-64/console-latest.logを参照する。

このファイルの末尾の方に下記のようにエラーが起きているタスクのログファイルのフルパスが表示されている。

ERROR: Logfile of failure stored in: /home/mickey/work/yocto/rpi-gatesgarth/build_kiosk/tmp/work/cortexa72-poky-linux/chromium-x11/89.0.4389.90-r0/temp/log.do_compile.3513135
NOTE: recipe chromium-x11-89.0.4389.90-r0: task do_compile: Failed
ERROR: Task (/home/mickey/work/yocto/rpi-gatesgarth/poky/meta-browser/meta-chromium/recipes-browser/chromium/chromium-x11_89.0.4389.90.bb:do_compile) failed with exit code '1'
NOTE: Tasks Summary: Attempted 3513 tasks of which 3512 didn't need to be rerun and 1 failed.

log.do_compile.3513135である。最後の数字は実行時のプロセスIDとなっている。

ログファイルの調査

errorの文字列でログファイルを検索していくと下記のようなエラーがメッセージが見つかる。

これはmeta-clangがgatesgarthブランチ時のログ

clang-11: error: unable to execute command: Segmentation fault (core dumped)
clang-11: error: linker command failed due to signal (use -v to see invocation)

つぎのmeta-clangがmasterブランチの時のログ。

clang-12: error: unable to execute command: Segmentation fault (core dumped)
clang-12: error: linker command failed due to signal (use -v to see invocation)

つまり同じところ、それもリンカ実行時にエラーが起きている。

リンカについての調査

リンカに問題がありそうということでコンパイル時にどのリンカが使用されているか、ログファイルを検索する。

python "../../build/toolchain/gcc_solink_wrapper.py" --readelf="aarch64-poky-linux-readelf" --nm="aarch64-poky-linux-llvm-nm"  --sofile="./libGLESv2.so" --tocfile="./libGLESv2.so.TOC" --output="./libGLESv2.so" -- aarch64-poky-linux-clang++ -target aarch64-poky-linux  -mcpu=cortex-a72 -march=armv8-a+crc+crypto   -mlittle-endian -Qunused-arguments -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security --sysroot=/home/mickey/work/yocto/rpi-gatesgarth/build_kiosk/tmp/work/cortexa72-poky-linux/chromium-x11/89.0.4389.90-r0/recipe-sysroot -shared -Wl,-soname="libGLESv2.so" -Wl,--fatal-warnings -Wl,--build-id=sha1 -fPIC -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,-z,defs -Wl,--as-needed -fuse-ld=gold -Wl,--threads -Wl,--thread-count=4 -Wl,--icf=all -Wl,-O2 -Wl,--gc-sections -rdynamic -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-z,relro,-z,now -o "./libGLESv2.so" @"./libGLESv2.so.rsp"

-fuse-ld=goldということでgoldが使用されているようだ。

meta-chromiumgrepすると下記のような行が見つかる。

# by using the ld-is-lld distro feature otherwise use gold linker
GN_ARGS += "${@bb.utils.contains('DISTRO_FEATURES', 'ld-is-lld', 'use_lld=true use_gold=false', 'use_lld=false use_gold=true', d)}

これによるとDISTRO_FEATURESls-is-lldを追加する音でgoldの代わりにlldを使用するようになるらしい。

local.confの修正

conf/local.confに下記のように追加する。

IMAGE_INSTALL_append = " chromium-x11"
BBMASK += "meta-clang/recipes-core/busybox/busybox_1.33%.bbappend"
DISTRO_FEATURES_append = " ld-is-lld"

BBMASKはmeta-clangをmasterブランチで使用する時に発生するエラーを回避している。gatesgarthでは不要。

最終的に使用したレイヤの情報

こういう情報もcosole-latest.logに残っている。

Build Configuration:
BB_VERSION           = "1.48.0"
BUILD_SYS            = "x86_64-linux"
NATIVELSBSTRING      = "universal"
TARGET_SYS           = "aarch64-poky-linux"
MACHINE              = "raspberrypi4-64"
DISTRO               = "poky"
DISTRO_VERSION       = "3.2.2"
TUNE_FEATURES        = "aarch64 armv8a crc crypto cortexa72"
TARGET_FPU           = ""
meta                 
meta-poky            
meta-yocto-bsp       = "gatesgarth:6ed895d2b2d0dd5e5c85851c082954f5bb0294a0"
meta-oe              = "gatesgarth:945f062ff098dc9c8ba8d22c5eef88adec60730d"
meta-clang           = "master:404e8129c26ea5387a51248eebff1820db6f5015"
meta-python2         = "gatesgarth:56288c2599d7a6df6e34e8b07b7dc3d4d2d71e30"
meta-chromium        = "master:d6b1385daf2fd9178ba7bed5ba1eb909e47e8347"
meta-raspberrypi     = "gatesgarth:3ae135e590e375c8da26b003bda41c18fb977ae1"

おそらくmeta-clangはgatesgarthでも良い気がする。

meta-browserについて

もともとchromiumのレシピはmeta-browserのは以下にあったが、つい最近meta-firefoxとmeta-chromiumに分離されたようだ。 どちらも巨大だし依存関係も異なっているので、別々に管理するのは賛成。

その都合上2021/03/25前後ではbitbake-layers layerindex-fetchが使えない。

まとめ

Yoctoでchromiumをビルドする際にはDISTRO_FEATURES_append = " ld-is-lld"は必須。

最近meta-chromiumとmeta-firefoxに分離した。

chromiumのビルドだけで数時間はかかるのでエラーが出るとしんどい。

エラー時の解析にはconsole-latest.logを最初に参照すると便利。