PHPがsegmentation faultで死ぬ原因を追跡する
発端
WordPressで構築されたサイトで 502 Proxy Error
が出る、という問題が発生した。
[LB] -> [Reverse proxy] -> [Webサーバ]
という構成のため、ユーザへ返るステータスコードは Reverse proxy
が吐いてる。
ここが 502 Proxy Error
となるのは、プロキシした先の Webサーバ
でhttpdプロセスが異常終了してしまっている事が原因だった。
※ちなみに今回PHPのセグフォでhttpdが死んでいるのは、dsoだったため。httpdから生えたcgiだった場合、cgiのセグフォをhttpdが検知できるので、恐らく500エラーを返すことになる
なぜ異常終了しているかを調べた(未解決)
- httpdのエラーログを見ると、プロセスがセグフォで死んでいることがわかる。
[Wed Nov 30 11:53:51.240210 2016] [core:notice] [pid 16547] AH00052: child pid 18079 exit signal Segmentation fault (11)
- straceでセグフォで死ぬプログラムをみてみると
brk
システムコールを呼び続けて最後に死んでた
brk(0x5631000) = 0x5631000 brk(0x5671000) = 0x5671000 brk(0x56b1000) = 0x56b1000 brk(0x56f1000) = 0x56f1000 brk(0x5731000) = 0x5731000 brk(0x5771000) = 0x5771000 brk(0x57b1000) = 0x57b1000 brk(0x57f1000) = 0x57f1000 brk(0x5831000) = 0x5831000 brk(0x5871000) = 0x5871000 brk(0x58b1000) = 0x58b1000 --- SIGSEGV (Segmentation fault) @ 0 (0) --- +++ killed by SIGSEGV +++
brkシステムコール直前 wp-content/cache/object/
とキャッシュを触っており、キャッシュ関連のプラグインが怪しいと目星がついたので、試しにそのプラグインを無効化すると、本問題は発生しなくなった。
プラグイン無効化で終わり、でもいいが、なぜセグフォするのかもう少し調査
- 次にcore dumpを吐かせた
# coreファイルのサイズ制限を外す $ ulimit -c unlimited # 確認 $ ulimit -a | grep core # 問題のコードを実行する # カレントディレクトリにcoreがはかれる $ ls -l core.19380 # fileコマンドで何のプログラムでセグフォしたcoreかみれる $ file core.19380 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, from '/usr/local/php/bin/php-cgi sample.php' # gdbで解析 $ gdb /usr/local/php/bin/php-cgi -c core.19380 (略) Core was generated by `/usr/local/php/bin/php-cgi sample.php'. Program terminated with signal 11, Segmentation fault. #0 zend_parse_arg (arg_num=1, arg=0x5e4a6b8, va=0x7ffdbf6cd110, spec=0x7ffdbf6cd0c8, quiet=0, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_API.c:686 686 /tmp/php-build/source/5.6.21/Zend/zend_API.c: そのようなファイルやディレクトリはありません. in /tmp/php-build/source/5.6.21/Zend/zend_API.c (略) (gdb) bt #0 zend_parse_arg (arg_num=1, arg=0x5e4a6b8, va=0x7ffdbf6cd110, spec=0x7ffdbf6cd0c8, quiet=0, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_API.c:686 #1 0x000000000089dec3 in zend_parse_va_args (num_args=<value optimized out>, type_spec=0xa2b863 "s", va=0x7ffdbf6cd110, flags=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_API.c:873 #2 0x000000000089e7d6 in zend_parse_parameters (num_args=1, tsrm_ls=0x1b350c0, type_spec=<value optimized out>) at /tmp/php-build/source/5.6.21/Zend/zend_API.c:924 #3 0x00000000008a8464 in zif_defined (ht=<value optimized out>, return_value=0x5dff408, return_value_ptr=<value optimized out>, this_ptr=<value optimized out>, return_value_used=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_builtin_functions.c:735 #4 0x000000000091bf93 in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:558 #5 0x0000000000909c4b in execute_ex (execute_data=0x5e4a610, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:363 #6 0x000000000091c44e in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:592 #7 0x0000000000909c4b in execute_ex (execute_data=0x5e4a3d0, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:363 #8 0x000000000091c44e in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:592 #9 0x0000000000909c4b in execute_ex (execute_data=0x5e49b38, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:363 #10 0x000000000091c44e in zend_do_fcall_common_helper_SPEC (execute_data=<value optimized out>, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:592 #11 0x0000000000909c4b in execute_ex (execute_data=0x5e499d0, tsrm_ls=0x1b350c0) at /tmp/php-build/source/5.6.21/Zend/zend_vm_execute.h:363 (略)
Zend/zend_vm_execute.h:363行目
と Zend/zend_vm_execute.h:592行目
が無限につづいていた。
なんでこうなるのかよくわかってない。Zendのバグなんじゃないの?とか思って眺めてた。
また、上記の問題は thread safe版
の場合。試しに同じconfigureオプションで作った non thread safe版
を使用して同じプログラムを実行させると、セグフォはおきなかった。
その代わりに brk
システムコールを無限に実行し続けて memory_limit
の値に引っかかってた。
試しに1GBほど割り当てても同様に全て食いつぶしてメモリ不足になってたので、やっぱりZendのバグなんじゃないの?とか思ってる。
ここからどうすれば根本的な原因(もしあるならバグの箇所)までたどり着けるのか、調べ方がわからない。勉強しようと思った
追記: 原因と思われるもの
IIJmio みおふぉんへMNPで乗換希望の人に見せるページ
身内や知人にちょいちょい聞かれるので、まとめとく。 内容間違ってたらすいません
IIJmio みおふぉん?
IIJのやってる音声通話付の格安SIMサービスのこと。 docomo回線とau回線を使用しており、自分が使っている限り通信速度に不満無し。
特徴
- 前述の通り、回線品質は良い
- 音声通話付の場合、12ヶ月以内の解約は
(12ヶ月 - 使用した月数) * 1,000円
かかる。それ以降、いつでもOK - 高速データ通信残量は翌月持ち越し可能。ミニマムスタートプランでは
3GB/月
付与され、2.5GB使った場合、翌月は3.5GB使える
プラン(一人(SIM一枚)向け)
- (最安) 通話可能で3GB/月 高速通信可能 音声通話は従量課金・3GB使用後は低速で使い放題
ミニマムスタートプラン 900円 + 音声通話付帯 700円 + その他雑費 = 約1,800円(税込み)
- 5分以内通話し放題で3GB/月 高速通信可能
ミニマムスタートプラン 900円 + 音声通話付帯 700円 + かけ放題 830円 + その他雑費 = 約2600円(税込み)
プラン(複数人(SIM複数枚)向け)
- SIM2枚通話可能で月10GB(全体で共有)
ファミリーシェアプラン 2560円 + (音声通話付帯 700円 * 2枚) + その他雑費 = 約4,300円(税込み)
- SIM3枚通話可能で月10GB(全体で共有)
ファミリーシェアプラン 2560円 + (音声通話付帯 700円 * 3枚) + その他雑費 = 約5,000円(税込み)
- SIM4枚通話可能で月10GB(全体で共有)
ファミリーシェアプラン 2560円 + (音声通話付帯 700円 * 4枚) + (追加SIM利用(4枚目以降) 400円 * 1枚)+ その他雑費 = 約6,300円(税込み)
注意事項
- 通話料金まあまあ高い。
20円/30秒
基本、みおふぉんダイヤルというアプリを利用するので、実質は10円/30秒
- SIMサイズ変更時に費用がかかる
2000円/1回
- 初期費用がかかる
3000円
- MNP転入できるのは、みおふぉんと3大キャリアの契約者名が同じ場合のみ
- 結構罠で、夫婦のキャリアまとめるときに面倒。キャリア側で名義変更をやっておかなくてはいけない。
- オンライン申込だと利用できない期間が発生する
- 即日利用したい場合は店舗でやるとよさそう
申込の流れ
- 端末用意
- 別にSIMフリーじゃなくてもdocomoまたはauの端末がそのまま使えるっぽい
- キャリア同様、端末を割賦購入するプランもある
- たとえば ASUS ZenFone 3 Laserなら24回払いで
1,200円/月
なので、最安プランと併用すると1,200円 + 1,800円 = 約3,000円/月
- IIJmio会員登録
- クレカと本人確認書類がいる
- MNP転出予約番号の取得
- 契約中のキャリアにネットか電話で取得できる
- MNP転出予約番号をもってみおふぉんの申込
やっておくこと
- キャリアの解約可能月確認
- だいたい二年毎に一ヶ月間解約料かからない月がある。要確認
やらなくていいこと
- キャリアへの解約依頼
- MNP転入完了をもって解約になるっぽい
実際いくら払ってんの?
自分 + 妻で音声通話付きのSIMを2枚利用中。10GB使えるので、動画やkindle本ダウンロードなど余り気にせずやっても足りてる。
請求金額の実績は以下
妻実家との通話が結構多くて、毎月 1,400円
くらいかかってる。受ける専用だったら 4000円で済むのに…
2016年08月 5,436円 2016年09月 5,350円 2016年10月 5,530円
まとめ
- iPhoneやXperiaZシリーズのような、10万円近くするスマホの場合、割賦が使えないから一括で買わなくちゃいけなくてちょっと辛い
- もし金利無しの24回払いできても端末だけで
4,000円/月
なので毎月の支払いは最安プランでも6000円くらい - キャリアとあんまりかわらない。解約月の縛りないからそれでもこっちがお得だとは思う
- もし金利無しの24回払いできても端末だけで
- タブレットなんか買い足すときにデータ通信専用SIMだったら、SIM追加手数料だけで増やせるからすごい助かる
最後に
申し込む人は以下からよろしく
または
紹介コード 633 5790 8195 4353
5人紹介すると、なんと バッジ
がもらえるらしい
puppetのfileで「/」のパーミッション操作を行うと怒られる
こんなやつ
file { '/': ensure => directory, owner => 'root', group => "root", mode => 444; }
実行すると以下のように怒られる
Failed to apply catalog: Parameter path failed on File[/]: File paths must be fully qualified, not ''
「/.」でかくとよかった
file { '/.': ensure => directory, owner => 'root', group => "root", mode => 444; }
こういう時のググり力が低くて、なんて調べたらでてきたんだろうか
ポート番号とプロトコル名の組み合わせをすぐ忘れるからAlfredのワークフローにした
https://github.com/tap1ra/alfred/tree/master/port2protocolalfred/port2protocol at master · tap1ra/alfred · GitHub
ヤケクソ感が否めないけど意外と便利 その場しのぎなので、いずれちゃんとしたい
(追記) dojineko/listo という便利ツールがあったので乗り換え
githubにスタイルあてとくと見易い
https://github.com/tap1ra/md-sample/issues/1 みたいに、横に長いテーブルがあると、デフォルトの画面だとちょっと見づらい。
こんな感じ
拡張機能を使って横に広げるとみやすくなった
こうなる