tsrm_shutdown() and the CLI SAPI

php.internals

Steph

20 years ago
Under CLI ZTS build, when loading a PHP-GTK 2 .dll built against anything this side of PHP 5.1.2 release, I'm seeing an 'access violation' crash on reaching: if (resource_types_table && !resource_types_table[j].done && resource_types_table[j].dtor) { resource_types_table[j].dtor(p->storage[j], &p->storage); } Similar code is also used in: tsrm_free_interpreter_context() ts_free_thread() ts_free_worker_threads() ts_free_id() I thought ts_free_thread() was crashing at that line too at first, but that turned out to be because there's no 'done' check there, i.e. double dtors are possible via some functions. It's still vaguely possible there's a double flypast causing the crash I'm seeing, but I have everything I know about protected now. (On my laptop that is.) Eventually I found the resource id for PHP-GTK - the only extension I'm loading during runtime, via php.ini - is 32nd out of a possible 32. "Eventually", because that means I can't use ts_free_id() to avoid the crash as advised by Frank (and Tony, and Dmitry, and anyone else who ever used that MSHUTDOWN workaround for CLI). Interesting too, because the resource that causes the crash appears to be something completely other. Tracking down resource id #5 - and that's all I know about it apart from it crashes - is a barrel of laughs, I'll let y'all know if I ever find out which of the many possible extensions/files in ext/standard or core it is. Short version: One line is problematic, and only in one function, and presumably only under CLI SAPI. (CGI already doesn't call tsrm_shutdown(), thanks to similar issues some 3 years ago). The question is whether to take 'the Zeev approach' and simply comment out the tsrm_shutdown() call at the end of sapi/cli/php_cli.c, or whether to spend time knitting up a fine-grained approach to prevent the one bad line in the function from being called in single-threaded environments? I think I've given up on the idea of actually resolving the bug now... Thoughts? - oh, and don't make one of them 'chicken-and-egg' - this is definitively NOT related to the shutdown order in main.c!!!!! - Steph

Xuefer Tinys

20 years ago
i can confirm this on other extension. something like this grep free_id */*.c -B1 -A3 mbstring/mbstring.c-#ifdef ZTS mbstring/mbstring.c: ts_free_id(mbstring_globals_id); mbstring/mbstring.c-#else mbstring/mbstring.c- _php_mb_globals_dtor(&mbstring_globals TSRMLS_CC); mbstring/mbstring.c-#endif have no problem with it while some modules like $ grep 'ndef ZTS' */*.c -A2 apc/php_apc.c:#ifndef ZTS apc/php_apc.c- php_apc_shutdown_globals(&apc_globals); apc/php_apc.c-#endif - eaccelerator/eaccelerator.c:#ifndef ZTS eaccelerator/eaccelerator.c- eaccelerator_globals_dtor(&eaccelerator_globals TSRMLS_CC); eaccelerator/eaccelerator.c-#endif when compiled as shared module, will crash eaccelerator(mmcache) workaround it by disabling the dtor. /*??? FIXME ZEND_INIT_MODULE_GLOBALS(eaccelerator, eaccelerator_init_globals, eaccelerator_globals_dtor); */ ZEND_INIT_MODULE_GLOBALS(eaccelerator, eaccelerator_init_globals, NULL);

Steph

20 years ago
Thanks Xuefer... This bug's been extant for a long time, and I only found out why when I spent two days/nights trying to track down its history and mechanics. It's a pig. - Steph ----- Original Message ----- From: "Xuefer" <xuefer@gmail.com> To: "Steph Fox" <steph@zend.com> Cc: "internals" <internals@lists.php.net> Sent: Sunday, May 28, 2006 4:58 AM Subject: Re: [PHP-DEV] tsrm_shutdown() and the CLI SAPI

Andi Gutmans

20 years ago
Without looking to deeply into this reincarnation my guess would be that for CLI, Zeev's approach makes good sense. Andi At 08:04 PM 5/27/2006, Steph Fox wrote:

Steph

20 years ago
Fixing the config so that ZE doesn't think it's PHP might actually make Zend more stable too... I think I _know_ why other extension people are seeing a crash on ts_free_id(), but my biggest priority at present is getting the PHP-GTK crash out of the way. - Steph

Steph

20 years ago
C:\sandbox\php5\Zend>grep -l -drecurse "HAVE_LIBDL" *.* ChangeLog zend.h Zend.m4 zend_API.c zend_config.nw.h zend_config.w32.h Zend assumes Windows builds don't have HAVE_LIBDL defined. PHP - which only uses it in dl.c - assumes they do, and sets it during win32 config. ZEND_MODULE_DTOR - used in the module_registry hash - is defined as module_destructor(), which lives in zend_API.c and contains the following block. #if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H) #if !(defined(NETWARE) && defined(APACHE_1_BUILD)) if (module->handle) { DL_UNLOAD(module->handle); } #endif #endif So PHP-GTK's 'crime' is that it includes zend_API.h. Nice, eh? A better fix for Dmitry's initial win32 memory-setting issue would be to kill the HAVE_LIBDL line in config.w32.h.in (or replace it with #undef) and alter dl.c to deal with PHP_WIN32 directly. Dmitry, if you want to go through Zend's codebase and check the side-effects of every single setting in config.w32.h.in that wasn't in zend_config.w32.h before March 14th, that's groovy. But be warned, it takes a long time to test them...! - Steph ----- Original Message ----- From: "Steph Fox" <steph@zend.com> To: "Xuefer" <xuefer@gmail.com>; "Andi Gutmans" <andi@zend.com> Cc: "internals" <internals@lists.php.net> Sent: Wednesday, May 31, 2006 9:28 AM Subject: Re: [PHP-DEV] tsrm_shutdown() and the CLI SAPI

Dmitry Stogov

20 years ago
Oh well, now I see the difference. With my patch PHP starts call FreeLibrary() for dll extension. I am wonder why it wasn't called before. :) Probably some other bug that is the reason of the crash was masked by omitting FreeLibrary(). I know Tony fixed some kind of such bugs in ext/tidy and ext/sybase. Probably php-gtk needs similar fix. All other systems except win32 already used common config file, and I don't see any reason for this exceptions. Especially because it was the reason of bug, and masked other bugs that may be reproduced on linux with ZTS. Thanks. Dmitry.

Antony Dovgal

20 years ago
On 31.05.2006 15:19, Dmitry Stogov wrote:
> Oh well, now I see the difference. > With my patch PHP starts call FreeLibrary() for dll extension. > I am wonder why it wasn't called before. :) > > Probably some other bug that is the reason of the crash was masked by > omitting FreeLibrary(). > I know Tony fixed some kind of such bugs in ext/tidy and ext/sybase.
See http://cvs.php.net/viewcvs.cgi/php-src/ext/sybase_ct/php_sybase_ct.c?r1=1.110&r2=1.111 and http://cvs.php.net/viewcvs.cgi/php-src/ext/tidy/tidy.c?r1=1.85&r2=1.86
> Probably php-gtk needs similar fix. > > All other systems except win32 already used common config file, and I don't > see any reason for this exceptions. > Especially because it was the reason of bug, and masked other bugs that may > be reproduced on linux with ZTS.
-- Wbr, Antony Dovgal

Steph

20 years ago
> Oh well, now I see the difference. > With my patch PHP starts call FreeLibrary() for dll extension. > I am wonder why it wasn't called before. :)
Pure luck, by the look of it :)
> Probably some other bug that is the reason of the crash was masked by > omitting FreeLibrary(). > I know Tony fixed some kind of such bugs in ext/tidy and ext/sybase.
Yes, he gave those extensions the ts_free_id() workaround I mentioned a looooooooooong time ago when I first started looking into this.
> Probably php-gtk needs similar fix.
That workaround didn't work for PHP-GTK. I tried that first. That's why I need you to fix this bug rather than me just cover it up. The only thing that works for PHP-GTK is to either avoid tsrm_shutdown() completely (via Zeev's suggestion of commenting out the call in php_cli.c), or to fix the bug that makes reaching it a problem.
> All other systems except win32 already used common config file, and I > don't > see any reason for this exceptions.
I don't know or care what other systems do... how's that even relevant?
> Especially because it was the reason of bug, and masked other bugs that > may > be reproduced on linux with ZTS.
Sorry, I didn't parse that... can you rephrase?
> > Thanks. Dmitry.
Cheers, - Steph

Dmitry Stogov

20 years ago
Steph, Commenting tsrm_shutdown() or FreeLibrary() is just hidding real bugs. Of course this is a solution, but not excellent. Right now I haven't enough time even for ZE and PHP themself, so I don't like spent it looking into php-gtk on windows. (I don't know GTK at all). Do you know any other extension from PHP distribution that cause the same crash? Could you provide instruction how to reproduce it? Thanks. Dmitry.

Steph

20 years ago
At the moment I'm seeing it with Tidy under 5_2. Just about to get Tony to check. ----- Original Message ----- From: "Dmitry Stogov" <dmitry@zend.com> To: "'Steph Fox'" <steph@zend.com>; "'Xuefer'" <xuefer@gmail.com>; "'Andi Gutmans'" <andi@zend.com> Cc: "'internals'" <internals@lists.php.net>; "'Antony Dovgal'" <antony@zend.com> Sent: Wednesday, May 31, 2006 2:55 PM Subject: RE: [PHP-DEV] tsrm_shutdown() and the CLI SAPI

Andi Gutmans

20 years ago
At 04:28 AM 5/31/2006, Steph Fox wrote:
>>Probably some other bug that is the reason of the crash was masked by >>omitting FreeLibrary(). >>I know Tony fixed some kind of such bugs in ext/tidy and ext/sybase. > >Yes, he gave those extensions the ts_free_id() workaround I >mentioned a looooooooooong time ago when I first started looking into this.
I'm a bit behind so sorry if this has been answered already. I don't think ts_free_id() is a workaround but it's actually correct. We should free the resources of the extension during MSHUTDOWN and that's the way to do it in ZTS. Good chance that the crash is actually a bug which needs fixing although there could also be a bug lurking. Andi

Steph

20 years ago
> I'm a bit behind so sorry if this has been answered already. I don't think > ts_free_id() is a workaround but it's actually correct.
ts_free_id() would be a correct workaround if it came from zend_shutdown(). How's it right to suddenly force EVERY extension author to add it to their code individually? We

Steph

20 years ago
Hi all, I've spent a fun weekend debugging TSRM and bits of ZE2, having finally figured that the zend_compiler_globals dtor was the point of failure here. TSRM needs to mark resources as 'done' following a free and doesn't in most cases, but that's actually not the main problem we have in PHP-GTK (although fixing it may well solve everybody else's, I'll check that on my travels). Dmitry's "Optimized cleanup loops on request shutdown" commit(s) spanning the 13th and 14th March broke Andrei's 'EG(full_tables_cleanup) = 1' ruse (we needed user classes to be cleaned and internal classes to stay), but it also broke TSRM shutdown completely for us. PHP-GTK classes are recognized as being internal, but only the first one ever reaches the dtor - even when there are no user-defined classes. zend_hash_reverse_apply() is called at that point, so I'm guessing there's a reentrancy issue behind my access violation crash. I'll get back to this when I get some time, in the meantime if anyone (Dmitry?) wants to play with this you need to know that I can't put the 5_2 compat stuff into CVS until Andrei OKs it, so PHP-GTK HEAD has to be built against PHP_5_1 branch at present (anything after March 14th will do). - Steph

Edin Kadribasic

20 years ago
Hi, Yes, something broke while we were at 5.1.3-dev. It would be really nice if Dmitry could have a look at this. We have many reports that things have gotten much more ustable on Windows since 5.1.2. Edin Steph Fox wrote:

Dmitry Stogov

20 years ago
Hi Steph, I have no idea what is wrong with optimized class/functions tables cleanup. In case if EG(full_tables_cleanup) is set, the behavior should be exactly the same as before patch. PHP uses EG(full_table_cleanup) only for dl(), but I do't know how php-gtk uses it. Thanks. Dmitry.

Steph

20 years ago
Hi Dmitry, Finally cracked it, and you're right it had nothing to do with the suspected optimizations. There was a win32 memory fix where you included the PHP win32 config file in the Zend one, confusing heck out of TSRM's totally independent (until it meets Zend) alloca definition, which is some way before Zend meets PHP's. They all need to match. Can you find some other way to fix #36568 pliz? I'll take another look at those flags in TSRM itself for the work-aroundable shutdown issues when I've caught up with the weeklies... - Steph ps I knew it had to be you - nobody else did anything major in core that week ;)

Dmitry Stogov

20 years ago
Hi Steph, As I remember this patch modified "zend_config.w32.h". It made inclusion of "main/config.w32.h" in the same way as on all other systems. How it affects TSRM? May be I forgot something. Thanks. Dmitry.

Steph

20 years ago
Short version: zend_config.w32.h #define USE_ZEND_ALLOC 1 -#define HAVE_ALLOCA 1 -#define HAVE_LIMITS_H 1 + +#include <../main/config.w32.h> In theory that's OK because main/config.w32.h has '#define HAVE_ALLOCA 1' halfway down it. In practice, the order actually matters. - Steph ----- Original Message ----- From: "Dmitry Stogov" <dmitry@zend.com> To: "'Steph Fox'" <steph@zend.com> Cc: "'PHP-GTK dev'" <php-gtk-dev@lists.php.net>; "'internals'" <internals@lists.php.net> Sent: Tuesday, May 30, 2006 5:36 AM Subject: RE: [PHP-DEV] Ides of March [WAS: tsrm_shutdown() and the CLI SAPI]

Marcus Börger

20 years ago
Hello Steph, can it be that the return value of the dtor functions are wrong? They have always been wrong and during last months we tried to sort things out. Actually i was planning to have HEAD and 5.2 both respect the APPLY values correct. Should i wait with those changes now until someone figures out this dtor issue or go ahead and we look then? best regards marcus Monday, May 29, 2006, 11:40:15 AM, you wrote:
> Hi all,
> I've spent a fun weekend debugging TSRM and bits of ZE2, having finally > figured that the zend_compiler_globals dtor was the point of failure here.
> TSRM needs to mark resources as 'done' following a free and doesn't in most > cases, but that's actually not the main problem we have in PHP-GTK (although > fixing it may well solve everybody else's, I'll check that on my travels).
> Dmitry's "Optimized cleanup loops on request shutdown" commit(s) spanning > the 13th and 14th March broke Andrei's 'EG(full_tables_cleanup) = 1' ruse > (we needed user classes to be cleaned and internal classes to stay), but it > also broke TSRM shutdown completely for us. PHP-GTK classes are recognized > as being internal, but only the first one ever reaches the dtor - even when > there are no user-defined classes.
> zend_hash_reverse_apply() is called at that point, so I'm guessing there's a > reentrancy issue behind my access violation crash.
> I'll get back to this when I get some time, in the meantime if anyone > (Dmitry?) wants to play with this you need to know that I can't put the 5_2 > compat stuff into CVS until Andrei OKs it, so PHP-GTK HEAD has to be built > against PHP_5_1 branch at present (anything after March 14th will do).
> - Steph
>> Under CLI ZTS build, when loading a PHP-GTK 2 .dll built against anything >> this side of PHP 5.1.2 release, I'm seeing an 'access violation' crash on >> reaching: >> >> if (resource_types_table && !resource_types_table[j].done && >> resource_types_table[j].dtor) { >> resource_types_table[j].dtor(p->storage[j], &p->storage); >> } >> >> Similar code is also used in: >> >> tsrm_free_interpreter_context() >> ts_free_thread() >> ts_free_worker_threads() >> ts_free_id() >> >> I thought ts_free_thread() was crashing at that line too at first, but >> that turned out to be because there's no 'done' check there, i.e. double >> dtors are possible via some functions. It's still vaguely possible there's >> a double flypast causing the crash I'm seeing, but I have everything I >> know about protected now. (On my laptop that is.) >> >> Eventually I found the resource id for PHP-GTK - the only extension I'm >> loading during runtime, via php.ini - is 32nd out of a possible 32. >> "Eventually", because that means I can't use ts_free_id() to avoid the >> crash as advised by Frank (and Tony, and Dmitry, and anyone else who ever >> used that MSHUTDOWN workaround for CLI). Interesting too, because the >> resource that causes the crash appears to be something completely other. >> Tracking down resource id #5 - and that's all I know about it apart from >> it crashes - is a barrel of laughs, I'll let y'all know if I ever find out >> which of the many possible extensions/files in ext/standard or core it is. >> >> Short version: One line is problematic, and only in one function, and >> presumably only under CLI SAPI. (CGI already doesn't call tsrm_shutdown(), >> thanks to similar issues some 3 years ago). >> >> The question is whether to take 'the Zeev approach' and simply comment out >> the tsrm_shutdown() call at the end of sapi/cli/php_cli.c, or whether to >> spend time knitting up a fine-grained approach to prevent the one bad line >> in the function from being called in single-threaded environments? I think >> I've given up on the idea of actually resolving the bug now... >> >> Thoughts? >> >> - oh, and don't make one of them 'chicken-and-egg' - this is definitively >> NOT related to the shutdown order in main.c!!!!! >> >> - Steph >> >> -- >> PHP Internals - PHP Runtime Development Mailing List >> To unsubscribe, visit: http://www.php.net/unsub.php >> >> >> __________ NOD32 1.1380 (20060125) Information __________ >> >> This message was checked by NOD32 antivirus system. >> http://www.eset.com >> >>
Best regards, Marcus

Steph

20 years ago
I'm down to four possible changes - I'm just going back through them with a full build, one by one. (Takes ages here.) It could be anything at present... Dmitry, you're definitely off the hook over those optimizations though, promising though they seemed. /me was hoping for something relatively obvious