ld-elf.soに怒られた
症状
freebsd-updateした環境で、一部の実行ファイルが動作しませんでした。
ffmpegの場合。
$ ffmpeg
ld-elf.so.1: /usr/local/lib/libvmaf.so.3: Undefined symbol "_ZTTNSt3__114basic_ifstreamIcNS_11char_traitsIcEEEE"
ccの場合。
$ type cc
/usr/bin/cc
$ cc -v
ld-elf.so.1: Undefined symbol "_ZTVNSt3__118basic_stringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEE" referenced from COPY relocation in /usr/bin/cc
ffmpegならともかく、/usr/bin/ccが動かないのはなかなかです。
対処
わたしの場合、以下のファイルを参照できないようにしたら動作するようになりました。
$ ll /lib/libc++.so*
lrwxr-xr-x 1 root wheel 11B Nov 24 2013 /lib/libc++.so@ -> libc++.so.1
-rwxr-xr-x 1 root wheel 868K Nov 24 2013 /lib/libc++.so.1*
ふ、古い・・・いかにも怪しいですね
# mv /lib/libc++.so /lib/libc++.so.del
# mv /lib/libc++.so.1 /lib/libc++.so.1.del
結果
やりました。
$ ffmpeg
ffmpeg version 6.1.2 Copyright (c) 2000-2024 the FFmpeg developers
built with FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2e05e67)
(以下略)
$ cc -v
FreeBSD clang version 18.1.6 (https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2e05e67)
Target: i386-unknown-freebsd13.4
Thread model: posix
InstalledDir: /usr/bin
説明
環境
2013年のライブラリが残っていたのは、わたしのPCが10.x->11.4へfreebsd-updateしたのち、長いことそのまま運用していたからなのです。(もしかしたら最初は9系だったかも・・・)
そろそろupgradeでもするかぁと12.4に上げたら、12.4もとっくにEOLになっていてpkg updateできず、13.4に上げた次第です。
(もちろん反省しております・・・)
デバッグ
/usr/bin/ccの由来を実はわかってなかったのですが、FreeBSDの場合/usr/bin以下など基本的なファイルセットは"base.txz"(以下にアーキテクチャ・バージョンごとに置いてある)から展開されるものなのだそうです。
そこで、base.txzを入手し、一時ディレクトリに展開後chrootした環境でcc -vしてみると動く。
一時展開したファイルと、"/" 以下のファイルをcmpで比較したら一部ファイル(ライブラリ含む)で差異があったので、ちょっと乱暴ですが"/" にetc以外を展開してみましたがそうするとcc -vはエラー終了します。(Undefined symbolを喰らいます)
なにか余計なファイルが邪魔していることはほぼ確定です。
そこでお邪魔虫を探すために、chrootして動く環境と、chrootしてない不動環境それぞれで
# truss cc -v
を実行し、openしているライブラリの差分を確認すると、動かない方では余計なファイル(/lib/libc++.so)を触りに行ってることを確認しました。
動かない環境では、
open("/lib/libc++.so.1",O_RDONLY|O_CLOEXEC|O_VERIFY,06) = 3 (0x3)
とOPEN成功していますが、chrootした動く環境には当該ファイルはなくて、
open("/lib/libc++.so.1",O_RDONLY|O_CLOEXEC|O_VERIFY,06) ERR#2 'No such file or directory'
になってます。(ちなみに新しいlibc++.soは/usr/lib以下にあります)
お作法的にこの対応では色々まずいのだろうとは思いますが、ひとまず手っ取り早く動かすようにはできました。
initやsshdなど、重要プロセスでこのエラーくらわずよかったです。 /usr/sbinや/usr/bin以下はstaticなバイナリのほうが安全かもと思った次第・・・。