Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:87524 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 92360 invoked from network); 2 Aug 2015 17:50:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 2 Aug 2015 17:50:57 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.175 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.212.175 mail-wi0-f175.google.com Received: from [209.85.212.175] ([209.85.212.175:32966] helo=mail-wi0-f175.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 36/E4-55344-F785EB55 for ; Sun, 02 Aug 2015 13:50:56 -0400 Received: by wicmv11 with SMTP id mv11so110067159wic.0 for ; Sun, 02 Aug 2015 10:50:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=FqXfXC14NA/ruPUhnxxluDkRZb07zIKLUzCOjElgwnA=; b=hHjXF2xBv59Vj1Iuw6KFH+5W3sy+9ff8+ZR5aVxcYPq7cMunACt76W4xUiaQjVwdWi HzqjWirWkeNY5CBmvVtFs90qB8jLqlD9Ao/tAY9zde+zw5BVQbC9NJSUsgPHRrV167vZ l6GD0qmLAZ8Id8HhBVPmnBUyLDu9MzrDTjTwDbdn61H0wdUjCwnBX+ydF6nJfJ/r/CCk /v7+u3SvIc6cwVE/5P8vzgzSQ37DJtWc3Kke5uaBC+JA4U3at5bkQBEpU7fCevqSWlTP NVglLnAlRXVJxAAPWgMDxG9dNtOOOJLFHtW+gjGPoH74Jdubd4qBalQNgrNAUHjrHp8g JPoQ== X-Received: by 10.181.12.20 with SMTP id em20mr27383425wid.28.1438537852498; Sun, 02 Aug 2015 10:50:52 -0700 (PDT) Received: from [192.168.0.5] (cpc68956-brig15-2-0-cust215.3-3.cable.virginm.net. [82.6.24.216]) by smtp.googlemail.com with ESMTPSA id lj2sm9282489wic.1.2015.08.02.10.50.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 02 Aug 2015 10:50:51 -0700 (PDT) To: PHP Internals References: <550FA2ED.6080000@gmail.com> <55B7B08E.7070700@gmail.com> <55BBD2EE.2070008@gmail.com> <55BC069A.6000402@gmail.com> Cc: Stanislav Malyshev Message-ID: <55BE587A.5050901@gmail.com> Date: Sun, 2 Aug 2015 18:50:50 +0100 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.1.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Re: Serializing exceptions From: rowan.collins@gmail.com (Rowan Collins) On 01/08/2015 01:06, Rowan Collins wrote: > On 1 August 2015 00:36:58 BST, Stanislav Malyshev wrote: > >>> DEBUG_BACKTRACE_IGNORE_ARGS in a debug_backtrace() call. IIRC the >>> object of called methods is already excluded (equivalent to masking >>> out DEBUG_PROVIDE_OBJECT) so what's left is all strings. >> I'm not sure how you arrived at the conclusion that all arguments in >> backtrace are strings. Arguments can be of any type. When printed, they >> are converted to strings, but they are not strings when stored. > I'll have to recheck when I have more time, and something better than a phone to type on, but from memory, the backtrace which can be retrieved from an exception includes the same information as debug_backtrace(false), that is: > - function: string > - line: integer > - file: string > - class: string > - type: string > - args: array > > Of these 6 items, it is only 'args' that can contain an object of any kind, so without this item, the data would be serializable. This would be equivalent to debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS). > > If any of these items (other than args) are stored in memory in a different form (which doesn't seem likely to me), that form is completely inaccessible to the user, so converting to string during serialization would effectively be lossless. (Or, pre-converting would have zero BC break.) Similarly, if additional details are stored, those details are inaccessible, so removing them has no impact on any existing (userland) code. I just double-checked this. You can see that there is not even an internal reference to objects which were $this in the stack trace, because the object can be garbage collected separately from the exception. http://3v4l.org/hOYb9 So, as I said, no object will be implicitly attached to the exception anywhere other than the 'args' key of the backtrace. Obviously, people can attach object references wherever they like, but without this implicit gathering of objects from the entire environment, "serialize(new Exception)" would be a safe operation. Slightly abbreviated version: class Example { private $label; public function __construct($label) { $this->label = $label; } public function __sleep() { echo "Attempt to serialize object with label $this->label\n"; return array('label'); } public function __destruct() { echo "Refcount reached zero for object with label $this->label\n"; } public function throwSomething($unused_parameter) { throw new Exception; } } $target = new Example('Target of method call'); $parameter = new Example('Parameter passed but never actually used'); try { $target->throwSomething($parameter); } catch ( Exception $e ) { // Serialize exception, will attempt to serialize $parameter but not $target var_dump(serialize($e)); // Destroy $target, as there are no other references to it unset($target); // Attempt to do the same for $parameter, but Exception holds a reference unset($parameter); } echo "-- PHP process cleanup begins here --\n"; // $parameter will have its destructor fired once $e goes out of scope and relinquishes its reference Regards, -- Rowan Collins [IMSoP]