Em sex, 11 de out de 2019 às 08:05, Nikita Popov
<nikita....@gmail.com> escreveu:
>
> Hi,
>

Hello :)

> Currently exit() is implemented using bailout and unclean shutdown, which
> means that we're going to perform a longjmp back to the top-level scope and
> let the memory manager clean up all the memory it knows about. Anything not
> allocated using ZMM is going to leak persistently.
>
> For me, one of the most annoying things about this is that we can't perform
> proper leak checks on code using PhpUnit, because it will always exit() at
> the end, which will result in "expected" memory leaks.
>
> I think it would be good to switch exit() to work by throwing a magic
> exception, similar to what Python does. This would allow us to properly
> unwind the stack, executing finally blocks (which are currently skipped)
> and perform a clean engine shutdown.
>
> Depending on the implementation, we could also allow code to actually catch
> this exception, which may be useful for testing scenarios, as well as
> long-running daemons.
>
> I'm mainly wondering how exactly we'd go about integrating this in the
> existing exception hierarchy.

> Assuming that it is desirable to allow people
> to actually catch this exception
> my first thought would be along these
> lines:
>
> Throwable (convert to abstract class)
> \-> Exception
> \-> Error
> \-> ExitThrowable
>
> This does mean though that existing code using catch(Throwable) is going to
> catch exit()s as well. This can be avoided by introducing *yet another*
> super-class/interface above Throwable, which is something I'd rather avoid.
>

Since you brought python as inspiration, I believe the hierarchy goes
like this on their land:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
     +-- [kitchen sink]

Being `BaseException` the base class for all built-in exceptions. It
is not meant to be directly
inherited by user-defined classes. It 's the equivalent to our
`Throwable` situation. In this context
`ExitThrowable -> Throwable ` appears legit.

>
> Anyone have thoughts on this matter?
>

Yes. There is an obvious can of worms if I've got this right: `exit()`
and `die()` would no longer guarantee a
program to actually terminate in case catching `ExitThrowable` is
allowed. Python solves this by actually
having two patterns:

1. `quit()`, `exit()`, `sys.exit()` are the equivalent to `raise
SystemExit`, can be caught / interrupted
2. `os._exit()`, can't be caught but has a callback mechanism like our
`register_shutdown_function`,
see https://docs.python.org/3/library/atexit.html

If we bind `exit()` and `die()` to a catchable exception how would we
still have the scenario 2 available
on PHP land without a BCB? :)

I have one simple suggestion: Introduce `EngineShutdown -> Throwable`,
bind `exit|die` to it but disallow
`catch(\EngineShutdown $e)` at compile time. This would allow keeping
backwards compatibility to
scenario 2 without messing with our current exception hierarchy.

> Nikita

Thanks,
Márcio

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to