Req #80517 [Opn->Wfx]: Retain parent method name of Closure in call stack

From: Date: Wed, 12 May 2021 09:04:24 +0000
Subject: Req #80517 [Opn->Wfx]: Retain parent method name of Closure in call stack
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-233800@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80517&edit=1

 ID:                 80517
 Updated by:         krakjoe@php.net
 Reported by:        ttijhof at wikimedia dot org
 Summary:            Retain parent method name of Closure in call stack
-Status:             Open
+Status:             Wont fix
 Type:               Feature/Change Request
 Package:            Scripting Engine problem
 Operating System:   Debian stable
 PHP Version:        Irrelevant
 Block user comment: N
 Private report:     N

 New Comment:

This is outside of the scope of normal operation for PHP, we store no information about
relationships between closures and the declaring op array, and we probably shouldn't.

One of the problems with this is avoiding collisions in naming, the internal solution used to be to
append the opcode address to the end of the closure ... but this is obviously meaningless
information that should not leak into userland, an implementation detail that today we are without,
and we wouldn't want to introduce another detail like it.

So decide for yourself how you want to name closure, below is a demonstration of how to achieve
that.

https://github.com/krakjoe/cloname

While I'm aware that there are other reports complaining about unidentifiable closures,
I'm going to close this one because you've got a pretty good answer here for your
particular use case.

If we do decide to append some information to a closures name, it is not likely to be enough for
your use case whatever.


Previous Comments:
------------------------------------------------------------------------
[2020-12-15 11:45:09] danack@php.net

imo, this would be useful for all closures, including those created through Closure::fromCallable().

------------------------------------------------------------------------
[2020-12-15 02:58:25] ttijhof at wikimedia dot org

The formatted outcome for this bug, may be of use in bug 62325 as the identifier or token for the
Reflection API.

Mentions:
- https://bugs.php.net/bug.php?id=62325
Backtrace gives no handle to anonymous functions

------------------------------------------------------------------------
[2020-12-15 02:55:51] ttijhof at wikimedia dot org

Description:
------------
When an anonymous function is encountered on the stack, it is currently not feasible (afaik) to
obtain the name of the class/method or function where the closure was declared.

My use case is a sampling profiler observing EG(current_execute_data), in which I'd like to
report something more useful and stable to the end-user than file path and line number.

This information would be useful to expose via debug_backtrace() as well, although maybe that should
could be a separate ticket.


Downstream code: https://github.com/wikimedia/php-excimer/
Downstream task: https://phabricator.wikimedia.org/T231335
Downstream use case: Flame graphs, such as https://performance.wikimedia.org/php-profiling/


Test script:
---------------
class ResourceLoader {
 public function getHashes() {
  return array_map( function ( $module ) {
    return $this->getModule( $module )->getVersionHash();
  }, $moduleNames );
 }
}




Expected result:
----------------
Able to construct a string like "Closure$ResourceLoader::getHashes".


Before Wikimedia upgraded to PHP 7.2, we used HHVM and its Xenon extension, which provided
"faux" function name for closures that were unique over a given code base and added
signifant value for developers as part of stack traces.

Example:
https://github.com/facebook/hhvm/blob/HHVM-3.23.4/hphp/tools/gdb/README.md#stacktraces
https://github.com/facebook/hhvm/blob/HHVM-3.23.4/hphp/test/slow/closure/name.php.expect

Note that a method could define multiple closures, in which we could append a number to them. HHVM
did this by appending "#2" as needed. XHProf does something similar for nested functions,
by appending "@2" to the faux function name.

Actual result:
--------------
function_name:
class_name:
filename: /tmp/foo.php
closure_line: 3

For closures, we currently format this as {closure:/tmp/foo.php(3)}

https://github.com/wikimedia/php-excimer/blob/d82eaf7b3b/excimer_log.c#L311


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=80517&edit=1


Thread (5 messages)

« previous php.bugs (#233800) next »