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