[PHP-BUG] Bug #77091 [NEW]: Using debug_backtrace() to distinguish continuations called on the same line

[email protected] ("asmqb7 at gmail dot com") Wed, 31 Oct 2018 22:30:07 +0000
Newsgroups php.standards
Message-ID <[email protected]>
From:             asmqb7 at gmail dot com
Operating system: All
PHP version:      7.2.11
Package:          PHP Language Specification
Bug Type:         Bug
Bug description:Using debug_backtrace() to distinguish continuations called on the same line

Description:
------------
Hi,

While working to add some robustness to a debug helper library I
stumbled on a "fun" little edge-case scenario that may arise due to the
increasing popularity of continuation-passing style programming.

I unfortunately suspect it will be a bit tricky to fix in the shorter
term, so I'm adding this bug to document the existence of the following
in the hope that it can be factored into future design decisions.

--

Consider a scenario where the same continuation function is called
multiple times. For example, a setter function:

$blah->setValue()->setValue()->setValue();

I agree that patterns using the same function name can be a tad awkward,
but entirely plausible to find being used in real-world scenarios (I
unfortunately have no citable examples I can list).

Now, in theory, each of those setValue() calls might be doing something
appropriately contained to the scope of $blah, but nonetheless
sufficiently nontrivial that I might want to inspect the state of $blah
at each setValue() call site.

Here's the problem: it's not possible for me to determine which
setValue() call I'm in. I have to rely on examination of function
arguments or other context in order to figure things out.

--

The included test script demonstrates this.

- It generates a backtrace, stores it, and if it's the same as the last
backtrace, it prints "same".

- The script prints one backtrace then prints "same" twice because the
other two collected backtraces are completely identical.

I strongly argue that some mechanism other than line numbers is needed
to identify which function is being executed. (Particularly considering
that the line numbers PHP reports are inaccurate.)

It may sound like overkill, but something similar to token_get_all()
that folds currently-executing-function annotation metadata into the
returned token stream would be pretty awesome and would completely solve
this and probably many other issues.

Test script:
---------------
<?php

class x {
   function z() {
      $bt = debug_backtrace();
      global $oldbt;
      if ($bt == $oldbt) {
         print "same\n";
      } else {
         print_r($bt);
      }
      $oldbt = $bt;
      return $this;
   }
}

$z = new x();

$z->z()->z()->z();


Expected result:
----------------
I'm not going to impose any specific interpretation; any solution that
allows me to determine exactly which function I'm in regardless of line
number will be highly appreciated.

Actual result:
--------------
Array
(
    [0] => Array
        (
            [file] => test.php
            [line] => 19
            [function] => z
            [class] => x
            [object] => x Object
                (
                )

            [type] => ->
            [args] => Array
                (
                )

        )

)
same
same


-- 
Edit bug report at https://bugs.php.net/bug.php?id=77091&edit=1
-- 
Try a snapshot (PHP 5.4):   https://bugs.php.net/fix.php?id=77091&r=trysnapshot54
Try a snapshot (PHP 5.5):   https://bugs.php.net/fix.php?id=77091&r=trysnapshot55
Try a snapshot (trunk):     https://bugs.php.net/fix.php?id=77091&r=trysnapshottrunk
Fixed in SVN:               https://bugs.php.net/fix.php?id=77091&r=fixed
Fixed in release:           https://bugs.php.net/fix.php?id=77091&r=alreadyfixed
Need backtrace:             https://bugs.php.net/fix.php?id=77091&r=needtrace
Need Reproduce Script:      https://bugs.php.net/fix.php?id=77091&r=needscript
Try newer version:          https://bugs.php.net/fix.php?id=77091&r=oldversion
Not developer issue:        https://bugs.php.net/fix.php?id=77091&r=support
Expected behavior:          https://bugs.php.net/fix.php?id=77091&r=notwrong
Not enough info:            https://bugs.php.net/fix.php?id=77091&r=notenoughinfo
Submitted twice:            https://bugs.php.net/fix.php?id=77091&r=submittedtwice
register_globals:           https://bugs.php.net/fix.php?id=77091&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=77091&r=php4
Daylight Savings:           https://bugs.php.net/fix.php?id=77091&r=dst
IIS Stability:              https://bugs.php.net/fix.php?id=77091&r=isapi
Install GNU Sed:            https://bugs.php.net/fix.php?id=77091&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=77091&r=float
No Zend Extensions:         https://bugs.php.net/fix.php?id=77091&r=nozend
MySQL Configuration Error:  https://bugs.php.net/fix.php?id=77091&r=mysqlcfg