Bug #17643 Updated: Zend Engine unloading extension in the wrong order
| From: | list at firehawksystems dot com | Date: | Sat, 08 Jun 2002 16:20:56 +0000 |
| Subject: | Bug #17643 Updated: Zend Engine unloading extension in the wrong order | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-9871@lists.php.net to get a copy of this message | ||
ID: 17643
Updated by: list@firehawksystems.com
Reported By: list@firehawksystems.com
Status: Open
Bug Type: Scripting Engine problem
Operating System: FreeBSD 4.3, but any Unix
PHP Version: 4.2.1
New Comment:
After talking on the php-dev list it looks like
zend_hash_graceful_reverse_destroy() would be a better fix as it
doesn't require a new function, but does the same thing.
Brian
Previous Comments:
------------------------------------------------------------------------
[2002-06-07 12:13:02] list@firehawksystems.com
I have been tracking down a core dump with my php extension when it is
unloading some of its shared libraries. I have shared extension that
is link against libexpat and will load fine if it is the only on in the
php.ini. If I then load xml.so extension (also link against libexpat)
then my extension it works fine, but if it is my extension then xml.so
it crashes while xml.so is unloading libexapt.
What I have found is the Zend Engine is unloading extension in the same
order it loaded them.
load: foo_bar.so
load: xml.so
unload: foo_bar.so
unload: xml.so
I believe this is wrong and think it should be in reverse order.
load: foo_bar.so
load: xml.so
unload: xml.so
unload: foo_bar.so
There are two ways to fix this problem. One is to push the modules to
the head of the hash, but looking at the zend_hash_add function I
decided to go with the second. Second way is to destroy them in
reverse order. I created a zend_hash_reverse_destroy and call that
instead of zend_hash_destroy. There may be a better way to do this,
but this is the quick fix for me.
I have included a patch below, should I submit a bug report as well?
Thanks,
Brian
diff -rc php-4.2.1/Zend/zend.c
*** php-4.2.1/Zend/zend.c Tue Feb 26 10:59:25 2002
--- php-4.2.1/Zend/zend.c Thu Jun 6 11:32:57 2002
***************
*** 487,493 ****
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
#endif
zend_destroy_rsrc_list_dtors();
! zend_hash_destroy(&module_registry);
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
free(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
--- 487,493 ----
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
#endif
zend_destroy_rsrc_list_dtors();
! zend_hash_reverse_destroy(&module_registry);
zend_hash_destroy(GLOBAL_FUNCTION_TABLE);
free(GLOBAL_FUNCTION_TABLE);
zend_hash_destroy(GLOBAL_CLASS_TABLE);
diff -rc php-4.2.1/Zend/zend_hash.c
*** php-4.2.1/Zend/zend_hash.c Mon Apr 22 23:53:26 2002
--- php-4.2.1/Zend/zend_hash.c Thu Jun 6 11:32:57 2002
***************
*** 550,555 ****
--- 550,579 ----
SET_INCONSISTENT(HT_DESTROYED);
}
+ ZEND_API void zend_hash_reverse_destroy(HashTable *ht)
+ {
+ Bucket *p, *q;
+
+ IS_CONSISTENT(ht);
+
+ SET_INCONSISTENT(HT_IS_DESTROYING);
+
+ p = ht->pListTail;
+ while (p != NULL) {
+ q = p;
+ p = p->pLast;
+ if (ht->pDestructor) {
+ ht->pDestructor(q->pData);
+ }
+ if (!q->pDataPtr && q->pData) {
+ pefree(q->pData, ht->persistent);
+ }
+ pefree(q, ht->persistent);
+ }
+ pefree(ht->arBuckets, ht->persistent);
+
+ SET_INCONSISTENT(HT_DESTROYED);
+ }
ZEND_API void zend_hash_clean(HashTable *ht)
{
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=17643&edit=1