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 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)
   {

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

Reply via email to