php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72057 PHP Hangs when using custom error handler and typehint
Submitted: 2016-04-19 12:14 UTC Modified: 2016-04-21 02:44 UTC
From: php dot net at koesen dot nl Assigned: laruence
Status: Closed Package: *General Issues
PHP Version: 7.0.5 OS: at least OSX/Linux
Private report: No CVE-ID:
 [2016-04-19 12:14 UTC] php dot net at koesen dot nl
Description:
------------
PHP Hangs when using custom error handler and typehinting.

I've minimised it into a small reproduceable case, see below.

It hangs on both my OSX with my brew 7.0.5 installation, as well as in my ubuntu VM running 7.0.4-7+deb.sury.org~trusty+2.


Strace:

```
vagrant@dev:/tmp$ strace php test.php
[..]
write(1, "execute the test..", 18execute the test..)      = 18
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5697085000
munmap(0x7f5697085000, 2097152)         = 0
mmap(NULL, 4190208, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5696e86000
munmap(0x7f5696e86000, 1548288)         = 0
munmap(0x7f5697200000, 544768)          = 0
madvise(0x7f5697000000, 2097152, MADV_HUGEPAGE) = 0
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5696e00000
madvise(0x7f5696e00000, 2097152, MADV_HUGEPAGE) = 0
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5696c00000
madvise(0x7f5696c00000, 2097152, MADV_HUGEPAGE) = 0
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|0x40000, -1, 0) = -1 ENOMEM (Cannot allocate memory)
mmap(NULL, 2097152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5696a00000
madvise(0x7f5696a00000, 2097152, MADV_HUGEPAGE) = 0

^CProcess 28055 detached

vagrant@dev:/tmp$ time php test.php
execute the test..^C

real	0m39.198s
user	0m35.877s
sys	0m0.960s

```

Notice that nothing happens, it just hangs, and I ctrl-c out of it 40 seconds later.


The GDB trace:

```
vagrant@dev:/tmp$ gdb /usr/bin/php
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/php...(no debugging symbols found)...done.
(gdb) run test.php
Starting program: /usr/bin/php test.php
Warning: couldn't activate thread debugging using libthread_db: Cannot find new threads: generic error
Warning: couldn't activate thread debugging using libthread_db: Cannot find new threads: generic error
warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
execute the test..^C
Program received signal SIGINT, Interrupt.
0x00005555557cfd8d in zend_hash_func ()
(gdb) bt
#0  0x00005555557cfd8d in zend_hash_func ()
#1  0x00005555557ba53d in zend_hash_find ()
#2  0x00005555557dd0d7 in zend_std_read_property ()
#3  0x00005555557b2094 in zend_read_property ()
#4  0x00005555557c76a7 in zend_exception_set_previous ()
#5  0x000055555563778f in zend_throw_exception_internal ()
#6  0x00005555556378db in zend_throw_exception ()
#7  0x0000555555636a3c in zend_throw_error ()
#8  0x00005555557f132e in ?? ()
#9  0x00005555557e3d6b in execute_ex ()
#10 0x0000555555798df9 in dtrace_execute_ex ()
#11 0x00007ffff5b9a9cf in xdebug_execute_ex (execute_data=0x7ffff6013180) at /build/xdebug-4Itzjs/xdebug-2.4.0/xdebug-2.4.0/xdebug.c:1890
#12 0x0000555555821400 in ?? ()
#13 0x00005555557e3d6b in execute_ex ()
#14 0x0000555555798df9 in dtrace_execute_ex ()
#15 0x00007ffff5b9a9cf in xdebug_execute_ex (execute_data=0x7ffff6013030) at /build/xdebug-4Itzjs/xdebug-2.4.0/xdebug-2.4.0/xdebug.c:1890
#16 0x000055555582cb2f in zend_execute ()
#17 0x00005555557a8434 in zend_execute_scripts ()
#18 0x000055555574c308 in php_execute_script ()
#19 0x000055555582e70b in ?? ()
#20 0x000055555563c5d0 in main ()
(gdb) quit
A debugging session is active.

	Inferior 1 [process 489] will be killed.

Quit anyway? (y or n) y
vagrant@dev:/tmp$
```


Interesting/important note: if you remove the typehints (so run it like: 'public function undefinedConst($score, $scale) { [..] }' the script works as expected and does _not_ hang.

Test script:
---------------
<?php
set_error_handler(
    function($errno, $errstr, $errfile, $errline) {
        throw new Exception("My custom error");
    }
);

class Foo {
    public function undefinedConst(int $score, int $scale) {
        return $scale !== self::UNDEFINED_CONST;
    }

    public function missingParam(int $score, int $scale) {
        return undefinedMethod();
    }
}

$foo = new Foo();
$foo->undefinedConst('7,2', 2); # this hangs
$foo->missingParam('7,2', 2); # and this as well


Expected result:
----------------
An exception being thrown.

Actual result:
--------------
The PHP process hangs with unable to allocate memory.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-19 12:54 UTC] php dot net at koesen dot nl
I forgot to mention another important note:

If you change the parameter '7,2' to '7.2' (comma to dot) it also works as expected.
 [2016-04-19 16:34 UTC] inefedor at gmail dot com
Opened a PR with fix at https://github.com/php/php-src/pull/1872
 [2016-04-20 07:28 UTC] php dot net at koesen dot nl
That's fast! Thanks a lot Nikita :)
 [2016-04-21 02:44 UTC] laruence@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: laruence
 [2016-04-21 02:44 UTC] laruence@php.net
The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Aug 20 21:01:35 2017 UTC