🦀
Homebrew経由で入れたbinutilsを使ってビルドスクリプトを使うようなcargo build --releaseをするとSIGKILLが出て死ぬ
#tech
2024-06-29
タイトルの通り.Homebrew経由で入れたbinutils
を使ってcargo build --release
するとbuild-script-build
でSIGKILL
が出る.cargo build
すると正常に通る.
M1 MAXが載ったmacでやっていたのでチップの問題を疑ったが,原因はbinutils
をどう入れているかに起因したという話.
セキュリティ・キャンプ2024 全国大会 OS自作ゼミで,ひとまず以前作成したRISC-V 32bit向けRust製カーネルを64bitにしていくことになった.それ自体は割とすぐできたが,その後のユーザーランドを追加する部分でこの問題が発生した.まずは当時の状態を貼る:
この後の説明に必要な部分だけ説明すると,ディレクトリ構造が次のようになっていて,
$ tree -L 2 -d
.
├── kernel
│ ├── src
│ └── target
└── user
├── src
└── target
6 directories
kernel
にはカーネルのソースコード,user
にはユーザーランドのソースコードを入れている.ビルド手順はMakefile.toml
に定義されているrun
というジョブにあるが,大雑把に言うとuser
をビルドしてそのバイナリをkernel
にリンクさせる形式でkernel
をビルドする.この際にkernel
に入ってcargo build --release
するとSIGKILL
が起こって死ぬ問題が発生した.
様子
ここでbuild-script-build
内でSIGKILL
が起こっていることは分かるのでとりあえず雑にこのバイナリに対してfile
とかotool
とかを刺してみるが有用っぽい情報は得られなかった.
「きびし~」と思って試しにcargo build
すると,これは通る.あと普段のこのOSの開発はWSL2上でやっているのだが,こちらだとどちらのビルドも通る.少し調べたがエスカレしておいて良さそうと思ったので,セキュキャンのDiscordサーバーで講師にエスカレした(見ていただいてありがとうございます...).
一緒に調査したところ,まずlldb
を刺してみると良いのではという話になり,lldb
でrun
してみた.その様子がこちら:
lldbを刺した様子
"Malformed Mach-O file"と宣っている.普通にビルドしただけなのにMalformedとか言われるの大分心外だが!?みたいな気持ちになり,なる.皆さんも同じ状況ならなると思います.
ここから調査すると,次のようなIssueが見つかった:
どうやらbinutils
をHomebrew経由で入れると,中に入っているstripが壊れていてMalformedなMach-Oになるらしい.確かにそれならreleaseビルドでだけ死ぬのも納得だが,だが...
で,更に調査するとHomebrew経由のbinutils
と使ってビルドしたものとMacにデフォルトで入っているbinutils
系のコマンドを使ってビルドしたものではMach-Oのバージョンが異なるので,binutils
側が追従できていないんだろうなあの気持ちになる(前者が2,後者が1).
ということでbrew uninstall binutils
をしてビルドして難を逃れている.上で挙げたIssueはどれも"Homebrew経由で入れるの止めようね!笑"でcloseされているのできびしい気持ちにはなる.