出现原因
程序加载一个不停在变化的文件,会出现bus error
原因
通过gdb发现在进行语法解析时,内存越界
php环境
Configure Command => ‘./configure’ ‘–prefix=/tmp/php56’ ‘–enable-fpm’ ‘-enable-debug’
没有opcache,apc等缓存。即bus error的出现于opcode缓存没有关系
出现bus error的代码
//文件名 parse.php
<?php
if ($argv[1] > 0) {
while ($argv[1]--) {
file_put_contents('test.tpl', "<?php #".str_repeat('A', mt_rand(4000, 5000))." ?>\n", LOCK_EX);
}
} else {
$p2 = popen("php parse.php 100", "r");
while (1) {
include 'test.tpl';
}
}
执行 $php parse.php
会出现:
[1] 17776 bus error (core dumped) php parse.php
coredump调试
命令:gdb php core-php.15285
现象:
balabala...
Core was generated by `php parse.php'.
Program terminated with signal 7, Bus error
(gdb) bt
#0 0x00000000007f39a7 in lex_scan (zendlval=0x7fffc794b888) at Zend/zend_language_scanner.l:1863
#1 0x00000000008309a7 in zendlex (zendlval=0x7fffc794b880) at /home/yankai-c/php-5.6.25/Zend/zend_compile.c:6913
#2 0x00000000007e45ce in zendparse () at /home/yankai-c/php-5.6.25/Zend/zend_language_parser.c:3732
#3 0x00000000007ed208 in compile_file (file_handle=0x7fffc794bca0, type=2) at Zend/zend_language_scanner.l:586
#4 0x000000000067f21c in phar_compile_file (file_handle=0x7fffc794bca0, type=2)
at /home/yankai-c/php-5.6.25/ext/phar/phar.c:3371
#5 0x00000000007ed3bb in compile_filename (type=2, filename=0x7f3ea56146a8) at Zend/zend_language_scanner.l:629
#6 0x000000000089a120 in ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER (execute_data=0x7f3ea55db330)
at /home/yankai-c/php-5.6.25/Zend/zend_vm_execute.h:2988
#7 0x0000000000893367 in execute_ex (execute_data=0x7f3ea55db330)
at /home/yankai-c/php-5.6.25/Zend/zend_vm_execute.h:363
#8 0x00000000008933ea in zend_execute (op_array=0x7f3ea5611d88)
at /home/yankai-c/php-5.6.25/Zend/zend_vm_execute.h:388
#9 0x000000000084d76c in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /home/yankai-c/php-5.6.25/Zend/zend.c:1341
#10 0x00000000007b2a02 in php_execute_script (primary_file=0x7fffc794f3d0)
at /home/yankai-c/php-5.6.25/main/main.c:2613
#11 0x0000000000904f71 in do_cli (argc=2, argv=0x2d9ecf0) at /home/yankai-c/php-5.6.25/sapi/cli/php_cli.c:994
#12 0x000000000090602e in main (argc=2, argv=0x2d9ecf0) at /home/yankai-c/php-5.6.25/sapi/cli/php_cli.c:1378
(gdb) p (*(struct _zval_struct*)0x7fffc794b888)
$1 = {value = {lval = 139907039412224, dval = 6.9123261784937185e-310, str = {
val = 0x7f3ea562c000 <Address 0x7f3ea562c000 out of bounds>, len = 6}, ht = 0x7f3ea562c000, obj = {
handle = 2774712320, handlers = 0x6}, ast = 0x7f3ea562c000}, refcount__gc = 2673624600, type = 1 '\001',
is_ref__gc = 127 '\177'}
(gdb) p (*(znode*)0x7fffc794b880).u.constant.value.str.val
$26 = 0x7f3ea562c000 <Address 0x7f3ea562c000 out of bounds>
说明:最后对zendlex的参数进行打印,可以看到提示内存越界。
在bus error文章中提到,出现bus error
的原因是加载了损坏的文件(broken file)。对于平时编程而言,加载损坏的文件是不能接受的。