Bug #65338 [PATCH]: Enabling both php_opcache and php_wincache AVs on shutdown

From: Date: Thu, 25 Jul 2013 17:30:56 +0000
Subject: Bug #65338 [PATCH]: Enabling both php_opcache and php_wincache AVs on shutdown
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-180483@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=65338&edit=1

 ID:                 65338
 Patch added by:     ericsten@php.net
 Reported by:        ericsten@php.net
 Summary:            Enabling both php_opcache and php_wincache AVs on
                     shutdown
 Status:             Open
 Type:               Bug
 Package:            Reproducible crash
 Operating System:   Windows
 PHP Version:        5.5.1
 Block user comment: N
 Private report:     N

 New Comment:

The following patch has been added/updated:

Patch Name: zend_interned_strings_shutdown_AV
Revision:   1374773456
URL:        https://bugs.php.net/patch-display.php?bug=65338&patch=zend_interned_strings_shutdown_AV&revision=1374773456


Previous Comments:
------------------------------------------------------------------------
[2013-07-25 17:30:31] ericsten@php.net

Description:
------------
If both php_wincache.dll and php_opcache.dll are enabled, and if they are both enabled for CLI, any
script leads to an AV at process exit.

The call stack indicates that the AV is in zend_interned_strings_dtor, on the following line:

          free(CG(interned_strings_start));

This is because the value in CG(interned_strings_start) is pointing at the chunk of memory provided
by php_wincache.dll for its interned strings.  

I'm seeing in the debugger that on process startup, the modules are loaded in the order:

1.	php_wincache.dll
2.	php_opcache.dll

And on shutdown, they're terminated in exactly the same order.

This causes a problem, because both modules set the CG(interned_strings_start) based upon the value
it copied during startup.  In this case, php_opcache.dll copied the value that php_wincache.dll set
when it started up.  So, the last value put back into CG(interned_strings_start) on shutdown was
php_wincache's interned strings buffer.  

php_wincache.dll allocated the interned strings block using (zend's) pemalloc(), but the
address for CG(interned_strings_start) is an offset within the allocation, so free() thinks the heap
is corrupted.

Question: 

Why are modules terminated in the same order they were initialized?  For modules that do
'hooking' of functions or memory, it seems the "unhooking" should happen in
reverse order.

php.ini settings:

zend_extension=php_opcache.dll
extension=php_wincache.dll
[opcache]
opcache.enable=1
opcache.enable_cli=1
[wincache]
wincache.enablecli=1
wincache.ocenabled=0


Test script:
---------------
<?php
$variable = 2.0;
function testGlobal()
{
    global $variable;
    var_dump($variable);
}
testGlobal();
$variable += 1;
testGlobal();
$variable = "Changing to string.";
testGlobal();
?>

Expected result:
----------------
No AV on shutdown



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



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


Thread (17 messages)

« previous php.bugs (#180483) next »