Hatena::ブログ(Diary)

Islands in the byte stream

2010-10-06

Xslateが特定の条件で落ちる件(fixed in 0.2009)

Xslateが特定の条件で落ちるという現象がいくつか確認されていました。

Xslateでテンプレート大きいと困った件 ←修正されました - pepponの日記

id:pepponさんの記事を参考に巨大なファイルを生成してrender()したところ、5.8.9でSEGV、5.12.2で致命的エラーとなって落ちることを確認したため、修正してXslate 0.2009をリリースしました。ご確認ください。

これは、Xslateではなくperl正規表現エンジンのバグ(あるいは限界)であったようです。

5.12.2で出力されるエラーメッセージに対するperldiagのエントリは以下の通り:

Complex regular subexpression recursion limit (%d) exceeded

(W regexp) The regular expression engine uses recursion in complex

situations where back-tracking is required. Recursion depth is

limited to 32766, or perhaps less in architectures where the stack

cannot grow arbitrarily. ("Simple" and "medium" situations are

handled without recursion and are not subject to a limit.) Try

shortening the string under examination; looping in Perl code (e.g.

with "while") rather than in the regular expression engine; or

rewriting the regular expression so that it is simpler or

backtracks less. (See perlfaq2 for information on Mastering

Regular Expressions.)

(適当訳)

複雑な正規表現の再帰が限界を越えた

正規表現エンジンは、バックトラックが必要な複雑なシチュエーションに対しては再帰を使う。

再帰の深さは32766であるが、スタックを伸ばすことのできないアーキテクチャではもっと少ないかもしれない。

(単純なシチュエーションでは再帰は使わないので、この限界は存在しない。)

検査する文字列を短くするか、正規表現エンジンではなくPerlコードにループを落とし込むか、バックトラックしないように正規表現を書き直してみるとよい。

確かにXslateのケースではバックトラックを行うような正規表現でコンパイル済みテンプレートを解析していたのでした。

最新版では、コンパイル済みテンプレートをData::MessagePackを使ってセーブ/ロードするようにしたので、この問題は発生しません。よって、テンプレートファイルを巨大にしたことで落ちることはなくなったはずです。

tokuhiromtokuhirom 2010/10/07 07:42 あー、バックトラックをつかう正規表現はSEGVうむから、普通つかわないねー。

pepponpeppon 2010/10/07 08:51 問題なく利用できるようになりました!

gfxgfx 2010/10/07 09:17 > tokuhirom
あ…そういうもんすか。バックトラックは遅いのでなるべく使わない方がいい、くらいにしか思ってなかった。5.12.2にしたところでSEGVしないまでもいきなり死ぬので、入力データサイズが不明な時はバックトラックは避けた方がいいのね。

> peppon
SEGVってすみません!なおってよかったです!

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証