Bug #72144 [Opn]: _emalloc_24 crash on recursive call
| From: | nikic@php.net | Date: | Tue, 24 May 2016 18:28:46 +0000 |
| Subject: | Bug #72144 [Opn]: _emalloc_24 crash on recursive call | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-201260@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72144&edit=1
ID: 72144
Updated by: nikic@php.net
Reported by: php at abiusx dot com
Summary: _emalloc_24 crash on recursive call
Status: Open
Type: Bug
Package: *Programming Data Structures
Operating System: Mac OS X 10.11
PHP Version: 7.0.6
Block user comment: N
Private report: N
New Comment:
Just to make sure: Did you check that the crash is not caused by a stack overflow? You have dtrace
enabled, so stack overflows are possible with simple function calls.
You suspect a bug in the Zend MM. This can be easily verified by running the program with
USE_ZEND_ALLOC=0 and seeing if the crash persists.
Should the crash still occur, try running the program under "USE_ZEND_ALLOC=0 valgrind"
and see if it prints any errors.
Previous Comments:
------------------------------------------------------------------------
[2016-05-24 18:15:49] php at abiusx dot com
I re-implemented the same logic as a Zend Extension. The same crash happens at the same exact point.
Using USE_ZEND_ALLOC=0 this is the error:
php(21970,0x7fff75d48000) malloc: *** error for object 0x7fbc5c1ac960: pointer being freed was not
allocated
This is the exact same error whether I use pure PHP code or Zend extension code to do the same
thing. Seems to depend on the size of the memory being utilized by the PHP process, if it is less
than a certain threshold, it doesn't crash (but then crashes a few statemenets later in the
same process, when only cutting out a few Kbytes).
I am pretty certain at this point that there's an error in Zend Memory Manager, specially with
regards to the way it handled zend objects in PHP 7. PHP 5+ are immune to this issue.
------------------------------------------------------------------------
[2016-05-24 18:15:42] php at abiusx dot com
I re-implemented the same logic as a Zend Extension. The same crash happens at the same exact point.
Using USE_ZEND_ALLOC=0 this is the error:
php(21970,0x7fff75d48000) malloc: *** error for object 0x7fbc5c1ac960: pointer being freed was not
allocated
This is the exact same error whether I use pure PHP code or Zend extension code to do the same
thing. Seems to depend on the size of the memory being utilized by the PHP process, if it is less
than a certain threshold, it doesn't crash (but then crashes a few statemenets later in the
same process, when only cutting out a few Kbytes).
I am pretty certain at this point that there's an error in Zend Memory Manager, specially with
regards to the way it handled zend objects in PHP 7. PHP 5+ are immune to this issue.
------------------------------------------------------------------------
[2016-05-03 14:30:27] php at abiusx dot com
Description:
------------
This bug is very hard to reproduce simplistically. It is deterministic and always happens on my PHP
7 (tested on both 7.0.5 and 7.0.6), but does not happen on PHP 5.4. PHP 7.0.6 --with-debug does not
crash either.
A core-dump backtrace is available below.
Basically a recursive function, which passes around a lot of arrays and references, is crashing,
very deep in the recursive part. Adding some heavy-duty code (like serialization of the array
causing the crash) makes PHP crash sooner in the recursion.
$ lldb -c /cores/core.99967
(lldb) target create --core "/cores/core.99967"
warning: (x86_64) /cores/core.99967 load command 121 LC_SEGMENT_64 has a fileoff + filesize
(0x29e73000) that extends beyond the end of the file (0x29e72000), the segment will be truncated to
match
warning: (x86_64) /cores/core.99967 load command 122 LC_SEGMENT_64 has a fileoff (0x29e73000) that
extends beyond the end of the file (0x29e72000), ignoring this section
Core file '/cores/core.99967' (x86_64) was loaded.
(lldb) bt
* thread #1: tid = 0x0000, 0x000000010200c267 phpd`_emalloc_24 + 52, stop reason = signal SIGSTOP
* frame #0: 0x000000010200c267 phpd`_emalloc_24 + 52
frame #1: 0x000000010207dfe8 phpd`ZEND_SEND_REF_SPEC_VAR_HANDLER + 125
frame #2: 0x000000010207de47 phpd`ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER + 82
frame #3: 0x0000000102069f10 phpd`execute_ex + 25
frame #4: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #5: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #6: 0x0000000102069f10 phpd`execute_ex + 25
frame #7: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #8: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #9: 0x0000000102069f10 phpd`execute_ex + 25
frame #10: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #11: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #12: 0x0000000102069f10 phpd`execute_ex + 25
frame #13: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #14: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #15: 0x0000000102069f10 phpd`execute_ex + 25
frame #16: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #17: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #18: 0x0000000102069f10 phpd`execute_ex + 25
frame #19: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #20: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #21: 0x0000000102069f10 phpd`execute_ex + 25
frame #22: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #23: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #24: 0x0000000102069f10 phpd`execute_ex + 25
frame #25: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #26: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #27: 0x0000000102069f10 phpd`execute_ex + 25
frame #28: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #29: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #30: 0x0000000102069f10 phpd`execute_ex + 25
frame #31: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #32: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #33: 0x0000000102069f10 phpd`execute_ex + 25
frame #34: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #35: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #36: 0x0000000102069f10 phpd`execute_ex + 25
frame #37: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #38: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #39: 0x0000000102069f10 phpd`execute_ex + 25
frame #40: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #41: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #42: 0x0000000102069f10 phpd`execute_ex + 25
frame #43: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #44: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #45: 0x0000000102069f10 phpd`execute_ex + 25
frame #46: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #47: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #48: 0x0000000102069f10 phpd`execute_ex + 25
frame #49: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #50: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #51: 0x0000000102069f10 phpd`execute_ex + 25
frame #52: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #53: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #54: 0x0000000102069f10 phpd`execute_ex + 25
frame #55: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #56: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #57: 0x0000000102069f10 phpd`execute_ex + 25
frame #58: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #59: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #60: 0x0000000102069f10 phpd`execute_ex + 25
frame #61: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #62: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #63: 0x0000000102069f10 phpd`execute_ex + 25
frame #64: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #65: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #66: 0x0000000102069f10 phpd`execute_ex + 25
frame #67: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #68: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #69: 0x0000000102069f10 phpd`execute_ex + 25
frame #70: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #71: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #72: 0x0000000102069f10 phpd`execute_ex + 25
frame #73: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #74: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #75: 0x0000000102069f10 phpd`execute_ex + 25
frame #76: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #77: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #78: 0x0000000102069f10 phpd`execute_ex + 25
frame #79: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #80: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #81: 0x0000000102069f10 phpd`execute_ex + 25
frame #82: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #83: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #84: 0x0000000102069f10 phpd`execute_ex + 25
frame #85: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #86: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #87: 0x0000000102069f10 phpd`execute_ex + 25
frame #88: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #89: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #90: 0x0000000102069f10 phpd`execute_ex + 25
frame #91: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #92: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #93: 0x0000000102069f10 phpd`execute_ex + 25
frame #94: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #95: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #96: 0x0000000102069f10 phpd`execute_ex + 25
frame #97: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #98: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #99: 0x0000000102069f10 phpd`execute_ex + 25
frame #100: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #101: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #102: 0x0000000102069f10 phpd`execute_ex + 25
frame #103: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #104: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #105: 0x0000000102069f10 phpd`execute_ex + 25
frame #106: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #107: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #108: 0x0000000102069f10 phpd`execute_ex + 25
frame #109: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #110: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #111: 0x0000000102069f10 phpd`execute_ex + 25
frame #112: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #113: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #114: 0x0000000102069f10 phpd`execute_ex + 25
frame #115: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #116: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #117: 0x0000000102069f10 phpd`execute_ex + 25
frame #118: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #119: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #120: 0x0000000102069f10 phpd`execute_ex + 25
frame #121: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #122: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #123: 0x0000000102069f10 phpd`execute_ex + 25
frame #124: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #125: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #126: 0x0000000102069f10 phpd`execute_ex + 25
frame #127: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #128: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #129: 0x0000000102069f10 phpd`execute_ex + 25
frame #130: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #131: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #132: 0x0000000102069f10 phpd`execute_ex + 25
frame #133: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #134: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #135: 0x0000000102069f10 phpd`execute_ex + 25
frame #136: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #137: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #138: 0x0000000102069f10 phpd`execute_ex + 25
frame #139: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #140: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #141: 0x0000000102069f10 phpd`execute_ex + 25
frame #142: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #143: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #144: 0x0000000102069f10 phpd`execute_ex + 25
frame #145: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #146: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #147: 0x0000000102069f10 phpd`execute_ex + 25
frame #148: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #149: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #150: 0x0000000102069f10 phpd`execute_ex + 25
frame #151: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #152: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #153: 0x0000000102069f10 phpd`execute_ex + 25
frame #154: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #155: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #156: 0x0000000102069f10 phpd`execute_ex + 25
frame #157: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #158: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #159: 0x0000000102069f10 phpd`execute_ex + 25
frame #160: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #161: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #162: 0x0000000102069f10 phpd`execute_ex + 25
frame #163: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #164: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #165: 0x0000000102069f10 phpd`execute_ex + 25
frame #166: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #167: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #168: 0x0000000102069f10 phpd`execute_ex + 25
frame #169: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #170: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #171: 0x0000000102069f10 phpd`execute_ex + 25
frame #172: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #173: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #174: 0x0000000102069f10 phpd`execute_ex + 25
frame #175: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #176: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #177: 0x0000000102069f10 phpd`execute_ex + 25
frame #178: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #179: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #180: 0x0000000102069f10 phpd`execute_ex + 25
frame #181: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #182: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #183: 0x0000000102069f10 phpd`execute_ex + 25
frame #184: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #185: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #186: 0x0000000102069f10 phpd`execute_ex + 25
frame #187: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #188: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #189: 0x0000000102069f10 phpd`execute_ex + 25
frame #190: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #191: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #192: 0x0000000102069f10 phpd`execute_ex + 25
frame #193: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #194: 0x000000010207cc78 phpd`ZEND_DO_FCALL_SPEC_HANDLER + 986
frame #195: 0x0000000102069f10 phpd`execute_ex + 25
frame #196: 0x000000010201e73d phpd`dtrace_execute_ex + 238
frame #197: 0x000000010206a142 phpd`zend_execute + 544
frame #198: 0x000000010202d6c2 phpd`zend_execute_scripts + 299
frame #199: 0x0000000101fd7cc4 phpd`php_execute_script + 804
frame #200: 0x00000001020b7aaa phpd`do_cli + 3699
frame #201: 0x00000001020b6aaa phpd`main + 1206
frame #202: 0x00007fff86d215ad libdyld.dylib`start + 1
(lldb)
Test script:
---------------
The code is huge and I could not simplify it by any means. It is performing a deep_copy of a huge
PHP array, with a lot of references.
I can provide the code in Github if needed, it is a private repo at the moment.
The recursive function calling itself is:
function
&deep_copy(&$variable,&$object_pool=[],&$zval_pool=[],$depth=0,&$id_zvals=[])
and it crashes at:
$t=&deep_copy($variable[$k],$object_pool,$zval_pool,$depth+1,$id_zvals);
$id_zvals and $variable[$k] both cause the crash. Replacing the rest of the arguments (in call) with
an empty array ($a=[]) will not prevent the crash, but replacing both $id_zvals and $variable[$k]
will.
$id_zvals has 181 members, all of which are references parts of the original $variable. Memory is
not exhausted, about 40 MB is used and the machine has 24 GB (PHP's memlimit is unlimited).
Expected result:
----------------
No crash.
Actual result:
--------------
Segfault
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72144&edit=1