2022年10月7日(金) 22:32 Arnaud Le Blanc <arnaud...@gmail.com>:

> Hi internals,
>
> I would like to propose a way to detect stack overflows before they
> happen, with the goal of improving debugability.
>
> Stack overflows are caused by excessive stack usage, typically due to
> deep recursions. Recursion in PHP doesn't use recursion internally, but
> some constructs still do, and it is not always possible to avoid without
> dramatically increasing complexity or degrading performances. Some
> examples of these constructs can be found at [1][2][3].
>
> Programs that overflow the stack are terminated with a SIGSEGV, and the
> user is left with no hint as to which code is causing the issue. This
> makes debugging difficult.
>
> Xdebug makes debugging easier by throwing an exception when the function
> call nesting level exceeds a certain limit [4], which is very useful.
> However, this can be overly limiting because this does not discriminate
> between the calls that actually use the stack and those that do not.
>
> Nikita proposed an other solution a while ago [5] that limits in terms
> of VM reentrances, so that only the constructs that actually cause
> internal recursion count towards the limit. One issue is that not all VM
> frames will consume the same amount of stack, and the maximum stack size
> depends on the system, so it's hard to determine a good default value
> for the limit that is not overly limiting.
>
> I would like to propose an alternative [6] that limits in terms of stack
> size. One issue is that it increases the internals complexity a bit, but
> this would make debugging easier without limiting recursion too much
> compared to what the system would allow.
>
> Any thoughts?
>
> [1] https://bugs.php.net/bug.php?id=64196
> [2] https://bugs.php.net/bug.php?id=75509
> [3] https://github.com/php/php-src/issues/8315
> [4] https://xdebug.org/docs/develop#max_nesting_level
> [5] https://externals.io/message/108348
> [6] https://github.com/php/php-src/pull/9104
>
>
The root cause that users cannot understand what happened is this:

$ php -n -r 'set_error_handler(function ($severity,$message, $filename,
$lineno) { throw new ErrorException($message, 0, $severity, $filename,
$lineno); });  function f() { f(); } f();'

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to
allocate 262144 bytes) in Command line code on line 1

When a fatal error happens, PHP does not allow  a stack dump.  Very old PHP
allowed users to catch E_ERROR by user error handler, but it is disabled to
prevent users from shooting their own foot.
I suppose allowing users to catch "only one" fatal error would solve many
issues as  well as infinite recursion.

Regards,

--
Yasuo Ohgaki
yohg...@ohgaki.net

Reply via email to