« Fedora 7 リリース | トップページ | エクスプローラでRapidSVN風表示 »

2007年6月 6日 (水)

Smartyを使っていてApacheが落ちた

PHPでの開発中、突如として以下のようなログを吐いてApacheが落ちる現象が発生した。

[notice] Parent: child process exited with status 3221225477 -- Restarting.

「確実にこのリンクを踏むと落ちる」というのは分かったので、ともかく追跡を開始。

結果的に、相互参照しているオブジェクトをSmartyのテンプレートにアサインした状態で、Smartyのデバッグコンソールを表示させると落ちるということが判明した。

以下、実証コード。

class A {
var $class_b;

function A () {
$this->class_b = new B($this);
}
}

class B {
var $class_a;

function B ($class_a) {
$this->class_a = $class_a;
}
}

set_include_path('.;c:/php/smarty/libs');
require 'Smarty.class.php';
$a = new A();
$smarty = new Smarty;
$smarty->debugging = true;
$smarty->assign("Infinite loop", $a);
$smarty->display('index.tpl');

デバッグコンソールの中で、オブジェクトのプロパティを列挙する際に、
オブジェクトを発見すると再帰呼び出しが起こるのだが、
再帰の階層を制限していないので、オブジェクトが相互参照していると
無限ループ化するようだ。

とりあえず、以下の関数に1行追加することで回避。

[smarty/libs/plugins/modifier.debug_print_var.php:23行目]
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
{
    //block infinite loop
    if ($depth > 20) return '';

20という数字に特に意味はない。まぁ、オブジェクトが階層化するにしても、
ここまで深くすることはないだろうと。(10でもいいぐらいだが、念のため)

とりあえず、Smartyのフォーラムにも同様のコードを書いておこう。
しょーもないバグなので、次のバージョンでは修正されてほしい。

2007/06/07追記:

Smarty開発者のmessju氏からコメントをいただき、「それで正しい。
直ると思わないでくれ」と言われてしまったので、とりあえずこの状態で
放置のようです。

ま、相互参照なんて作るほうがいけないという話もありますしね。

|

« Fedora 7 リリース | トップページ | エクスプローラでRapidSVN風表示 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/161557/15337941

この記事へのトラックバック一覧です: Smartyを使っていてApacheが落ちた:

« Fedora 7 リリース | トップページ | エクスプローラでRapidSVN風表示 »