DockerでUbuntu22(arm64)の環境を実行する必要があったのですが、Segmentation faultで数日悩まされた結果、回避方法が見つかったので共有。
どうもDockerに限らず、Qemuのコマンドqemu-aarch64-staticを使っていると起こることがあるようです。
(Dockerはqemu使って別アーキテクチャのイメージを実行してるっぽいので)
# エラー内容
Dockerでarm64v8/ubuntuを実行したときのエラー
PS D:\tmp> docker run -it arm64v8/ubuntu:latest /bin/bash
root@xxx:/# ldconfig
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault
root@xxx:/#
ldconfigコマンドを実行したら発生するのですが、困ったことにapt-getで何らかのパッケージをインストールすると、多くの場合はlibc-binのトリガーが発動し、内部でldconfigを実行してしまうため、結果的にapt-getコマンドが使い物になりません。
root@xxx:/# apt-get update && apt-get install -y curl
Get:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease [270 kB]
:
Processing triggers for libc-bin (2.35-0ubuntu3.6) ...
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Segmentation fault
dpkg: error processing package libc-bin (--configure):
installed libc-bin package post-installation script subprocess returned error exit status 139
:
Running hooks in /etc/ca-certificates/update.d...
done.
Errors were encountered while processing:
libc-bin
E: Sub-process /usr/bin/dpkg returned an error code (1)
aptもapt-getも失敗に終わるので、Dockerfileでなにかパッケージを入れるコマンドはエラーを無視する必要が出ちゃいます。
# 回避法1(apt使うだけなら)
libc-binのトリガーを無効化すればとりあえずaptを使えるようになります。
無効化する方法はいろいろあるようですが、最も簡単なのは/var/lib/dpkg/triggersにあるファイルを削除すること。
root@xxx:/# cat /var/lib/dpkg/triggers/ldconfig
libc-bin
root@xxx:/# rm -f /var/lib/dpkg/triggers/ldconfig
これでapt-getにてlibc-binのトリガーが実行されないため、apt-getも成功します。
でもldconfigコマンドが使えないままなので、ライブラリとかインストールした後に共有ライブラリのリンク等がうまくできない可能性があります。
# 回避法2(ldconfigの実行が必要なら)
ldconfigを使えるようにするためには、ちょっと/sbin/ldconfigのスクリプトを書き変える必要がありました。
root@xxx:/# cat `which ldconfig`
#!/bin/sh
:
exec /sbin/ldconfig.real "$@"
上記のexec /sbin/ldconfig.realの部分を、exec /qemu-aarch64-static /sbin/ldconfig.realに書き換えます。
root@xxx:/# sed -i.bak -e "s%/sbin/ldconfig%/qemu-aarch64-static /sbin/ldconfig%" /usr/sbin/ldconfig
root@xxx:/# cat /usr/sbin/ldconfig
#!/bin/sh
:
exec /qemu-aarch64-static /sbin/ldconfig.real "$@"
/qemu-aarch64-staticは、必要に応じてダウンロードしてきて配置してください。
dockerのホスト環境でダウンロードしてdocker cpしてもいいですし、コンテナ内でダウンロードする場合は、一時的に回避法1を利用して、wgetをインストールしてダウンロードすれば良いです。
# 補足
似たようなIssueが以前上がっていたようなのですが、私が使っている環境ではこの問題は修正済みでした。なのでこれとは関係なさそうです。
WSL上でubuntu22(arm64)のルートファイルシステムにchroot&qemu-aarch64-staticしても、ldconfigで同じくエラーになりました。
Docker上でx86_64ネイティブのコンテナを立ち上げて、同様にubuntu22(arm64)のルートファイルシステムにchroot&qemu-aarch64-staticしても同様。
# 最後に
あくまで回避法なので、早いところ問題が正式に改善されるといいですね。