Hi!
having a complete trace from an exception would be great:
function shutdown() {
$e = new Exception();
echo $e->getTraceAsString();
}
function test() {
exit;
}
register_shutdown_function('shutdown');
test();
gives:
#0 [internal function]: shutdown()
#1 {main}
Regards
Thomas
Bishop Bettini wrote on 04.08.2016 20:10:
Hi!
exit (and its doppelganger die) is a hard stop to the engine and there is
little telemetry provided about the circumstances (file, line, message, and
code). In source I control, exit is no big deal: I don't use exit! But in
library code, exit can be frustrating.register_shutdown_function + debug_backtrace doesn't help, because the
trace doesn't flow out of the shutdown function. xdebug helps to find the
exit frame, but cannot pinpoint the exact line. It seems like the engine
could help with a little extra telemetry.I'm wondering if the shutdown functions could access telemetry:
<?php
register_shutdown_function(function () {$context = shutdown_get_context();
/** array ( 'exit' => array ('file' => '/path/to/Foo.php', 'line' =>
242, 'message' => "Calling exit() because...", 'code' => 0)) */
// different SAPI may expand on this context
});require 'vendor/autoload.php';
\Vendor\Package\Class::callsExit();
?>Or, alternatively, I wonder if a method to convert an exit to an exception
would be better:<?php
echo ini_get('zend.exit_exception'); // "1"try {
require 'vendor/autoload.php';
\Vendor\Package\Class::callsExit();
} catch (\ExitException $ex) { // extends \RuntimeException
echo 'Stop that!';
}
?>(In all these examples, "callsExit" is vendor code that performs an
undesirable exit();)This latter approach feels more modern, at least from a user perspective,
but it has the side effect of making exit recoverable. IMO, that's a good
thing, because the conditions under which libraries exit may merely be
exceptional for consuming applications.However, I'm uncertain of an "exit exception" implementation. Perhaps when
INI enabled, zend_compile_exit could rewrite to emit ZEND_THROW with a
synthetic node. Or all the ZEND_EXIT could be updated to throw instead of
bailout. Don't know.TL;DR: Engine support for tracing/trapping/debugging exit helps developers
find and avoid hard exits in dependent code they don't control. Thoughts on
proceeding with an RFC?bishop