Hi Internals,
Below are details of a suggested patch for COM extension defect 35872 (http://bugs.php.net/bug.php?id=35872) for review/approval.
All comments welcome; good or bad.

Regards
  Andy

Andy Wharmby
IBM United Kingdom Limited
Winchester, England SO21 2JN
E-mail: [EMAIL PROTECTED]

Using supplied testcase the backtrace is as follows:

php6ts_debug.dll!zend_object_store_get_object(_zval_struct * zobject=0x009c19e8, void * * * tsrm_ls=0x009659a8) Line 263 + 0x1b C php6ts_debug.dll!zend_objects_get_address(_zval_struct * zobject=0x009c19e8, void * * * tsrm_ls=0x009659a8) Line 144 + 0xd C php6ts_debug.dll!zend_std_object_get_class(_zval_struct * object=0x009c19e8, void * * * tsrm_ls=0x009659a8) Line 1074 + 0xd C php6ts_debug.dll!zend_get_class_entry(_zval_struct * zobject=0x009c19e8, void * * * tsrm_ls=0x009659a8) Line 239 + 0x13 C php6ts_debug.dll!disp_destructor(php_dispatchex * disp=0x00194460) Line 562 + 0x10 C php6ts_debug.dll!dispatch_dtor(_zend_rsrc_list_entry * rsrc=0x009c3230, void * * * tsrm_ls=0x009659a8) Line 60 + 0x9 C php6ts_debug.dll!list_entry_destructor(void * ptr=0x009c3230) Line 184 + 0x10 C php6ts_debug.dll!zend_hash_apply_deleter(_hashtable * ht=0x00968290, bucket * p=0x009c31d8) Line 836 + 0xf C php6ts_debug.dll!zend_hash_graceful_reverse_destroy(_hashtable * ht=0x00968290) Line 871 + 0xd C php6ts_debug.dll!zend_destroy_rsrc_list(_hashtable * ht=0x00968290, void * * * tsrm_ls=0x009659a8) Line 240 + 0x9 C php6ts_debug.dll!zend_deactivate(void * * * tsrm_ls=0x009659a8) Line 1358 + 0x1e C php6ts_debug.dll!php_request_shutdown(void * dummy=0x00000000) Line 1429 + 0x9 C php.exe!main(int argc=0x00000003, char * * argv=0x009658f8) Line 1306 + 0xa C
    php.exe!mainCRTStartup()  Line 398 + 0x11    C

We fail in zend_object_store_get_object() after the objects store has been destroyed earlier in request shutdown by zend_objects_store_destroy(). Which is very similar to defect 34617 (http://bugs.php.net/bug.php?id=34617).

The reference to the object store is caused by the trace() call in disp_destructor(). This call to trace() should probably be a NOOP in a non-debug build but we still need to fix reported problem so DEBUG builds don't hit the problem. I will raise a separate defect to disable the trace calls in non-DEBUG builds.

I have resolved the problem reported under defect 35872 by defining a new boolean flag "rshutdown_started" in COMG which is set to false by COM RINIT routine and true by the COM RSHUTDOWN routine. This allows the COM code to avoid reference to the object store if invoked during request shutdown. The trace calls themselves have been modified to add the object address to allow entries referring to the same object to be correlated even if the object name is not
available.

Fixing code in disp_destructor revealed a similar issue in FETCH_DISP macro which is fixed in a same way.

The full patch; built against CVS HEAD is attached.
### Eclipse Workspace Patch 1.0
#P php6-cvs
Index: ext/com_dotnet/com_extension.c
===================================================================
RCS file: /repository/php-src/ext/com_dotnet/com_extension.c,v
retrieving revision 1.24
diff -u -r1.24 com_extension.c
--- ext/com_dotnet/com_extension.c      1 Jan 2007 09:29:21 -0000       1.24
+++ ext/com_dotnet/com_extension.c      2 Mar 2007 13:58:14 -0000
@@ -315,6 +315,7 @@
  */
 PHP_RINIT_FUNCTION(com_dotnet)
 {
+       COMG(rshutdown_started) = 0;
        return SUCCESS;
 }
 /* }}} */
@@ -328,6 +329,7 @@
                php_com_dotnet_rshutdown(TSRMLS_C);
        }
 #endif
+       COMG(rshutdown_started) = 1;
        return SUCCESS;
 }
 /* }}} */
Index: ext/com_dotnet/com_wrapper.c
===================================================================
RCS file: /repository/php-src/ext/com_dotnet/com_wrapper.c,v
retrieving revision 1.14
diff -u -r1.14 com_wrapper.c
--- ext/com_dotnet/com_wrapper.c        24 Feb 2007 16:25:53 -0000      1.14
+++ ext/com_dotnet/com_wrapper.c        2 Mar 2007 13:58:14 -0000
@@ -92,12 +92,17 @@
 # define TSRMLS_FIXED()
 #endif
 
-#define FETCH_DISP(methname)   \
-       TSRMLS_FIXED() \
-       php_dispatchex *disp = (php_dispatchex*)This; \
-       trace(" PHP:%s %s\n", Z_OBJCE_P(disp->object)->name, methname); \
-       if (GetCurrentThreadId() != disp->engine_thread) \
-               return RPC_E_WRONG_THREAD;
+#define FETCH_DISP(methname)                                                   
                                                                                
                \
+       TSRMLS_FIXED()                                                          
                                                                                
                                \
+       php_dispatchex *disp = (php_dispatchex*)This;                           
                                                                                
\
+       if (COMG(rshutdown_started)) {                                          
                                                                                
        \
+               trace(" PHP Object:%p (name:unknown) %s\n", disp->object,  
methname);                                                   \
+       } else {                                                                
                                                                                
                        \
+               trace(" PHP Object:%p (name:%s) %s\n", disp->object, 
Z_OBJCE_P(disp->object)->name, methname);  \
+       }                                                                       
                                                                                
                                                \
+       if (GetCurrentThreadId() != disp->engine_thread) {                      
                                                                                
\
+               return RPC_E_WRONG_THREAD;                                      
                                                                                
                        \
+       }       
 
 
 static HRESULT STDMETHODCALLTYPE disp_queryinterface( 
@@ -534,7 +539,7 @@
 {
        php_dispatchex *disp = 
(php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex));
 
-       trace("constructing a COM proxy\n");
+       trace("constructing a COM wrapper for PHP object %p (%s)\n", object, 
Z_OBJCE_P(object)->name);
        
        if (disp == NULL)
                return NULL;
@@ -559,8 +564,13 @@
 {
        TSRMLS_FETCH();
        
-       trace("destroying COM wrapper for PHP object %s\n", 
Z_OBJCE_P(disp->object)->name);
-
+       /* Object store not available during request shutdown */
+       if (COMG(rshutdown_started)) {
+               trace("destroying COM wrapper for PHP object %p 
(name:unknown)\n", disp->object);
+       } else {
+               trace("destroying COM wrapper for PHP object %p (name:%s)\n", 
disp->object, Z_OBJCE_P(disp->object)->name);
+       } 
+               
        disp->id = 0;
        
        if (disp->refcount > 0)
Index: ext/com_dotnet/php_com_dotnet.h
===================================================================
RCS file: /repository/php-src/ext/com_dotnet/php_com_dotnet.h,v
retrieving revision 1.7
diff -u -r1.7 php_com_dotnet.h
--- ext/com_dotnet/php_com_dotnet.h     1 Jan 2007 09:29:22 -0000       1.7
+++ ext/com_dotnet/php_com_dotnet.h     2 Mar 2007 13:58:14 -0000
@@ -47,6 +47,7 @@
        zend_bool autoreg_case_sensitive;
        void *dotnet_runtime_stuff; /* opaque to avoid cluttering up other 
modules */
        int code_page; /* default code_page if left unspecified */
+       zend_bool rshutdown_started;
 ZEND_END_MODULE_GLOBALS(com_dotnet)
 
 #ifdef ZTS

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

Reply via email to