- 本文地址: https://www.laruence.com/2008/12/31/647.html
- 转载请注明出处
PHP是个脚本语言, 错误定位容易, 编写起来速度较快..但是, 如果遇到了PHP自身的一些问题,那就会让人很恼火.
最近遇到一个很低概率的Core dump(大概是2年才出现一次), 经过和同事一起仔细分析,跟踪,终于找出了原因, 拿出来与大家分享.
先看Core文件展示的堆栈:
(gdb) bt #0 0x000000302af2e2ed in raise () from /lib64/tls/libc.so.6 #1 0x000000302af2fa3e in abort () from /lib64/tls/libc.so.6 #2 0x000000302af62db1 in __libc_message () from /lib64/tls/libc.so.6 #3 0x000000302af6888e in _int_free () from /lib64/tls/libc.so.6 #4 0x000000302af68bd6 in free () from /lib64/tls/libc.so.6 #5 0x0000002a95bd4a8c in php_error_cb (type=1, error_filename=0x2a9755c608 "***********.php", error_lineno=272, format=Variable "format" is not available. ) at /home/huixinchen/php-5.2.4/main/main.c:803 #6 0x0000002a95c182ed in zend_error (type=1, format=0x2a95ebee68 "Maximum execution time of %d second%s exceeded") at /home/huixinchen/php-5.2.4/Zend/zend.c:976 #7 <signal handler called> #8 0x000000302af6ac02 in malloc () from /lib64/tls/libc.so.6 #9 0x000000302af6fc92 in strdup () from /lib64/tls/libc.so.6 #10 0x0000002a95bd4720 in php_error_cb (type=8, error_filename=0x2a9755c608 "******.php", error_lineno=272, format=Variable "format" is not available. ) at /home/huixinchen/php-5.2.4/main/main.c:807
左分析,右分析,结论如下。
在PHP execute limit time 信号来的时候,PHP正在出错处理函数中, 这个时候,事件被响应,再次重入php_error_cb函数, 观察php_error_cb函数:
static void php_error_cb(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args){ .... if (display) { if (PG(last_error_message)) { free(PG(last_error_message)); } if (PG(last_error_file)) { free(PG(last_error_file)); } PG(last_error_type) = type; PG(last_error_message) = strdup(buffer); PG(last_error_file) = strdup(error_filename); PG(last_error_lineno) = error_lineno; } .... }
我们可以看到,在php_error_cb中, 会对上一次的错误文件名进行free操作, 并对当前错误文件名分配内存.
如果, 当php执行到free了旧的错误文件名以后, 响应了事件, 于是分配新的错误文件名内存这一步并没有被执行..
这个时候, 事件响应以后,又再一次进入到了php_error_cb函数, 当再次执行free(PG(last_error_file))的时候, 会导致core dump
另外,发现PHP(*nix下)是通过调用setitimer来实现脚本超时处理的。
具体代码可以grep zend_set_timeout
转一个可以较大概率重现这个Core的脚本(By Lili):
<?php set_time_limit(1); while(1) { $a = $arr['index_miss']; $a = $arr['index_miss']; $a = $arr['index_miss']; $a = $arr['index_miss']; $a = $arr['index_miss']; $a = $arr['index_miss']; } ?>
Thank you so much.
[…] HTTP1.0下HTTP_HOST为空 一个巧妙的分页方法 31 Dec 08 一个低概率的PHP Core dump 21 Feb 09 PHP字符串比较 26 May 09 PHP+Gtk实例(求24点) […]
[…] crash的案例:深入理解PHP内存管理之一个低概率Core的分析和一个低概率的PHP Core dump , 在其中, 我说过, 其实PHP在关键操作的时候, […]
[…] 本文地址: http://www.laruence.com/2008/12/31/647.html […]
话说,为啥sudo ulimit -c unlimited 了,还是没有core dump的输入哩……当然,已经–enable-debug过了。
我想知道你是怎末左分析、右分析的。。。。。。
这个比较汗…
这种情况应该很少见吧,都到出错处理了刚好又到limit time了.
@truemyth, 恩,2年见一次.