[PHP-BUG] Bug #75056 [NEW]: Unintuitive gotcha - Exception maintains handles to stack objects
[email protected] ("nachms+php at gmail dot com") Wed, 9 Aug 2017 15:05:11 GMT
| Newsgroups | php.standards |
|---|---|
| Message-ID | <[email protected]> |
From: nachms+php at gmail dot com
Operating system:
PHP version: 5.6.31
Package: PHP Language Specification
Bug Type: Bug
Bug description:Unintuitive gotcha - Exception maintains handles to stack objects
Description:
------------
Consider the attached code, it outputs:
The throw did not destruct
destructing
--------------
This is somewhat surprising at first, but is due to exceptions
containing a backtrace of all function parameters keeping objects alive
somewhat unintuitively.
This really means that to have sane destruction behavior with exception
handling, one must always unset the Exception at the end of a catch.
Which is usually fine...
However, if one needs to rethrow from an exception handler, this means
objects that need to be destructed as early as possible are now
long-lived through many nested levels. There is no built-in way in PHP
to remove these handles from the exception's backtrace.
With the way PHP currently works, we've found that an exception to
handle some occasional error could in turn generate a whole chain
reaction of problems simply because objects are now living far outside
their scope, holding onto resources they ideally should not.
We're not sure of the best solution here, but it would seem that in
order to handle these kinds of cases, PHP needs to offer a way to catch
exceptions without keeping handles to stack objects. Perhaps some other
way to catch, or some way to tell Exceptions to drop object handles from
their backtrace before further handling them.
Test script:
---------------
<?php
$destructed = false;
class c
{
function __destruct()
{
global $destructed;
$destructed = true;
echo 'destructing', "\n";
}
}
function thrower($c) { throw(new Exception('oops')); }
function test()
{
$c = new c();
thrower($c);
}
try { test(); }
catch(Exception $e)
{
echo 'The throw ', ($destructed ? 'destructed' : 'did not destruct'),
"\n";
}
Expected result:
----------------
One would intuitively expect:
destructing
The throw destructed
--
Edit bug report at https://bugs.php.net/bug.php?id=75056&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=75056&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=75056&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=75056&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=75056&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=75056&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=75056&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=75056&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=75056&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=75056&r=support
Expected behavior: https://bugs.php.net/fix.php?id=75056&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=75056&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=75056&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=75056&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=75056&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=75056&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=75056&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=75056&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=75056&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=75056&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=75056&r=mysqlcfg