APC 3.0.19 on Solaris10(sparc)
Twitterで自分のTimelineを汚しまくった件ですが、まとめ?として。
Solaris10(sparc)の環境下でapc.stat=0にすると落ちるようです。apc.stat=0にしない限り大丈夫なようです。
この設定を変更する場合は十分注意してください。デフォルト設定は On で、 これは、ファイルが変更されていないかどうかを スクリプトの実行のたびに APC が調べ、 もし変更されていれば、再コンパイルして新しいバージョンをキャッシュします。 この設定を Off にすると、変更されているかどうかがチェックされません。 つまり、変更内容を有効にするには Web サーバを再起動する必要があるということです。 実運用環境ではコードを変更することはめったにないでしょうから、 この設定を Off にしておくことでパフォーマンスを大きく向上させられます。
PHPマニュアルには上記のように書かれており、パフォーマンスを大きく向上させられるなんて大変魅力的なオプションなのですが、自分の戦場だと使えないので意味が無い。_| ̄|○
自分は全く関与していないのですが(諸事情により)このオプションを「何としてでも」使わないといけない状況になってしまったので(なんで自分が?って感じですが)解決に向けて調べてみました。
まずは環境面からの調査。調査結果は以下の通り。
・apc.stat=1 Debien Etch(x86)=> OK Solaris10(sparc)=> OK Solaris10(x86) => OK ・apc.stat=0 Debien Etch(x86)=> OK Solaris10(sparc)=> NG Solaris10(x86) => OK
調査結果からsparc環境に起因する問題と仮定。真っ先に考えられるのはエンディアンやアライメント関係。
アフォなログを残しつつ(まずは)落ちている箇所を調べてみましたが、apc_cache.c関数内で用意されているstring_nhash_8関数内で落ちているようでした。
この関数はファイル名と長さを引数にして、戻り値としてハッシュ値(と書くと語弊があるかもしれませんが)を返す関数なのですが、この関数が発動された時点で落ちているので、この実装がイケてないみたい。
現時点での最新バージョンは3.1.3p1(まだbeta版)なのですが、こちらの実装を(念の為)確認してみたところ。。。実装が変わってやんの。_| ̄|○
3.1.3p1での実装がZend/zend_hash.h内にあるzend_inline_hash_func関数を使うように変更されていたので、その通りに変更してみたところ、sparc環境でも問題なく動作することでできました。zend_inline_hash_func関数は出来る子でした。偉いぞ。(w
対象は限りなく限定されるかと思いますが、一応、差分を晒しておきます。
--- APC-3.0.19,orig/apc_cache.c 2008-05-15 15:45:27.000000000 +0900 +++ APC-3.0.19/apc_cache.c 2009-09-03 11:54:13.900595000 +0900 @@ -62,24 +62,7 @@ /* }}} */ /* {{{ string_nhash_8 */ -static unsigned int string_nhash_8(const char *s, size_t len) -{ - register const unsigned int *iv = (const unsigned int *)s; - register unsigned int h = 0; - register const unsigned int *e = (const unsigned int *)(s + len - (len % sizeof(unsigned int))); - - for(;iv<e;iv++) { - h += *iv; - h = (h << 7) | (h >> ((8*sizeof(unsigned int)) - 7)); - } - s = (const char *)iv; - for(len %= sizeof(unsigned int);len;len--) { - h += *(s++); - } - h ^= (h >> 13); - h ^= (h >> 7); - return h; -} +#define string_nhash_8(s,len) (unsigned int)(zend_inline_hash_func(s, len)) /* }}} */ /* {{{ make_slot */
gist.githubにも登録しておきました。
こういう風に書くとサラっと解決したように感じられますが、実際には解決までの道のりは大変でした。。。デバッグ・ログを入れすぎたせいで(ロック処理よりも前にデバッグ・ログを入れたせいで、スレッド間で潰しあいみたいなことがおきたり)余計に混乱しつつ、どうでもよいところを調査していたりと、結局は自分で自分の首を絞めていたダケなんだけどさ。自分の手際の悪さに脱帽です。吐き気がするわ。_| ̄|○
もう体力にモノを言わせて力任せにやれる年齢でもないので、頭をつかっていきたいところです。そのうち倒れそう。
確かに自分の環境は他と少し違うのは否めません。他の環境とと比べて酷い目に合いやすいし、解決しようにも事例が少なかったりと切ない状況に陥りがちですが、そういう環境だからこそ他では体験できないようなことが体験できたりと(もしかしたら)人生において得をしているのかもしれません。。。酷い目のほうが多いけどな!久々に「sparc環境なんて無くなってしまえばよいのに」と思ってしまいました。
ただ、最近よく思うのは、他とは違う環境を上手く活用できていない気がしていて「もったいないなぁ」と感じています。深堀しない自分が悪いんだと思いますけど。なんか良い使い道があるといいんですけどね。