これは何?
- PHPでDebugの方法を確認したくて、わざとSegmentation Faultを出して、Debugしてみるやり方をメモしたもの。
事前準備
- PHP + Apache を導入しておく。
sudo yum install -y php-devel
PHPのソースの導入
- 事前準備で導入したバージョンと同じPHPのソースを入手。
- 入手先の詳細は、http://php.net/git.php で参照。
$ git clone https://github.com/php/php-src.git
$ git checkout PHP-5.3 # これは任意のバージョン
PHPのモジュールを作る
わざとSegmentation Faultを出すPHPモジュールを作る。
まず、ひな形を作る
$ cd php-src/ext
$ ./ext_skel --extname=xxxx //xxxxは作りたいモジュール名
$ cd xxxx
次に、php_xxxx.hファイルを編集する。
PHP_FUNCTION(xxxx);
次に、xxxx.cファイルを編集する。
function_entry Down_functions[] =
{
PHP_FE(xxxx, NULL)
{NULL, NULL, NULL}
};
zend_module_entry Down_module_entry =
{
STANDARD_MODULE_HEADER,
"Down",
Down_functions,
NULL,
NULL,
NULL,
NULL,
NULL,
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
PHP_FUNCTION(xxxx)
{
char *ptr = NULL ;
strcpy(ptr, "down") ;
}
config.m4 下記の行頭delをはずす(16行目位)
PHP_ARG_ENABLE(helloworld, whether to enable helloworld support,
Make sure that the comment is aligned:
[ --enable-helloworld Enable helloworld support])
インストール
$ sudo phpize
$ ./configure
$ make
$ sudo make install
動作確認
$php xxxx.php
Functions available in the test extension:
confirm_down_method_compiled
Segmentation fault (core dumped)
ちゃんとCoreDumpになりました。
xxxx.php はモジュールをMakeをすると自動的に生成されます。
apacheでデバッグ
php.ini 下記を追加
extension=xxxx.so
httpd.conf 下記を追加
CoreDumpDirectory /tmp
apacheリスタート
sudo service httpd restart
先ほどの、xxxx.php
をHTTPでアクセス出来る領域にコピーして、アクセスしてみる。アクセスログを見てみると・・・期待通りにエラーが出ています。
[Sun Feb 01 17:39:25 2015] [notice] child pid 29222 exit signal Segmentation fault (11), possible coredump in /tmp
debug
pid をキーにして、gdbを実行してみると、xxxx.cで落ちていると指摘されている。狙い通り。
$ sudo gdb /usr/sbin/httpd /tmp/core.29222
(略)
Core was generated by `/usr/sbin/httpd'.
Program terminated with signal 11, Segmentation fault.
# 0 zif_confirm_down_method_compiled (ht=1, return_value=0x7fa80c6ac6c0,
return_value_ptr=0x0, this_ptr=0x0, return_value_used=1)
at /home/azureuser/php-src/ext/down_method/xxxx.c:162
162 strcpy(arg,"down");
Missing separate debuginfos, use: debuginfo-install httpd-2.2.15-39.el6.centos.x86_64
その他
(gdb) where // traceを見る事ができる
Segmentation Fault が起きる理由/可能性とか。
PHPをPrefowrkで動かすべきところを、Workerで動かしていた
# 1 0x00000000004657f7 in ap_worker_pod_check (pod=) at pod.c:57
下記コマンドで現在動いているMPMが確認できる。
$ apachectl -V | grep "Server MPM"
ImageMagick の場合
StackOverFlow の場合