2007年03月29日
なぜ apache module を更新すると Segmentation fault するのか
今回は、apache module について気になることがあったので紹介します。
先日 バージョンアップするために apache module を更新した直後 apache が Segmentation fault してしまうという問題に気が付きました。
Segmentation fault した後に apache を再起動すれば、新しいモジュールが反映されて正常に動作するものの何故この様なことが起こるのか不思議に思い原因を調査してみました。
先日 バージョンアップするために apache module を更新した直後 apache が Segmentation fault してしまうという問題に気が付きました。
Segmentation fault した後に apache を再起動すれば、新しいモジュールが反映されて正常に動作するものの何故この様なことが起こるのか不思議に思い原因を調査してみました。
たとえば、PHP5(mod_php5)をバージョンアップしたいとします。
通常通り php5 をビルドし、 make install をして apache にアクセスすると
レスポンスが空です。apache のログには
この様なエラーが出ています。
この後、apache を再起動することで問題なくアクセスが出来るようになるのですが、なぜ再起動が必要なのか疑問に思いました。
最初 apache の不具合ではないかと思い apache のデバッグを行ってみたのですが、原因は apache ではなくインストール方法に有ることが判りました。
php のソースディレクトリにて、
を実行すると make install した時と同様に apache は Segmentation fault します。しかし
だと、Segmentation fault しません。(新しい module は apache を再起動したときに反映されます)
どうやら、cp コマンドと install コマンドの違いに秘密がありそうです。これらのコマンドの違いはコピーする前に削除(unlink)するのが install コマンドで削除せず元のファイルを上書きを行うのが cp コマンドなのですが上書きを行うと何故 Segmentation fault してしまうのか、linux のダイナミックリンク機構について追ってみます。
linux ではダイナミックリンクの方法に暗黙的なリンクと明示的なリンクが有りますが apache では module をロードするために明示的なリンク dlopen(3) を行っています。
この dlopen(3) の中では共有ライブラリを普通に open(2) し mmap(2) を行います。つまり make install の中で呼ばれる cp コマンドが mmap 中のファイルを上書きしてしまったことが Segmentation fault してしまう原因だったようです。
ちなみに install コマンドで削除(unlink)しても大丈夫なのは open(2)中のファイルを unlink(2) しても close(2) するまでは正常にファイルを読み書き出来るからです。
長くなりましたが、当初の問題の解決するためには/usr/local/apache/build/instdso.sh を以下のように編集します。
これで安全に apache モジュールをインストール出来るようになりました。
# apxs -i などでも有効です。
通常通り php5 をビルドし、 make install をして apache にアクセスすると
% curl http://localhost/
curl: (52) Empty reply from server
レスポンスが空です。apache のログには
[Thr Mar 29 17:52:01 2007] [notice] child pid 20001 exit signal Segmentation fault (11)
この様なエラーが出ています。
この後、apache を再起動することで問題なくアクセスが出来るようになるのですが、なぜ再起動が必要なのか疑問に思いました。
最初 apache の不具合ではないかと思い apache のデバッグを行ってみたのですが、原因は apache ではなくインストール方法に有ることが判りました。
php のソースディレクトリにて、
% cp .libs/libphp5.so /usr/local/apache/modules/
を実行すると make install した時と同様に apache は Segmentation fault します。しかし
% install .libs/libphp5.so /usr/local/apache/modules/
だと、Segmentation fault しません。(新しい module は apache を再起動したときに反映されます)
どうやら、cp コマンドと install コマンドの違いに秘密がありそうです。これらのコマンドの違いはコピーする前に削除(unlink)するのが install コマンドで削除せず元のファイルを上書きを行うのが cp コマンドなのですが上書きを行うと何故 Segmentation fault してしまうのか、linux のダイナミックリンク機構について追ってみます。
linux ではダイナミックリンクの方法に暗黙的なリンクと明示的なリンクが有りますが apache では module をロードするために明示的なリンク dlopen(3) を行っています。
この dlopen(3) の中では共有ライブラリを普通に open(2) し mmap(2) を行います。つまり make install の中で呼ばれる cp コマンドが mmap 中のファイルを上書きしてしまったことが Segmentation fault してしまう原因だったようです。
ちなみに install コマンドで削除(unlink)しても大丈夫なのは open(2)中のファイルを unlink(2) しても close(2) するまでは正常にファイルを読み書き出来るからです。
長くなりましたが、当初の問題の解決するためには/usr/local/apache/build/instdso.sh を以下のように編集します。
52c52,53
< CMD="$SH_LIBTOOL --mode=install cp $DSOARCHIVE $TARGETDIR/"
---
> CMD="$SH_LIBTOOL --mode=install install $DSOARCHIVE $TARGETDIR/"
これで安全に apache モジュールをインストール出来るようになりました。
# apxs -i などでも有効です。
トラックバックURL
この記事へのトラックバック
1. [Rails勉強日記]Apache+FCGIで,時間が経つとSegmentation faultで落ちて接続できなくなる [ なんとなく日記 ] 2007年12月20日 18:12
いろいろ調べても解決法見つからず.と思ってたところに下記記事を見つけました. DSAS開発者の部屋:なぜ apache module を更新すると Segmentation fault するのか もしかして,ソースを更新するたびにちゃんとApacheをrestartせんといかんのだろうか(;´Д`).当たり前な