WindowsのPHPでエラーが発生するので、スタックサイズを増やして解決する
経緯
俺「なんか(NDAなので略)でエラーがでるのですよ」
ベンダさん「ログください」
俺「これでよいでしょうか」
ベンダさん「Exception code:0xc00000fdのエラーコードはスタックオーバーフローです、常識です。editbinでバイナリを書き換えてください。」
俺「えっと…どういう…」
ベンダさん「今手順をいいましたよね?」
俺「アッハイがんばります」
*1
マカーは(Windows)世界の常識を知らぬ。
どういうことか
WindowsのApache+PHPでは、まあ、稀にスタックオーバーフローが出る事がある、らしい。
スタックは設定ファイル等ではふやせず、Apacheのhttpd.exeのバイナリをいじったらスタックサイズをふやせる、らしい。
PHPのエラーなんだけど、Apacheをいじる(mod_phpだからね)のはまあわかった。
それにはEditbin.exeをつかうらしい。ほほう。
正直きいた事がなかったのだけれど、
http://www.s-arcana.co.jp/tech/2012/03/apache-crashed-using-php-preg-match-all-on-windows.html
まあ割りとある話らしい。
ちなみに、このエントリは上の記事の劣化版なので、上の記事を読むと良い、以下はよまなくてよい、さようならみなさん。
さて、じゃあがんばって直そう。
スタックサイズを増やす?
前述のとおりだが、Windowsのバイナリはスタックサイズが既定されているらしく、それを後からツールでいじることができる。
できないバイナリ(ビルドで指定)もあるらしいが、少なくとも今回いわれたApacheのhttpd.exeはできるらしい。
editbin.exeはいずこ?
正直名前を聞いたことなかったし、どこにあるんだ…まさかNT4の頃みたいにリソースキットのCDROMに入ってるツールとかそういうことはないよな…とおもいつつググっても単体配布されはおらず、怪しげなウイルス満載感あふれるヤバげサイトでDLできる以外、単体でDLできる所がドンピシャみつからない。
20分ばかりググったらVSに同梱されている、という情報を知る。
Visual Studioは先日のエントリでも入れたが、あれはWeb用だし、多分リンカとかのCLIコマンドの親戚であろうツールは、デスクトッププログラムをビルドするエディションじゃないとはいってなさそう。
ということでVisual Studioを入手
Visual Studioというと有料という感じだが、ご存知の通りExpress版は30日は評価版、それ以後も登録すれば無償で使うことができる。
用途はライセンス上、制限は個人用途にかぎられ(略(ダメだ、炎上するやつだ)
Visual StudioでググればサイトがみつかってDLできるのだが、まあVisual Studioと名のつくものは山ほどあり、Expressと名のつくものもたくさんある。
オチから言えば、
http://www.microsoft.com/visualstudio/jpn/downloads#d-express-windows-8
こちらなかにある「Visual Studio Express 2012 for Windows Desktop」をDLした*2。
普通にインストーラーが走り、ライセンスキーを要求される所は今回キャンセ(略)。評価です!!!!
ということで、VSがはいった。
直後起動するVSの画面は速攻で閉じた。
で、editbin.exeはどこだ?
CLIのツールなのは想像がつくので、コマンドプロンプトからいきなりeditbinをたたいてみるが、うごかず、Pathは通ってないらしい。
c:\program files\Microsoft Visual Studio 11.0の中を探す…あった、VC\bin\editbin.exeだ。
これをcmdで起動すると、mspdb110.dllがないと言われる。そうなのか、ないのか。
ググると同一ディレクトリにあるvcvars32.batを先にうごかせや(環境変数などが反映される)ということらしい。これをまずcmdで実行して「同一のcmdでそのまま」editbin.exeを実行したら、うごいた!
ということで編集
httpd.exeを適当にコピーしていれておいて、
editbin /stack:(適切な数字*3 ) c:\tmp\httpd.exe
と実行する、なにもいわれないでコマンドは終了する。
変更がされたか確認はdumpbinである。
dumpbin /headers httpd.exe
で、
xxxxxx size of stack reserve
などと出力される。(xxxxは16進)
修正がおわったhttpd.exeをもどしてエラー再現すると…再現しない!やったで!ホームランや!!!
ところで、これIISの場合どうするんだろうな?FastCGIモードがあるらしいから、それでPHP側をいじれということになるのかな。
そもそもIISはスタックがデカいからおこらねーよ!という事かもしれぬ…、まあいいや、ぶち当たってからしらべよう(無精)
最後に
VSに感謝の念を抱きながらアンインストールした。