Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93485 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 96902 invoked from network); 24 May 2016 15:32:27 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 May 2016 15:32:27 -0000 Authentication-Results: pb1.pair.com header.from=rasmus@mindplay.dk; sender-id=unknown Authentication-Results: pb1.pair.com smtp.mail=rasmus@mindplay.dk; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain mindplay.dk from 209.85.218.53 cause and error) X-PHP-List-Original-Sender: rasmus@mindplay.dk X-Host-Fingerprint: 209.85.218.53 mail-oi0-f53.google.com Received: from [209.85.218.53] ([209.85.218.53:36722] helo=mail-oi0-f53.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 14/32-10476-90474475 for ; Tue, 24 May 2016 11:32:26 -0400 Received: by mail-oi0-f53.google.com with SMTP id j1so32183290oih.3 for ; Tue, 24 May 2016 08:32:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mindplay-dk.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc; bh=Q+XSIKTuASUl0Kkalq1KrheaKAHMfaortbwEv0GykdY=; b=T0hnCTRQuYtqB+3CAzUdkiQPV6tn0Elrb5kfAwH8QFfFQ1tg5NWZrEZEOCWHy2TZW1 +ihvo5J4aDjktF6kQHzrIJoM0X3i9iwxnI9OUWqiLf11ezUE4O9P3h2JAQtazR+shFd7 BCx5PUNJyoXIAZhmaHh8fN4w1TVI4wOVJqURMZgw8VD1DZayV1R90WkzTds1Tpah4mUQ EfU/jkH9bmt6LwWhludUINXEGCrCY3zCtvd49tT+e1lQ6CqB+TtnYQHNhcdZ4fqlAmxI mM7twhhFiOruHf20z5iFbzYDIagtgvNS/qZ1SQSWep2NktKNoQMLurIpRrqaVsIqqEeA FOnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc; bh=Q+XSIKTuASUl0Kkalq1KrheaKAHMfaortbwEv0GykdY=; b=gFfwwMkqA6GmZqeveGyu6DpGetwrteaVwOr6Yfyfz6IkwBdNI2+XkizCj/sXDNGBsE 9e8wiShkArMrUxPkS1D6hzuStQ9g4j+woTc1rilZdxjPudSE7GDXoLqDTj9/hhgo5N70 qUDBBmV7AtGZCTY60wzNFwu3iZLCeD9YWugMAo9cZz539S6hhnRmrWSZaahVw0VJaK1B 1PYZzbVVuhGM9Sfxt6ACMxe+GyvpU85MrBNPgEYnDNT2dO+XScUMOWQXxJZQYGLc6Erk lKWgRUzSdx+cEbQ8O6gIgTfNYQrZBiOlZ9PkvL9xVWAiBcWiYYRSRfswaaNgJ+p8BFxW iAGw== X-Gm-Message-State: ALyK8tIk3aHqE53uPQb4HfBJnFMU0f4FmDSfn8Wkcs6o4u9pa4cbYhKeqbIrOZJMz0kk4goulozC0TqvIncZjw== MIME-Version: 1.0 X-Received: by 10.157.20.202 with SMTP id r10mr3088968otr.59.1464103942375; Tue, 24 May 2016 08:32:22 -0700 (PDT) Received: by 10.157.44.214 with HTTP; Tue, 24 May 2016 08:32:22 -0700 (PDT) In-Reply-To: References: <72f547d6-5fcf-3cd2-960d-cb612a429e47@php.net> Date: Tue, 24 May 2016 17:32:22 +0200 Message-ID: To: Julien Pauli Cc: Rowan Collins , PHP internals Content-Type: text/plain; charset=UTF-8 Subject: Re: [PHP-DEV] Exception::getLine() From: rasmus@mindplay.dk (Rasmus Schultz) > it would be more logical to collect the trace in the ZEND_THROW Opcode instead of in the create_handler of the Exception class I've been pondering a means of doing this with relatively few BC issues. There are four use-cases right now: 1. Direct: throw new Exception() 2. Indirect: throw $factory->createException() 3. Re-throwing: throw $exception 4. Not throwing: $exception = new Exception() The first use-case (throw new) makes up the large majority, and would be unaffected by this change. The second use-case (indirect throw, factory) and third use-case (re-throwing) are both broken as-is - in either case, it isn't reporting the correct stack-trace now. This change corrects those cases. Even if that's a minor BC break, it corrects an error. By my analysis, that leaves only the 4th case (not throwing) as a potentially serious BC break. If somebody is presently constructing an Exception just as a means of extracting a stack-trace, this would no longer work. But there is a more direct way of doing that, which is debug_backtrace(), so likely the number of cases of this in the wild are few, and easy to correct, and likely with backwards-compatibility of the corrected code in all cases. I can't think of any other case where this change affects anything, but please correct me and point out any other case you can think of? As for Exception::getTrace(), I would propose the signature be changed to Exception::getTrace($index = 0) which would be backwards compatible in API terms - the default argument of 0 for $index would return the most recent stack trace, whereas an index of 1 would return the previous stack trace, e.g. after a re-throw. Exception::getTraceAsString() could either change in the same way, or render out all collected traces (which might be a bit much) or could simply render the most recently collected trace - I'm not sure which is best or most compatible. Exception::getLine() could either return the line-number of the first or last collected stack-trace - returning the first collected line-number is more compatible, consistent with "return new" and re-throwing, but returning the last line-number might be more correct, I'm not sure. Would a change like this require an RFC (and a vote) or is it arguably a bug? (I'm guessing this change is too substantial to be considered a "bug fix"?) On Mon, May 23, 2016 at 10:12 AM, Julien Pauli wrote: > On Sat, May 21, 2016 at 8:16 PM, Rasmus Schultz wrote: >> Alright, so forget my comparison with other languages. >> >> My other points remain: >> >> Presently, "throw new" is treated as though it was one statement. >> That's not the case. We have deferred throws and factory methods for >> exceptions, and we have re-throws, so collecting the stack-trace at >> construction time doesn't work. >> >> The construction site would only be relevant if "throw new" was in >> deed a single statement. >> >> Recording the actual throw site is clearly the goal - the current >> implementation is betting on "throw" and "new" happening at the same >> site, which is merely circumstance. >> >> Ideally, an Exception should collect another stack trace for each >> successive throw, which would enable you to trace not only the >> original site, but the flow through any exception-handlers that might >> have re-thrown the same Exception. >> >> As is, there is no information collected on throw, and thereby no >> evidence or record of possible re-throws - on top of the fact that you >> may be collecting and looking at bogus stack-traces from factory >> methods or exception mappers. >> >> >> On Fri, May 20, 2016 at 11:06 AM, Rowan Collins wrote: >>> On 20/05/2016 08:22, Niklas Keller wrote: >>>> >>>> 2016-05-20 4:13 GMT+02:00 Jesse Schalken : >>>>> >>>>> The top frame is the construction (get_error) and the site of the throw >>>>> (do_throw) doesn't appear in the stack at all. >>>>> >>>> >>>> The comparison with JavaScript isn't a good one, since you can throw >>>> everything in JS. If they didn't provide the stack trace upon throw, you >>>> would not have a stack trace at all if you throw a plain string. >>>> >>> >>> >>> That explanation justifies completely the opposite behaviour to what Jesse >>> described. >>> >>> According to MDN [1] the "stack" property is completley unstandardised, and >>> some engines may indeed populate it on throw, but there's no hint on that >>> page that they'll attach it to anything not constructed as an Error. >>> >>> So it's not a great comparison for either side (note that it was originally >>> brought up by Rasmus as an example where it *does* come from the throw site) >>> because the language doesn't actually guarantee you a stack trace at all. >>> >>> [1] >>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack >>> >>> Regards, >>> -- >>> Rowan Collins >>> [IMSoP] >>> >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> > > Hi. > > I explained that in my article detailing Exceptions from internal , > http://jpauli.github.io/2015/04/09/exceptional-php.html > > I admit it would be more logical to collect the trace in the > ZEND_THROW Opcode instead of in the create_handler of the Exception > class. > > That would break backtraces, but we already broke them in PHP 7.0 > So we could think about it for a 8.0 ideally , or a 7.1 ; I'm not > sure. Anyway, that needs more debate ;-) > > > > Julien.Pauli