Solaris の elf_find_sym で動的ロードで2012年01月07日 12時44分07秒

Solaris で elf_find_sym が SIGSEGV を起こして、プログラムが止まってしまう。何と古来からある標準 C ライブラリ関数を呼び出そうとしている時に、プログラムが落ちる。全ての環境で起きるわけでもなく、特定のバイナリのみで起きる。取り敢えず、見つけたことをまとめてみた。今回の場合は、strtok を呼び出す瞬間に落ちるので、かなり厄介だ。

Solaris ではバイナリの実行中に呼び出す関数がまだ組み込まれていなければ、 elf_find_sym を通して関数をロードして行く。libc 等は、共有ライブラリとして、リンクされているので典型的な例だ。nm で実行ファイルを調べると、strtok を参照しているのが分る。ldd では、libc を必要としているのが判る。

elf_find_sym 関数内で落ちるので、デバッガでブレイクポイントを仕掛けて、幾つも観察しているとやはり、プログラムの実行を初めてから最初の関数呼び出しのときに、呼び出され共有ライブラリから関数を読みだしているのが確認できた。つまり、プログラム起動時に、全てのシンボルを読み込んでおくのではなく、必要になるたびに、随時読み込んでいく遅延方式になる。

コンパイル時には、何のエラーもない。また、リンク時にも問題はない。実行時に関数を呼び出そうとしている時に問題があるので、ldd などの動的ロード関連かとは思うのだが、調べても有効なものが見付からず困っていた。Solaris のバグだとは思うのだが、確証が掴めず取り敢えずのところは別の実装を静的に組み込むことで回避した。三ヵ月ぐらい放置したところで、再度試したところ再現しなくなっていたのだが…。