php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #69131 Destructor does not release acquired reference, causing exception on shutdown
Submitted: 2015-02-27 00:08 UTC Modified: 2016-01-11 16:34 UTC
From: p at wspnr dot com Assigned: colder (profile)
Status: Closed Package: Weakref (PECL)
PHP Version: 5.6.6 OS: Linux
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.
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: p at wspnr dot com
New email:
PHP Version: OS:

 

 [2015-02-27 00:08 UTC] p at wspnr dot com
Description:
------------
Under certain conditions, unsetting a Weakref instance that has acquired and NOT released a strong reference will result in an exception being thrown during shutdown.

This seems to cause PHP to shut down uncleanly, and the next request (FPM SAPI) will fail with a cryptic error (e.g. re-declaration of a function that is only declared once). After a few requests, the FPM child process will terminate due to a segmentation fault.

I had to apply a patch as a stopgap on our dev server since every other request was failing. The problem seems to be within wr_weakref_ref_dtor: it sets valid to 0 but does not release the reference. During shutdown, wr_weakref_object_free_storage calls wr_weakref_ref_release which fails as valid is now 0. Adding a loop to release the reference in wr_weakref_ref_dtor fixes the problem. 

Version 0.2.5/0.2.6 of Weakref.

Additional note: the documentation for this extension does not make it clear that acquire() and release() need to be called in pairs. The code this first surfaced called acquire() multiple times, and release() only once. Perhaps this could be added to the documentation?


Test script:
---------------
$wr = [];
for($i = 0; $i < 2; $i++) {
        $c = new stdClass();
        $wr[$i] = new Weakref($c);
        $wr[$i]->acquire();
}
unset($wr[0]);


Expected result:
----------------
(no output)

Actual result:
--------------
Fatal error: Uncaught exception 'RuntimeException' with message 'Failed to correctly release the reference on free' in [no active file] on line 0

Patches

wr_weakref-fix-dtor-release (last revision 2015-02-27 00:09 UTC by p at wspnr dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-01-11 16:34 UTC] colder@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: colder
 [2016-01-11 16:34 UTC] colder@php.net
Hi,

thanks for this report; Indeed, during shutdown, objects may be dtored in "arbitrary" order, causing an acquired ref to be dtored before the wref. I've fixed the php7 port only.

It should be released shorty.
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Thu Aug 13 10:01:25 2020 UTC