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

From: Date: Fri, 11 Aug 2017 20:42:30 +0000
Subject: Bug #75056 [Com]: Unintuitive gotcha - Exception maintains handles to stack objects
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210617@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=75056&edit=1 ID: 75056 Comment by: rowan dot collins at gmail dot com Reported by: nachms+php at gmail dot com Summary: Unintuitive gotcha - Exception maintains handles to stack objects Status: Open Type: Bug Package: *General Issues PHP Version: 5.6.31 Block user comment: N Private report: N New Comment: This was actually one of the first topics I raised on the PHP Internals mailing list (which is generally a better place for open-ended discussions like this - http://php.net/mailing-lists.php). That was nearly 4 years ago, and didn't get much response; it then came up again a couple of years later, in the context of serialization errors (which are caused by the same data). See these threads in the archives: - http://marc.info/?t=138118341600002&r=1&w=2 - http://marc.info/?t=142708828500001&r=1&w=2 - http://marc.info/?t=143798102800002&r=1&w=2 The peculiar thing is that most of the information stored for the backtrace is already reduced to strings (class names and the like), but the *arguments* passed to functions in the trace are preserved as full object references. My inclination remains that removing these object references would solve both the destructor and serialization problems, and I'm going to raise it on the list again. I invite you to join the discussion there. Previous Comments: ------------------------------------------------------------------------ [2017-08-09 15:05:07] nachms+php at gmail dot com 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 this bug report at https://bugs.php.net/bug.php?id=75056&edit=1

« previous php.bugs (#210617) next »