From karma @ jazz.email.ne.jp Mon Mar 2 13:27:26 2009 From: karma @ jazz.email.ne.jp (KATOH Yasufumi) Date: Mon, 02 Mar 2009 13:27:26 +0900 Subject: [PHP-dev 1445] =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2RpbmcgGyRCJE4bKEI=?= =?iso-2022-jp?b?GyRCQ00kLEg/MUckNSRsJEokJD5sOWckLCQiJGs3bxsoQigxKQ==?= Message-ID: <873adwk0r5.wl%karma@jazz.email.ne.jp> 加藤泰文です. mbstring 使用時に internal_encoding を .htaccess で指定していた際 (か つ,encoding_translation On の時) の問題と思われる現象に行き当たりまし たので,少しデバッガで追ってみました.相変わらず,PHP 内部の構造とか作 法は素人ですので,ボケた事を言っていたらご容赦ください&長文ご容赦ください. # あと,こんな設定せずに,ちゃんと設定したらええやん,というのはそうで # すが,ここではそれは置いといてください.  ./configure \ --with-apxs2=/usr/local/apache2/bin/apxs \ --with-zlib \ --enable-mbstring \ --enable-mbregex \ --enable-zend-multibyte \ --with-openssl という風に構築した PHP 5.2.9 です (5.2.8 でも同様でした).5.2.6 以前は 起きていなかったようです. php.ini は以下. mbstring.language = Japanese mbstring.internal_encoding = EUC-JP mbstring.http_input = auto mbstring.http_output = pass mbstring.encoding_translation = On mbstring.detect_order = auto mbstring.substitute_character = none; mbstring.func_overload = 0 mbstring.strict_encoding = Off ここで,とあるディレクトリには .htaccess を置き,  php_value mbstring.language Japanese  php_value output_handler mb_output_handler  php_flag mbstring.encoding_translation 1  php_flag magic_quotes_gpc 0  php_value mbstring.internal_encoding UTF-8 という風に設定します. とりあえずブラウザ上で再現させる方法を書きます.サンプルプログラムは以 下.ソースは UTF-8 で記述. \n"; print "encoding: " . mb_detect_encoding($_REQUEST["message"]) . "
\n"; print htmlspecialchars($_REQUEST["message"]) . "
\n"; } ?>
">
 
 
 
 

(再現その1)
1. まず上記ページにアクセスします.
2. ブラウザに表示させたまま,一度 apache を落とします.
3. httpd -X で apache を起動します.(かならず発現するようにシングルプ
   ロセスモード)
4. フォームに日本語を入力し,submit します.
5. 前画面で input に入力した文字列のみ文字化け.mb_detect_encoding は
   EUC-JP となります.mb_get_info で表示させた internal_encoding は
   UTF-8 で正常です.
6. この後は (http -X で起動している限りは) 何度アクセスしても文字化け
   は起こらず,正常です.

(再現その2)
1. (再現その1) の 6 でその後は何度アクセスしても正常と書きましたが,こ
   こで一度,.htaccess のないディレクトリへ遷移して,その後,この
   .htaccess の存在するディレクトリへ戻ります.つまり
   .htaccess 有 -> 無 -> 有 と一度外に出て戻ります.
2. 戻る際は http://server/dir/test.php?message=あいうえお みたいに直接
   パラメータ指定します.
3. 文字化け.mb_detect_encoding は EUC-JP,mb_get_info は UTF-8.

つまり internal_encoding に関しては,
- Apache 起動直後の (Apache 各プロセスの) 最初のアクセスでは .htaccess
  の内容は反映されない.
- 起動直後でなくても,一度 .htaccess のないディレクトリへ遷移して,ま
  た戻ると .htaccess の内容は反映されない.
という現象です.

長文ですので,あとは別便で.

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================

From karma @ jazz.email.ne.jp  Mon Mar  2 13:29:23 2009
From: karma @ jazz.email.ne.jp (KATOH Yasufumi)
Date: Mon, 02 Mar 2009 13:29:23 +0900
Subject: [PHP-dev 1446]
 =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2RpbmcgGyRCJE4bKEI=?=
 =?iso-2022-jp?b?GyRCQ00kLEg/MUckNSRsJEokJD5sOWckLCQiJGs3bxsoQigyKQ==?=
Message-ID: <871vtgk0nw.wl%karma@jazz.email.ne.jp>

加藤泰文です.

(続き)

デバッガで追ってみました.全部追ってないので,かなりこう動くのだろう,
という想像が入ってますが..

Apache 起動後,

1. .htaccess が検出されると,OnUpdate_mbstring_internal_encoding へ飛
   ぶ.ここで new_value の値をデバッガで見てみると,"UTF-8" となってお
   り,確かに .htaccess は読み込まれているっぽいです.先の例で
   mb_get_info() で設定を取得すると,internal_encoding の値は "UTF-8"
   と正常になっていたのは,ちゃんと値が取得出来ているからだと思います.

2. ここで encoding_translation が指定されていると,mb_gpc.c 内の 
   mbstr_treat_data に処理が飛びます.ここで変換先のエンコーディングを
   決定しているっぽいですが,ここではグローバル変数 mbstring_globals
   の internal_encoding を見ているようで,この時点では
   mbstring_globals.internal_encoding の値は更新されておらず,例だと
   "EUC-JP" のままなので,その後の変換処理で(?) 入力文字列が EUC-JP へ
   変換されてしまい,結果,出力が文字化けしてしまうようです.

3. その後,グローバル変数は更新されるので,次にアクセスした際は,正常
   にエンコード変換される (or されない) のですが,一度,別設定が効いて
   くる他のディレクトリに移動すると,グローバル変数の値がそのディレク
   トリの値にリセットされるので,再度文字化けが発症します (=
   internal_encoding の値が .htaccess 以外の値に).

以上のように想像なのですが,エンコーディング変換が有効な際,.htaccess
の値でグローバル変数が更新されていれば,問題なく動くのだと思います.と
りあえず,きっと他の動きがめちゃめちゃになるのでしょうけど,以下のよう
にしてみると,文字化けは解消しています (今回の例のプログラム以外検証し
てません&使った関数もこれかなーという想像の適当 ^^;).

--- mbstring.c.orig	2009-03-02 13:02:25.000000000 +0900
+++ mbstring.c	2009-03-02 13:03:03.000000000 +0900
@@ -745,6 +745,7 @@
 		 * 2. mbstring.language directive is processed in per-dir or runtime
 		 * context and 3. call to the handler for mbstring.language is done
 		 * after mbstring.internal_encoding is handled. */
+		_php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);
 		return SUCCESS;
 	}
 }

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================

From karma @ jazz.email.ne.jp  Wed Mar 11 21:22:47 2009
From: karma @ jazz.email.ne.jp (KATOH Yasufumi)
Date: Wed, 11 Mar 2009 21:22:47 +0900
Subject: [PHP-dev 1447] Re:
 =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
 =?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhCKDIp?=
In-Reply-To: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
Message-ID: <87fxhk5jvs.wl%karma@jazz.email.ne.jp>

加藤泰文です.

もう少し調べて見ましたが,知識ナシ故に,進展ありません.(^_^;)

>>> On Mon, 02 Mar 2009 13:29:23 +0900
    in message   "[PHP-dev 1446] mbstring.internel_encoding の値が反映されない場合がある件(2)"
                  KATOH Yasufumi-san wrote:

> --- mbstring.c.orig	2009-03-02 13:02:25.000000000 +0900
> +++ mbstring.c	2009-03-02 13:03:03.000000000 +0900
> @@ -745,6 +745,7 @@
>  		 * 2. mbstring.language directive is processed in per-dir or runtime
>  		 * context and 3. call to the handler for mbstring.language is done
>  		 * after mbstring.internal_encoding is handled. */
> +		_php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);
>  		return SUCCESS;
>  	}
>  }

さすがに _php_mb_ini_mbstring_internal_encoding_set を使うのは目的外使
用みたいでマズい事が起こるのかもしれませんね.単純に
  MBSTRG(internal_encoding) = mbfl_name2no_encoding(new_value);
で良いのかも? (current_internal_encoding も?)

ところで,この部分のコメントがイマイチ良く分かりません.単に英語力がな
いだけかも? (^_^;)

| the corresponding mbstring globals needs to be set according to the
| ini value in the later stage because it never falls back to the
| default value if 1. no value for mbstring.internal_encoding is
| given, 2. mbstring.language directive is processed in per-dir or
| runtime context and 3. call to the handler for mbstring.language is
| done after mbstring.internal_encoding is handled.

1. mbstring.internal_encodings が no value
2. mbstring.language がディレクトリ単位もしくは実行時に設定される
3. mbstring.internal_encoding を処理した後に mbstring.language の処理
   が呼ばれる

の全てが当てはまるような場合に,もっと後に値をグローバル変数にセットす
る必要がある,ってことですよね? internal_encodings が設定されてないの
に,3 の「internal_encoding を処理した後」という部分が良く分かりませ
ん.どういう事でしょうか?

# 内部が分かってないのでボケてる可能性大ですが... (^_^;)

まあ,確かに後で PHP_RINIT_FUNCTION でグローバル変数にセットはされます
けど,encoding_translation が有効だと RINIT の前に変換の encoding が決
まってしまいますよね.

-----
と,ここまで調べて,ini_set した場合はどうなるかな,とやると,そもそも
ini_set だと OnUpdate_mbstring_internal_encoding には飛ばないので,グ
ローバル変数が ini_set で設定した値じゃないまま,mbstr_treat_data に行
きますね.この中で zend_ini_string とかしても,ini_set で設定する前の
値なので,更新されるのがもっとあと,ということですかね?

php-dev 1445 で PHP 5.2.6 では起きないと書きましたが,ini_set のケース
は 5.2.6 でも同じでうまく動かないですね.

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================
ドキドキ...

From mozo @ mozo.jp  Wed Mar 11 22:22:34 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Wed, 11 Mar 2009 22:22:34 +0900
Subject: [PHP-dev 1448] Re:
	=?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
	=?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhC?=
	=?iso-2022-jp?b?KDIp?=
In-Reply-To: <87fxhk5jvs.wl%karma@jazz.email.ne.jp>
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
Message-ID: 

小泉です。

メールをすっかり見落としていました。
いろいろ調べていただいていてすみません。
おかげさまですぐに原因にアタリをつけることができました。ありがとうございます。

> ところで,この部分のコメントがイマイチ良く分かりません.単に英語力がな
> いだけかも? (^_^;)
>
> | the corresponding mbstring globals needs to be set according to the
> | ini value in the later stage because it never falls back to the
> | default value if 1. no value for mbstring.internal_encoding is
> | given, 2. mbstring.language directive is processed in per-dir or
> | runtime context and 3. call to the handler for mbstring.language is
> | done after mbstring.internal_encoding is handled.
>
> 1. mbstring.internal_encodings が no value
> 2. mbstring.language がディレクトリ単位もしくは実行時に設定される
> 3. mbstring.internal_encoding を処理した後に mbstring.language の処理
>   が呼ばれる
>
> の全てが当てはまるような場合に,もっと後に値をグローバル変数にセットす
> る必要がある,ってことですよね? internal_encodings が設定されてないの
> に,3 の「internal_encoding を処理した後」という部分が良く分かりませ
> ん.どういう事でしょうか?

これは、私の文章力がないせいですね (笑)
ここで直したかったバグは、あるディレクトリの.htaccess内でmbstring.languageを設定しておくと、その設定内容が他のディレクトリのスクリプトのmbstring.itnernal_encodingの設定に影響するというものでした。

From hossy421 @ yahoo.co.jp  Fri Mar 13 18:19:55 2009
From: hossy421 @ yahoo.co.jp (Hoshizuki Yusuke)
Date: Fri, 13 Mar 2009 18:19:55 +0900
Subject: [PHP-dev 1449]
 =?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5JGsbKEI=?=
 =?iso-2022-jp?b?GyRCJEgbKEIgQXBhY2hlIBskQiQsGyhCIFNJR0FCUlQgGyRCJEcbKEI=?=
 =?iso-2022-jp?b?GyRCPSpOOyQ5JGsbKEI=?=
Message-ID: <20090313172650.623F.305AAED1@yahoo.co.jp>

はじめまして。
今回初めてこちらの ML に登録させていただきました。
星月優佑と申します。

php5 の mod_php におきまして、件名のとおりのバグを発見し、
ソースコードを追いかけて原因も判明しましたので、
こちらで報告させていただきたいと思います。


1. 環境

当方の環境は以下の通りです。

OS: FreeBSD 6.3R ( in jail )
HTTPd: Apache 2.2.11
PHP: PHP5 5.2.8

Apache も PHP も ports からインストールしたもので、
以下すべてこのバージョンについて書いてあります。

他のバージョンに関しては検証していませんが、
おそらく OS や Apache のバージョンには関係しないものと考えられます。


2. 症状

httpd-error.log に以下のようなメッセージを残して httpd が死にます。

> httpd in free(): error: recursive call
> [notice] child pid XXXXX exit signal Abort trap (6)

XXXXX の部分は httpd の pid で、毎回異なる番号となります。


3. 原因

php.ini にて max_execution_time の設定が有効になっていると、
Zend/zend_execute_API.c にて

> setitimer(ITIMER_PROF, &t_r, NULL);
> signal(SIGPROF, zend_timeout);

このように、指定時間後に SIGPROF が飛んでくるよう設定されます。

このシグナルハンドラ、zend_timeout() は Zend/zend.c にて

> /* The error may not be safe to handle in user-space */
> zend_error_cb(type, error_filename, error_lineno, format, args);

このようにコールバック関数を呼ぶようになっていますが、
デバッガで追いかけると main/main.c の php_error_cb() を指していました。
ここでは

> buffer_len = vspprintf(&buffer, PG(log_errors_max_len), format, args);

> efree(buffer);

このように、malloc や free などが呼ばれています。


何もないところで SIGPROF が飛んでこればいいのですが、
malloc(), free() の関数内を実行中に SIGPROF が飛んでくると、
先ほどのログにあるように free() の再帰呼び出しとなってしまい、
それを検出した libc が abort() を実行しているのが原因です。

そもそも、原則としてシグナルハンドラ中はアトミックな操作しか
行ってはいけないはずですが、それが破られているのが原因だと考えられます。


4. 解決(回避)方法

いくつか考えられるものがあります。

4.1. max_execution_time を 0 ( 無効 ) にする

おそらく最も順当な手法と思いますが、スクリプトが暴走した場合に
サーバ自体が停止するので怖くて試せませんでした。

4.2. zend_timeout() で何も言わずに即死させるパッチを当てる

つまりはこういうことです。

void zend_timeout() { _exit( -2 ); }

exit() では atexit() で指定されたフック関数が呼ばれるので NG。
グローバルリソースの解放などが行われなくなる可能性があるので
怖くて試せませんでした。

4.3. malloc(), free() をフックしてシグナルをブロックする

すごく気持ち悪い方法ですが、LD_PRELOAD を用いて
とりあえず malloc(), free(), realloc() をハックし、
SIGPROF を一時的にブロックするフック関数をかませます。

詳細については私の blog にまとめてありますので参考までに。
ref: http://d.hatena.ne.jp/Hossy/20090222#p1



以上が今回報告させていただくバグの概要です。

一応 4.3. の方法でエラーは発生しなくなりましたが、
いろいろと気持ちの悪い方法な上、そもそもシグナルハンドラ内で
複雑な処理を行いすぎること自体が問題であるため、
きちんと PHP インタプリタの側でデバッグが必要であると思います。


5. 教えていただきたいこと

今回この ML への投稿で教えていただきたいことは以下の2点です。

・もっとスマートな(安全な)回避方法はないでしょうか
・とりあえず日本語ということでこちらの ML に投げましたが、
 もっと適したところがありましたら紹介していただけないでしょうか


以上です。長文失礼いたしました。

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
 送信者 : 星月 優佑
   Mail : hossy421 @ yahoo.co.jp
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*


From mozo @ mozo.jp  Mon Mar 16 03:00:58 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Mon, 16 Mar 2009 03:00:58 +0900
Subject: [PHP-dev 1450] Re:
	=?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5GyhC?=
	=?iso-2022-jp?b?GyRCJGskSBsoQiBBcGFjaGUgGyRCJCwbKEIgU0lHQUJSVCA=?=
	=?iso-2022-jp?b?GyRCJEc9Kk47JDkkaxsoQg==?=
In-Reply-To: <20090313172650.623F.305AAED1@yahoo.co.jp>
References: <20090313172650.623F.305AAED1@yahoo.co.jp>
Message-ID: 

小泉です。

お返事が遅くなってすみません (相変わらずです。。。)

可能であれば本家のバグ管理システムに報告していただけると助かります。

http://bugs.php.net/

さて、問題が発生していると思われる状況はどのようにすれば再現できますでしょうか。再現のためのコードまたは手順をご教示ください。

malloc(3) 系の libc 関数は確かに非同期シグナルセーフではありませんが、emalloc() や efree() といった関数は
libc の関数そのものではなく、PHP
の側で用意しているアロケータです。これらの関数でも、クリティカルセクションの中でシグナルをブロックしているはず
(HANDLE_BLOCK_INTERRUPTIONS / HANDLE_UNBLOCK_INTERUPTIONS)
なので、そのような状況が発生するとは考えにくいです。むしろ、heap corruptionが発生しているという可能性はないですか?

> そもそも、原則としてシグナルハンドラ中はアトミックな操作しか
> 行ってはいけないはずですが、それが破られているのが原因だと考えられます。

シグナルを適切にブロックしていればその限りではないと思いますが…。あまりシグナルハンドラ中であれこれやらないほうがいいのがベストプラクティスといえばその通りと思います。

スマートな回避策があるとすれば、クリティカルセクションに入れるべきものが入ってない状況を回避するということになるでしょうか。

From mozo @ mozo.jp  Mon Mar 16 03:57:48 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Mon, 16 Mar 2009 03:57:48 +0900
Subject: [PHP-dev 1451] Re:
	=?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5GyhC?=
	=?iso-2022-jp?b?GyRCJGskSBsoQiBBcGFjaGUgGyRCJCwbKEIgU0lHQUJSVCA=?=
	=?iso-2022-jp?b?GyRCJEc9Kk47JDkkaxsoQg==?=
In-Reply-To: 
References: <20090313172650.623F.305AAED1@yahoo.co.jp>
	
Message-ID: 

小泉です。

よくよく見てみたら、apache
SAPIでは下記のマクロの中でシグナルをブロックするハンドラに飛ばしていたのですが、apache2handler
SAPIでは何もしていませんでした。なのでそれが原因のような気がします。

というわけでパッチを作成してみました。これを当てることで問題は回避されるでしょうか?

2009/3/16 Moriyoshi Koizumi :
> 小泉です。
>
> お返事が遅くなってすみません (相変わらずです。。。)
>
> 可能であれば本家のバグ管理システムに報告していただけると助かります。
>
> http://bugs.php.net/
>
> さて、問題が発生していると思われる状況はどのようにすれば再現できますでしょうか。再現のためのコードまたは手順をご教示ください。
>
> malloc(3) 系の libc 関数は確かに非同期シグナルセーフではありませんが、emalloc() や efree() といった関数は
> libc の関数そのものではなく、PHP
> の側で用意しているアロケータです。これらの関数でも、クリティカルセクションの中でシグナルをブロックしているはず
> (HANDLE_BLOCK_INTERRUPTIONS / HANDLE_UNBLOCK_INTERUPTIONS)
> なので、そのような状況が発生するとは考えにくいです。むしろ、heap corruptionが発生しているという可能性はないですか?
>
>> そもそも、原則としてシグナルハンドラ中はアトミックな操作しか
>> 行ってはいけないはずですが、それが破られているのが原因だと考えられます。
>
> シグナルを適切にブロックしていればその限りではないと思いますが…。あまりシグナルハンドラ中であれこれやらないほうがいいのがベストプラクティスといえばその通りと思います。
>
> スマートな回避策があるとすれば、クリティカルセクションに入れるべきものが入ってない状況を回避するということになるでしょうか。
>
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: php-apache2-sigblock-20090316.patch.diff
型:         text/x-patch
サイズ:     4586 バイト
説明:       無し
URL:        http://ml.php.gr.jp/pipermail/php-dev/attachments/20090316/d76b15fc/attachment.bin 

From mozo @ mozo.jp  Mon Mar 16 03:59:17 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Mon, 16 Mar 2009 03:59:17 +0900
Subject: [PHP-dev 1452] Re:
	=?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5GyhC?=
	=?iso-2022-jp?b?GyRCJGskSBsoQiBBcGFjaGUgGyRCJCwbKEIgU0lHQUJSVCA=?=
	=?iso-2022-jp?b?GyRCJEc9Kk47JDkkaxsoQg==?=
In-Reply-To: 
References: <20090313172650.623F.305AAED1@yahoo.co.jp>
	
	
Message-ID: 

すみません、ファイルに一部余計なものが含まれていました。
これを当ててください。

よろしくお願いします。

2009/3/16 Moriyoshi Koizumi :
> 小泉です。
>
> よくよく見てみたら、apache
> SAPIでは下記のマクロの中でシグナルをブロックするハンドラに飛ばしていたのですが、apache2handler
> SAPIでは何もしていませんでした。なのでそれが原因のような気がします。
>
> というわけでパッチを作成してみました。これを当てることで問題は回避されるでしょうか?
>
> 2009/3/16 Moriyoshi Koizumi :
>> 小泉です。
>>
>> お返事が遅くなってすみません (相変わらずです。。。)
>>
>> 可能であれば本家のバグ管理システムに報告していただけると助かります。
>>
>> http://bugs.php.net/
>>
>> さて、問題が発生していると思われる状況はどのようにすれば再現できますでしょうか。再現のためのコードまたは手順をご教示ください。
>>
>> malloc(3) 系の libc 関数は確かに非同期シグナルセーフではありませんが、emalloc() や efree() といった関数は
>> libc の関数そのものではなく、PHP
>> の側で用意しているアロケータです。これらの関数でも、クリティカルセクションの中でシグナルをブロックしているはず
>> (HANDLE_BLOCK_INTERRUPTIONS / HANDLE_UNBLOCK_INTERUPTIONS)
>> なので、そのような状況が発生するとは考えにくいです。むしろ、heap corruptionが発生しているという可能性はないですか?
>>
>>> そもそも、原則としてシグナルハンドラ中はアトミックな操作しか
>>> 行ってはいけないはずですが、それが破られているのが原因だと考えられます。
>>
>> シグナルを適切にブロックしていればその限りではないと思いますが…。あまりシグナルハンドラ中であれこれやらないほうがいいのがベストプラクティスといえばその通りと思います。
>>
>> スマートな回避策があるとすれば、クリティカルセクションに入れるべきものが入ってない状況を回避するということになるでしょうか。
>>
>
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: php-apache2-sigblock-20090316.patch.diff
型:         text/x-patch
サイズ:     2811 バイト
説明:       無し
URL:        http://ml.php.gr.jp/pipermail/php-dev/attachments/20090316/33d415a8/attachment.bin 

From mozo @ mozo.jp  Mon Mar 16 06:20:09 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Mon, 16 Mar 2009 06:20:09 +0900
Subject: [PHP-dev 1453] Re:
	=?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
	=?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhC?=
	=?iso-2022-jp?b?KDIp?=
In-Reply-To: 
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
Message-ID: 

小泉です。

おそらくこの問題を解決できました。
添付のパッチをお試しいただけないでしょうか?
(すでに 5.2 CVS には反映済みです)

2009/3/11 Moriyoshi Koizumi :
> 小泉です。
>
> メールをすっかり見落としていました。
> いろいろ調べていただいていてすみません。
> おかげさまですぐに原因にアタリをつけることができました。ありがとうございます。
>
>> ところで,この部分のコメントがイマイチ良く分かりません.単に英語力がな
>> いだけかも? (^_^;)
>>
>> | the corresponding mbstring globals needs to be set according to the
>> | ini value in the later stage because it never falls back to the
>> | default value if 1. no value for mbstring.internal_encoding is
>> | given, 2. mbstring.language directive is processed in per-dir or
>> | runtime context and 3. call to the handler for mbstring.language is
>> | done after mbstring.internal_encoding is handled.
>>
>> 1. mbstring.internal_encodings が no value
>> 2. mbstring.language がディレクトリ単位もしくは実行時に設定される
>> 3. mbstring.internal_encoding を処理した後に mbstring.language の処理
>>   が呼ばれる
>>
>> の全てが当てはまるような場合に,もっと後に値をグローバル変数にセットす
>> る必要がある,ってことですよね? internal_encodings が設定されてないの
>> に,3 の「internal_encoding を処理した後」という部分が良く分かりませ
>> ん.どういう事でしょうか?
>
> これは、私の文章力がないせいですね (笑)
> ここで直したかったバグは、あるディレクトリの.htaccess内でmbstring.languageを設定しておくと、その設定内容が他のディレクトリのスクリプトのmbstring.itnernal_encodingの設定に影響するというものでした。
>
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: php-encoding_translation-malfunction-under-per-dir-context.patch.diff
型:         text/x-patch
サイズ:     4307 バイト
説明:       無し
URL:        http://ml.php.gr.jp/pipermail/php-dev/attachments/20090316/1c1fb168/attachment-0001.bin 

From mozo @ mozo.jp  Mon Mar 16 15:10:56 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Mon, 16 Mar 2009 15:10:56 +0900
Subject: [PHP-dev 1454] Re:
	=?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5GyhC?=
	=?iso-2022-jp?b?GyRCJGskSBsoQiBBcGFjaGUgGyRCJCwbKEIgU0lHQUJSVCA=?=
	=?iso-2022-jp?b?GyRCJEc9Kk47JDkkaxsoQg==?=
In-Reply-To: 
References: <20090313172650.623F.305AAED1@yahoo.co.jp>
	
	
	
Message-ID: 

小泉です。

本件ですが、本家のメーリングリストでしれっと触れてみたら以下のような話になりました。

http://news.php.net/php.internals/43357

以上、参考になれば。


2009/3/16 Moriyoshi Koizumi :
> すみません、ファイルに一部余計なものが含まれていました。
> これを当ててください。
>
> よろしくお願いします。
>
> 2009/3/16 Moriyoshi Koizumi :
>> 小泉です。
>>
>> よくよく見てみたら、apache
>> SAPIでは下記のマクロの中でシグナルをブロックするハンドラに飛ばしていたのですが、apache2handler
>> SAPIでは何もしていませんでした。なのでそれが原因のような気がします。
>>
>> というわけでパッチを作成してみました。これを当てることで問題は回避されるでしょうか?
>>
>> 2009/3/16 Moriyoshi Koizumi :
>>> 小泉です。
>>>
>>> お返事が遅くなってすみません (相変わらずです。。。)
>>>
>>> 可能であれば本家のバグ管理システムに報告していただけると助かります。
>>>
>>> http://bugs.php.net/
>>>
>>> さて、問題が発生していると思われる状況はどのようにすれば再現できますでしょうか。再現のためのコードまたは手順をご教示ください。
>>>
>>> malloc(3) 系の libc 関数は確かに非同期シグナルセーフではありませんが、emalloc() や efree() といった関数は
>>> libc の関数そのものではなく、PHP
>>> の側で用意しているアロケータです。これらの関数でも、クリティカルセクションの中でシグナルをブロックしているはず
>>> (HANDLE_BLOCK_INTERRUPTIONS / HANDLE_UNBLOCK_INTERUPTIONS)
>>> なので、そのような状況が発生するとは考えにくいです。むしろ、heap corruptionが発生しているという可能性はないですか?
>>>
>>>> そもそも、原則としてシグナルハンドラ中はアトミックな操作しか
>>>> 行ってはいけないはずですが、それが破られているのが原因だと考えられます。
>>>
>>> シグナルを適切にブロックしていればその限りではないと思いますが…。あまりシグナルハンドラ中であれこれやらないほうがいいのがベストプラクティスといえばその通りと思います。
>>>
>>> スマートな回避策があるとすれば、クリティカルセクションに入れるべきものが入ってない状況を回避するということになるでしょうか。
>>>
>>
>

From hossy421 @ yahoo.co.jp  Tue Mar 17 06:54:50 2009
From: hossy421 @ yahoo.co.jp (Hoshizuki Yusuke)
Date: Tue, 17 Mar 2009 06:54:50 +0900
Subject: [PHP-dev 1455] Re:
 =?iso-2022-jp?b?bWF4X2V4ZWN1dGlvbl90aW1lIBskQiRyQF9EaiQ5GyhC?=
 =?iso-2022-jp?b?GyRCJGskSBsoQiBBcGFjaGUgGyRCJCwbKEIgU0lHQUJSVCA=?=
 =?iso-2022-jp?b?GyRCJEc9Kk47JDkkaxsoQg==?=
In-Reply-To: 
References: 
	
Message-ID: <20090317063344.0147.305AAED1@yahoo.co.jp>

こんにちは。星月です。

いつの間にかすごく話が進んでいてびっくりしました。
お忙しい中ありがとうございます。

> 再現のためのコードまたは手順をご教示ください。

再現しようとは試みているのですが、なぜか手元で再現できません。
高負荷の状態でファイル読み込みを大量に発生させてタイムアウトさせると
発生しやすいみたいですが、他にも要因があるのかもしれません。

> これらの関数でも、クリティカルセクションの中でシグナルをブロックしているはず
> (HANDLE_BLOCK_INTERRUPTIONS / HANDLE_UNBLOCK_INTERUPTIONS)

> よくよく見てみたら、apache SAPIでは下記のマクロの中でシグナルをブロックする
> ハンドラに飛ばしていたのですが、apache2handler SAPIでは何もしていませんでした。
> なのでそれが原因のような気がします。

おそらくその通りのようです。

> #define HANDLE_BLOCK_INTERRUPTIONS() \
> if (zend_block_interruptions) { zend_block_interruptions(); }

Zend/zend.h によるとこのようにマクロ定義されていますが、

> (gdb) p zend_block_interruptions
> $4 = (void (*)(void)) 0

実際には NULL ポインタになっています。

> (gdb) p apache2_sapi_module
> $1 = {name = 0x28759d5d "apache2handler", pretty_name = 0x28759d6c "Apache 2.0 Handler",
<省略>
>   block_interruptions = 0, unblock_interruptions = 0,
<省略>

元々の sapi/apache2handler/sapi_apache2.c でも NULL に
なっているようですので、そもそもシグナルブロックがされていないようですね。

> というわけでパッチを作成してみました。これを当てることで問題は回避されるでしょうか?

ありがとうございます。早速パッチを当てて試していますが、
今のところ問題なく動いているように見えます。

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
 送信者 : 星月 優佑
   Mail : hossy421 @ yahoo.co.jp
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*


From karma @ jazz.email.ne.jp  Tue Mar 17 17:25:30 2009
From: karma @ jazz.email.ne.jp (KATOH Yasufumi)
Date: Tue, 17 Mar 2009 17:25:30 +0900
Subject: [PHP-dev 1456] Re:
 =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
 =?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhCKDIp?=
In-Reply-To: 
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
	
Message-ID: <87wsaowo79.wl%karma@jazz.email.ne.jp>

加藤泰文です.

>>> On Mon, 16 Mar 2009 06:20:09 +0900
    in message   "[PHP-dev 1453] Re:	mbstring.internel_encoding の値が反映されない場合がある件(2)"
                  Moriyoshi Koizumi-san wrote:

> おそらくこの問題を解決できました。
> 添付のパッチをお試しいただけないでしょうか?
> (すでに 5.2 CVS には反映済みです)

ありがとうございました.パッチを試してみました.

とりあえず .htaccess で internal_encoding を設定したときは,無事
mb_gpc.c の mbstr_treat_data 関数内でも,きちんと設定値が取得され,き
ちんとエンコード変換されますね.

ただ,(PHP) プログラム冒頭で
  ini_set("mbstring.internal_encoding", "UTF-8");
とやって設定した場合は値は反映されないようです.

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================

From mozo @ mozo.jp  Tue Mar 17 20:59:17 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Tue, 17 Mar 2009 20:59:17 +0900
Subject: [PHP-dev 1457] Re:
	=?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
	=?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhC?=
	=?iso-2022-jp?b?KDIp?=
In-Reply-To: <87wsaowo79.wl%karma@jazz.email.ne.jp>
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
	
	<87wsaowo79.wl%karma@jazz.email.ne.jp>
Message-ID: 

小泉です。

問題が解決できたようでよかったです。

> ただ,(PHP) プログラム冒頭で
>  ini_set("mbstring.internal_encoding", "UTF-8");
> とやって設定した場合は値は反映されないようです.

これはどういう意味でしょうか? プログラム中で ini_set() を使って mbstring.internal_encoding
を変更しても、そのエンコーディングにクエリ文字列が変換されないというような現象を指していますか? それとも単純に
mbstring.internal_encoding の設定を変更する際に mb_internal_encoding() の代わりに
ini_set() を使ったときに、値が設定されないというような状況が発生しているということでしょうか?

一応手元では

php.iniで
mbstring.internal_encoding=ISO-8859-1

あるいは .htaccess で
php_value mbstring.internal_encoding ISO-8859-1

などとしたときに



以上のスクリプトが
string(10) "ISO-8859-1"
string(5) "UTF-8"
という結果を返すことは確認しています。

From karma @ jazz.email.ne.jp  Tue Mar 17 22:24:49 2009
From: karma @ jazz.email.ne.jp (KATOH Yasufumi)
Date: Tue, 17 Mar 2009 22:24:49 +0900
Subject: [PHP-dev 1458] Re:
 =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
 =?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhCKDIp?=
In-Reply-To: 
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
	
	<87wsaowo79.wl%karma@jazz.email.ne.jp>
	
Message-ID: <87vdq8wace.wl%karma@jazz.email.ne.jp>

加藤泰文です.

>>> On Tue, 17 Mar 2009 20:59:17 +0900
    in message   "[PHP-dev 1457] Re:	mbstring.internel_encoding の値が反映されない場合がある件(2)"
                  Moriyoshi Koizumi-san wrote:

> これはどういう意味でしょうか? プログラム中で ini_set() を使って mbstring.internal_encoding
> を変更しても、そのエンコーディングにクエリ文字列が変換されないという
> ような現象を指していますか?

はい,このような現象を指しているつもりでしたが,再度確認してみますね.
なんかボケてるような気がしてきた...

一応,php-dev 1445 のような環境,プログラムで,.htaccess での
internal_encoding の設定をやめて,プログラム内で ini_set で設定して試
しました.

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================

From mozo @ mozo.jp  Wed Mar 18 09:33:10 2009
From: mozo @ mozo.jp (Moriyoshi Koizumi)
Date: Wed, 18 Mar 2009 09:33:10 +0900
Subject: [PHP-dev 1459] Re:
	=?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
	=?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhC?=
	=?iso-2022-jp?b?KDIp?=
In-Reply-To: <87vdq8wace.wl%karma@jazz.email.ne.jp>
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
	
	<87wsaowo79.wl%karma@jazz.email.ne.jp>
	
	<87vdq8wace.wl%karma@jazz.email.ne.jp>
Message-ID: 

小泉です。

2009/3/17 KATOH Yasufumi :
>> これはどういう意味でしょうか? プログラム中で ini_set() を使って mbstring.internal_encoding
>> を変更しても、そのエンコーディングにクエリ文字列が変換されないという
>> ような現象を指していますか?
>
> はい,このような現象を指しているつもりでしたが,再度確認してみますね.
> なんかボケてるような気がしてきた...

一応、クエリ文字列のエンコーディング変換はスクリプトの実行前に行われるので、スクリプト中で設定を変更しても、動作に影響はありません。

# でも、これってすごく不便ですよね。遅延評価みたいな感じその辺の処理ができたら都合がいいんですが。

From karma @ jazz.email.ne.jp  Wed Mar 18 11:25:05 2009
From: karma @ jazz.email.ne.jp (KATOH Yasufumi)
Date: Wed, 18 Mar 2009 11:25:05 +0900
Subject: [PHP-dev 1460] Re:
 =?iso-2022-jp?b?bWJzdHJpbmcuaW50ZXJuZWxfZW5jb2Rpbmcg?=
 =?iso-2022-jp?b?GyRCJE5DTSQsSD8xRyQ1JGwkSiQkPmw5ZyQsJCIkazdvGyhCKDIp?=
In-Reply-To: 
References: <871vtgk0nw.wl%karma@jazz.email.ne.jp>
	<87fxhk5jvs.wl%karma@jazz.email.ne.jp>
	
	
	<87wsaowo79.wl%karma@jazz.email.ne.jp>
	
	<87vdq8wace.wl%karma@jazz.email.ne.jp>
	
Message-ID: <87mybj1sam.wl%karma@jazz.email.ne.jp>

加藤泰文です.

>>> On Wed, 18 Mar 2009 09:33:10 +0900
    in message   "[PHP-dev 1459] Re:	mbstring.internel_encoding の値が反映されない場合がある件(2)"
                  Moriyoshi Koizumi-san wrote:

> 一応、クエリ文字列のエンコーディング変換はスクリプトの実行前に行われ
> るので、スクリプト中で設定を変更しても、動作に影響はありません。

あ,やっぱり.そうかと思って今から追ってみようかと思ってました.(^_^;)

すっきりしました.ありがとうございます.(_o_)

あ,マニュアルの
| PHP スクリプトで HTTP 入力文字変換を制御する手段はありません。 HTTP
| 入力文字変換を無効にするには、php.ini  で行う必要があります。 
ってのがソレの説明かあ.

> # でも、これってすごく不便ですよね。遅延評価みたいな感じその辺の処理
> # ができたら都合がいいんですが。

そうですねぇ..htaccess すら書けない,という不便な環境があった場合,ど
うしようもなくなりますねぇ.そういう環境があるのか良く分かりませんが...

-- 
==============================================
((((    加藤泰文
○-○                karma @ jazz.email.ne.jp
==============================================
 (Web Page) http://www.ne.jp/asahi/ka/to/
==============================================