カテゴリ:ソフト開発日誌
busybox を glibc 2.9 でコンパイルすると busybox がまともに動作せず segmentation fault (SIGSEGV) で動作しない問題を探っていた。init や login が動作しないので、使い物にならない状態だった。
Read this page in English. glibc の vfprintf() の実体 __vfprintf_chk() の実装に問題が有った。無限の再帰呼び出し構造が有った。stack overflow を発生させている。恐らく glibc 2.11.1 も同様の問題が有ると考えられる。 ct-ng (crosstool-ng) を使用してターゲット環境を glibc 2.9 で構築している。ct-ng に patch を当てる機能がある。これを利用して、__vfprintf_chk() に patch を当てた。用意した patch は glibc 2.9 専用の物だ。他の glibc version にもほぼ同様に適応できると考えられる。 ct-ng 用の patch ファイルの内容は次の通りだ。__vfprintf_chk() 関数の処理を __vfwprintf_chk() と同様に _IO_xxx() 関数を呼び出す様にした。 diff -durN glibc-2.9.orig/debug/vfprintf_chk.c glibc-2.9/debug/vfprintf_chk.c --- glibc-2.9.orig/debug/vfprintf_chk.c 2007-07-20 02:12:45.000000000 +0900 +++ glibc-2.9/debug/vfprintf_chk.c 2010-09-03 23:52:48.000000000 +0900 @@ -32,7 +32,7 @@ if (flag > 0) fp->_flags2 |= _IO_FLAGS2_FORTIFY; - done = vfprintf (fp, format, ap); + done = _IO_vfprintf (fp, format, ap); if (flag > 0) fp->_flags2 &= ~_IO_FLAGS2_FORTIFY; 注: 表示整形のため、余計なスペースを入れてあります。 download した patch ファイルを ct-ng の作業用ディレクトリ ${ct_working_directory} に展開する。例えば ${ct_working_directory} は /home/furuta/work/qemu/ct だ。 % cd ${ct_working_directory} % tar xvf patches.local.tar.gz 作業ディレクトリに patches.local ディレクトリが作られるので、ct-ng menuconfig にて次の設定をする。 Paths and misc options ---> Patches origin (Bundled, then local) CT_PATCH_BUNDLED_LOCAL=y (${ct_working_directory}/patches.local) Local patch directory CT_LOCAL_PATCH_DIR=${ct_working_directory}/patches.local パッチを Bundled, then local の順で当てる様にする。 Local patch directory を先の展開したディレクトリに指定する。例えば /home/furuta/work/qemu/ct/patches.local となる。 ct-ng build で構築すれば、busybox が正常に動作する glibc を構築できるはずだ。 他の解決方法としては uClibc を使う方法、CT_LIBC_GLIBC_EXTRA_CFLAGS="-U_FORTIFY_SOURCE" を指定する方法が有る様だ。 glibc って、全関数テストされてないのかなぁ。 お気に入りの記事を「いいね!」で応援しよう
最終更新日
2010.09.04 10:25:10
コメント(0) | コメントを書く
[ソフト開発日誌] カテゴリの最新記事
|
|