Bug #75056 [NEW]: Unintuitive gotcha - Exception maintains handles to stack objects

From: Date: Wed, 09 Aug 2017 15:05:11 +0000
Subject: Bug #75056 [NEW]: Unintuitive gotcha - Exception maintains handles to stack objects
Groups: php.standards 
Request: Send a blank email to standards-+get-1288@lists.php.net to get a copy of this message
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

« previous php.standards (#1288) next »