トップ 差分 一覧 Farm ソース 検索 ヘルプ RSS ログイン

BugTrack-wiki/307

ページの作成や編集にはユーザ登録が必要です。

exitのオーバライドとmod_perl

  • 投稿者: tateisu
  • カテゴリ: 本体
  • 優先度: 普通
  • 状態: リリース済
  • 日時: 2007年06月28日 17時12分12秒

 内容

fswiki3.6.2を試してみました。サーバ環境はx86 LinuxのApache/2.2.3 (Debian) mod_perl/2.0.2 Perl/v5.8.8 です。

他のスクリプトでもmod_perlを利用していて、同じインタプリタが他のスクリプトとFSWikiを動かしている状態で次の不具合がありました。

  • chdirはBEGIN時だけでは不十分。他スクリプトがchdirした後にFSWikiが実行された場合を考慮する必要がある。
  • 他スクリプトがexitを使うと safe_die というメッセージがApacheのエラーログに流れる。

そこでdie,exitのオーバライドを外してみると、今度は次の問題がありました。

  • リダイレクト直後に ModPerl::Util::Exit 云々というエラーがHTML出力される
  • _process_before_exit が呼ばれない

これらを踏まえて、evalの前後にだけdie,exitのオーバライドを行うように変更してみました。

変更案A

wiki.cgiのeval〜$@より前のエラーはキャッチできないのだから、Util.pmでBEGIN中にオーバライドしてるのはあまり意味がありません。wiki.cgiから_process_before_exitを呼び出すのは必要なので、スクリプト実行時にdie,exitをオーバライドするのは必要です。ただしその状態のまま放置されると、mod_perl上の他スクリプトに良くありません。

そこで実行時に毎回オーバライドとリストアするようにしてみました。ご確認の上オリジナルでも対応頂ければ幸いです。

--- /home/tateisu/fswiki-orig/wiki.cgi	2006-07-02 18:09:56.000000000 +0900
+++ index.pl	2007-06-28 16:48:57.000000000 +0900
@@ -28,2 +28,3 @@
 if(exists $ENV{MOD_PERL}){
+	chdir($ENV{FSWIKI_HOME});
 	eval("use Digest::Perl::MD5;");
@@ -39,3 +40,3 @@
 my $cgi = $wiki->get_CGI();
-
+Util::override_die();
 eval {
@@ -321,4 +322,3 @@
 $wiki->_process_before_exit();
-
-if($msg && index($msg, 'safe_die')<0){
+if( $msg && index($msg, 'safe_die')<0 ){
 	$msg = Util::escapeHTML($msg);
@@ -328 +328,2 @@
 }
+Util::restore_die();
--- /home/tateisu/fswiki-orig/lib/Util.pm	2006-07-02 18:10:04.000000000 +0900
+++ lib/Util.pm	2007-06-28 16:50:11.000000000 +0900
@@ -10,4 +10,3 @@
 	require Util;
-	*CORE::GLOBAL::die = \&Util::_die;
-	*CORE::GLOBAL::exit = \&Util::_exit;
+	exists($ENV{MOD_PERL}) or override_die();
 }
@@ -694,2 +693,24 @@
 
+#===============================================================================
+# <p>
+#   dieとexitのオーバライド操作を行います。
+# </p>
+#===============================================================================
+sub override_die{
+	our @original_exit_handler;
+	@original_exit_handler or @original_exit_handler = (\&CORE::GLOBAL::die,\&CORE::GLOBAL::exit);
+	*CORE::GLOBAL::die = \&Util::_die;
+	*CORE::GLOBAL::exit = \&Util::_exit;
+}
+#===============================================================================
+# <p>
+#   dieとexitのオーバライド操作を解除します。
+# </p>
+#===============================================================================
+sub restore_die{
+	our @original_exit_handler;
+	*CORE::GLOBAL::die = $original_exit_handler[0];
+	*CORE::GLOBAL::exit = $original_exit_handler[1];
+}
+
 1;

関連項目

  • mod_perl環境だと同一のインタプリタが複数のスクリプトを扱うことがある。
  • mod_perl環境だとCORE::GLOBAL::exit は ModPerl::Util::exitを指すようになる
  • FSWikiがdieとexitをオーバライドするのは、eval後に _process_before_exit を呼び出すため。あとエラーメッセージをHTML出力するため。
  • mod_perlで動く他のスクリプトはModPerl::Util::exitのかわりに、FSWikiに汚染されたexitを使ってしまう。error.logに毎回safe_dieが出てしまう。

その他の問題

  • Util.pm はmod_perlだと名前空間の衝突が怖い気がする。

 コメント

  • ほぼパッチの通りの変更をコミットしました。ステータスを完了にします。 - typer (2007年07月08日 23時13分03秒)
  • 3.6.3dev2でリリースしました。 - たけぞう (2007年09月22日 17時00分07秒)
お名前: コメント:

最終更新時間:2007年09月22日 17時00分07秒