Hi, On Mon, Dec 20, 2021 at 6:41 PM Derick Rethans <der...@php.net> wrote:
> Literature since at least 2006 (Sara's Extending and Embedding PHP > book), as well as numerous presentations that I have seen and given, and > including the online PHP Internals Book > ( > https://www.phpinternalsbook.com/php7/extensions_design/php_lifecycle.html), > > always expected that the MINIT (and MSHUTDOWN) functions are called once > per worker process. However, PHP-FPM does not do that. It only calls > extension's MINITs once in the main control process, but it *does* call > an MSHUTDOWN for each worker process. > In the past, this has already caused an issue where I couldn't create a > monitoring thread in MINIT, and then wait for it to end in MSHUTDOWN, as > MSHUTDOWN would wait on the same thread in each worker process, although > only one was created in MINIT. > > The way how PHP-FPM handles this breaks the generally assumed "one > MINIT, one MSHUTDOWN call" per process approach. > Yeah this is a bit unfortunate asymetry. It has got some slight advantages like in case of preloading that is done just once instead of on each child init. However there are most likely more disadvantages like the ones above and also the fact that MINIT is often run under the root so it's not ideal from the security point of view - especially when running 3rd party extensions. > In particular, in the case of Xdebug bug #2051 it creates a problem with > the following set-up: > > 1. php.ini has a `xdebug.mode=off` > 2. the pool configuration has a `php_admin_value[xdebug.mode] = debug` > directive > > So this is actually mainly about the fact that fpm_php_apply_defines runs after the MINIT. You might be able to tweak this but not sure if it completely fixes the issue as there's another to way overwrite INI that happens during the request. It is using FCGI env PHP_ADMIN_VALUE (see fastcgi_ini_parser usage) so you might need to handle this case in your code anyway. Basically you can't rely on the fact that INI stays the same so you will probably have to add some logic to your RINIT to handle this. > > My suggestion for a fix would be to emulate what Apache always did: > > One MINIT/MSHUTDOWN in the main control process (I think it needed that > to be able to implement php_admin_value and php_value), and then > additionally also in each worker process. > As I said above, it won't probably fully fix your problem but if you still want to try to tackle it and move the MINIT, the way that I would do it is to try to separate the whole sapi init logic and call it from the child init as the first thing. If you want to experiment with using php_admin_value before the module minit, then it might be worth to try put fpm_php_init_child (or just the defines) to sapi startup callback before calling php_module_startup so the main INIs are loads but it might be a bit tricky to get worker pool config - it might need some extra globals maybe for it. But not sure if that's gonna work (e.g. if the main INI files are loaded at the sapi startup stage) and what will be impact on extensions. I'd probably have to check it more and try it. Think it's also something that could happen in master branch only as it's changing some fundamental bits in FPM... Regards Jakub