Edit report at https://bugs.php.net/bug.php?id=65822&edit=1

 ID:                 65822
 Comment by:         askalski at gmail dot com
 Reported by:        askalski at gmail dot com
 Summary:            crash on shutdown because of zend extension cleanup
                     order
 Status:             Open
 Type:               Bug
 Package:            Reproducible crash
 Operating System:   Linux
 PHP Version:        5.4.20
 Block user comment: N
 Private report:     N

 New Comment:

Spent some time digging into this.  It's not as simple as calling 
zend_shutdown_extensions before zend_destroy_modules; there are a few issues at 
play which complicate matters.

The two Zend Extensions I investigated (OpCache and XDebug) implement both the 
zend_extension and zend_module API.  Both of these extensions load the 
zend_module portion by calling zend_startup_module in the zend_extension 
startup function.  Also, it is possible to load modules at runtime using the 
dl() userland function.

Consequently, the shutdown order is not a simple matter of "extensions first, 
then modules".  Because startup order of extensions and modules can be 
interleaved, this precise order must be recorded during initialization.  The 
implementation might be something as simple as a stack of enumerated values: { 
MODULE, MODULE, MODULE, MODULE, EXTENSION, MODULE, EXTENSION, MODULE }


Previous Comments:
------------------------------------------------------------------------
[2013-10-02 22:09:12] askalski at gmail dot com

Description:
------------
php_module_startup() initializes modules first, extensions second.

However, zend_shutdown() destroys them in the same order (modules first, 
extensions second), rather than in stack order as one would expect.

Furthermore, it seems (based on reading the zend_startup_extensions() 
zend_shutdown_extensions() functions) that if multiple zend extensions are 
loaded, they are destroyed in the wrong order as well.

Multiple modules work fine; they are destroyed in stack order.

To reproduce the issue, load an extension and module which both override the 
same Zend structure.  For example, loading both OpCache 7.0.2 and APC 3.1.13 
will cause a segfault on shutdown because of improper cleanup order of 
orig_interned_strings_start, old_interned_strings_start, and 
compiler_globals.interned_strings_start.

I'm aware that the example sounds like a bizarre combination of modules and 
extensions here; I'm reporting the bug because it points at an issue in PHP 
itself.  The specific use case for loading both APC and OpCache is to use 
OpCache for opcodes and APC with apc.cache_by_default=0 for the 
apc_store/apc_fetch userland functions.


Test script:
---------------
zend_extension=/usr/lib64/php/modules/opcache.so
extension=apc.so

Load both OpCache and APC in mod_php in Apache "prefork" mode.  Send SIGTERM to 
one of the workers (or simply send enough requests to make Apache reap the 
worker), and watch for the Segmentation fault in Apache's error_log.


Expected result:
----------------
No crash.

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


------------------------------------------------------------------------



-- 
Edit this bug report at https://bugs.php.net/bug.php?id=65822&edit=1

Reply via email to