php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70891 opcache+exception = segfault in some cases
Submitted: 2015-11-11 14:28 UTC Modified: 2020-03-15 04:22 UTC
From: s dot chernomorets at gmail dot com Assigned: cmb (profile)
Status: No Feedback Package: opcache
PHP Version: 5.6.15 OS: centos5
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: s dot chernomorets at gmail dot com
New email:
PHP Version: OS:

 

 [2015-11-11 14:28 UTC] s dot chernomorets at gmail dot com
Description:
------------
When opcache disabled - no segfaults. I have tried last php version from  https://github.com/php/php-src/commits/PHP-5.6 (1a1240) 

I cannot reproduce segfault on small script, so code bellow is enough approximate (I know it very-very ugly code, but it works on php5.3+APC).
On my project segfault reproduces in 100% cases on the first HTTP-request.               

It seems, opcache broke cache of compiled scripts: when I move source code of function sql_assoc above or below of other function - no problem. When I return function on old place - segfault return also.



Test script:
---------------
//WARN: Code is very approximate! It uses PDO.

try {
    sql_assoc("SELECT which throw exception");                                                      
}catch(Exception $e)
{
    // we MUST catch exception here, but process killed by SIGSEGV                       
}

function sql_assoc($sql, $link = null)                                                        
{   
    return sql_fetch(sql_query($sql, $link));                                             
}                                                                                        
function sql_query($sql, $link = null)                                                    
{           
    return sql_get_connect($link)->query($sql);                                               
}               
                    
function sql_get_connect($link = null)                                                    
{                                                                                         
    if ($OurPDO = DBConnector::instance()->getConnection($link)) {                       
        return $OurPDO;
    } else {
        throw new Exception('...');
    }   
}   
 
function sql_fetch($result, $fetch_type = PDO::FETCH_ASSOC)                              
{
    sql_check_result($result); 
    return $result->fetch($fetch_type);                                                  
}   

function sql_check_result($result)                                                       
{   
    if (!($result instanceof OurPDOStatement)) {                                         
        throw new Exception('...');                                                      
    }   
}

Expected result:
----------------
Catched PDOException

Actual result:
--------------
Segmentation fault

$ gdb -x gdb.run /usr/sbin/httpd

GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
This GDB was configured as "x86_64-redhat-linux-gnu".
Reading symbols from /usr/sbin/httpd...(no debugging symbols found)...done.
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7fad000
[Thread debugging using libthread_db enabled]


Program received signal SIGSEGV, Segmentation fault.
0x00007ffff36b9cbd in zend_mm_check_ptr (heap=0x7ffff842ee80, ptr=0x600000000, silent=1,
    __zend_filename=0x7ffff3ce9bc8 "/home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h", __zend_lineno=1218, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_alloc.c:1384
1384            if (p->info._size != ZEND_MM_NEXT_BLOCK(p)->info._prev) {
(gdb)
(gdb) bt
#0  0x00007ffff36b9cbd in zend_mm_check_ptr (heap=0x7ffff842ee80, ptr=0x600000000, silent=1,
    __zend_filename=0x7ffff3ce9bc8 "/home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h", __zend_lineno=1218, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_alloc.c:1384
#1  0x00007ffff36bbb79 in _zend_mm_free_int (heap=0x7ffff842ee80, p=0x600000000,
    __zend_filename=0x7ffff3ce9bc8 "/home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h", __zend_lineno=1218, __zend_orig_filename=0x0, __zend_orig_lineno=0)
    at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_alloc.c:2068
#2  0x00007ffff36bd260 in _efree (ptr=0x600000000, __zend_filename=0x7ffff3ce9bc8 "/home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h", __zend_lineno=1218,
    __zend_orig_filename=0x0, __zend_orig_lineno=0) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_alloc.c:2440
#3  0x00007ffff373d66e in ZEND_HANDLE_EXCEPTION_SPEC_HANDLER (execute_data=0x7ffff7f21a98) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:1218
#4  0x00007ffff3739c97 in execute_ex (execute_data=0x7ffff7f21a98) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:363
#5  0x00007ffff3739d20 in zend_execute (op_array=0x7ffff924dc60) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:388
#6  0x00007ffff36e1858 in zend_call_function (fci=0x7fffffffb930, fci_cache=0x7fffffffb900) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_execute_API.c:829
#7  0x00007ffff3442580 in zim_reflection_method_invokeArgs (ht=2, return_value=0x7ffff959d998, return_value_ptr=0x7ffff7f20cd0, this_ptr=0x7ffff958fea8, return_value_used=0)
    at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/ext/reflection/php_reflection.c:3079
#8  0x00007ffff373a805 in zend_do_fcall_common_helper_SPEC (execute_data=0x7ffff7f20ce8) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:558
#9  0x00007ffff373b51c in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x7ffff7f20ce8) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:693
#10 0x00007ffff3739c97 in execute_ex (execute_data=0x7ffff7f20ce8) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:363
#11 0x00007ffff3739d20 in zend_execute (op_array=0x7ffff8b38a38) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:388
#12 0x00007ffff36f7c1d in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend.c:1341
#13 0x00007ffff365dd05 in php_execute_script (primary_file=0x7fffffffe090) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/main/main.c:2597
#14 0x00007ffff37a7d8f in php_handler (r=0x7ffff8775940) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/sapi/apache2handler/sapi_apache2.c:667
#15 0x00007ffff7fdaf4a in ap_run_handler ()
#16 0x00007ffff7fde3d8 in ap_invoke_handler ()
#17 0x00007ffff7fe8d3a in ap_internal_redirect ()
#18 0x00007fffecd94c70 in ap_make_dirstr_parent () from /home/chernomorets/test-httpd/modules/mod_rewrite.so
#19 0x00007ffff7fdaf4a in ap_run_handler ()
#20 0x00007ffff7fde3d8 in ap_invoke_handler ()
#21 0x00007ffff7fe8ee8 in ap_process_request ()
#22 0x00007ffff7fe60d0 in ?? ()
#23 0x00007ffff7fe21d2 in ap_run_process_connection ()
#24 0x00007ffff7fed389 in ?? ()
#25 0x00007ffff7fed589 in ?? ()
#26 0x00007ffff7fee0a7 in ap_mpm_run ()
#27 0x00007ffff7fc8058 in main ()
(gdb) list
1379                            return zend_mm_check_ptr(heap, ptr, 0 ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
1380                    }
1381            }
1382    #endif
1383
1384            if (p->info._size != ZEND_MM_NEXT_BLOCK(p)->info._prev) {
1385                    if (!silent) {
1386                            zend_debug_alloc_output("Invalid pointer: ((size="PTR_FMT") != (next.prev="PTR_FMT"))\n", p->info._size, ZEND_MM_NEXT_BLOCK(p)->info._prev);
1387                            had_problems = 1;
1388                    } else {
(gdb) p ptr
$1 = (void *) 0x600000000
(gdb) f 3
#3  0x00007ffff373d66e in ZEND_HANDLE_EXCEPTION_SPEC_HANDLER (execute_data=0x7ffff7f21a98) at /home/chernomorets/rpmbuild/BUILD/php-5.6.15.1/Zend/zend_vm_execute.h:1218
1218                                    efree((char *) call->fbc->common.function_name);
(gdb) p call->fbc->common.function_name
$2 = 0x600000000 <Address 0x600000000 out of bounds>
(gdb) p call->fbc->common
$3 = {type = 0 '\000', function_name = 0x600000000 <Address 0x600000000 out of bounds>, scope = 0x7ffff9a68901, fn_flags = 3391487952, prototype = 0x7ffff879b590,
  num_args = 4159838832, required_num_args = 32767, arg_info = 0x7ffff9155670}
(gdb)

cat gdb.run 
run -X -f apache.conf

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-11-11 16:18 UTC] s dot chernomorets at gmail dot com
opcache.optimization_level="0xffffffef" solves problem - no segfault

According to http://stackoverflow.com/questions/21181045/php-opcache-optimization-levels-what-are-they it means:
bit 4 - pass 5:
block optimization (the most expensive optimization pass which perform many different optimization patterns based on CFG - control flow graph)
 [2020-03-02 11:58 UTC] cmb@php.net
-Status: Open +Status: Feedback -Assigned To: +Assigned To: cmb
 [2020-03-02 11:58 UTC] cmb@php.net
Can you still reproduce this segfault with any of the actively
supported PHP versions[1]?

[1] <https://www.php.net/supported-versions.php>
 [2020-03-15 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed Oct 28 06:01:23 2020 UTC