php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch Patch_for_PhpCrashInFCGIModeDuringCoUnintialzie.diff for COM related Bug #32099

Patch version 2011-04-22 23:17 UTC

Return to Bug #32099 | Download this patch
Patch Revisions:

Developer: thangaraj@gmail.com

Index: php-src-5.3/sapi/cgi/cgi_main.c
===================================================================
--- php-src-5.3/sapi/cgi/cgi_main.c	(revision 310436)
+++ php-src-5.3/sapi/cgi/cgi_main.c	(working copy)
@@ -2156,7 +2156,16 @@
 			{
 				STR_FREE(SG(request_info).path_translated);
 
-				php_request_shutdown((void *) 0);
+                /* Thanga/LTAC: For Win32 non-Thread safe builds using FastCGI 
+                 * mode invoke PHP request shutdown funtion with '1' in order
+                 * to avoid CoUninit - i.e., cache already made CoInit call
+                 * for future request processing
+                 */ 
+#if defined(PHP_WIN32) && !defined(ZTS)
+				php_request_shutdown((void *) 1);
+#else
+                php_request_shutdown((void *) 0);
+#endif 
 
 				if (exit_status == 0) {
 					exit_status = EG(exit_status);
Index: php-src-5.3/main/main.c
===================================================================
--- php-src-5.3/main/main.c	(revision 310436)
+++ php-src-5.3/main/main.c	(working copy)
@@ -24,6 +24,8 @@
  */
 
 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
+/* Thanga/LTAC: For COM debugging */
+#define ZEND_COM_DEBUG
 
 #include "php.h"
 #include <stdio.h>
@@ -1388,9 +1390,25 @@
 {
 	int retval = SUCCESS;
 
-#ifdef PHP_WIN32
-	PG(com_initialized) = 0;
-#endif
+/* Thanga/LTAC: 
+ * For Win32 Thread safe builds(ZTS):  com_initialized state is thread 
+ * specific and it is ok to reset the state during every PHP request 
+ * processing startup, since during request cleanup stage we do 
+ * CoUninitialize()
+ *
+ * For Win32 non-Thread safe builds:  com_initialized state is not reset 
+ * in order to avoid possibility of CoInit() done for each request processing
+ * stage and thereby avoiding multiple CoUninit calls on the same thread, such
+ * design resolves crashes induced by PHP scripts using COM objects 
+ * intemperately. Note that MSDN recommends using CoUnint API during 
+ * application shutdown. 
+ */     
+#if defined(PHP_WIN32) && defined(ZTS)
+   PG(com_initialized) = 0;   
+#ifdef ZEND_COM_DEBUG
+   OutputDebugString("phprequest_startup()   com_initialized=0");
+#endif /*ZEND_COM_DEBUG*/
+#endif 
 
 #if PHP_SIGCHILD
 	signal(SIGCHLD, sigchld_handler);
@@ -1566,7 +1584,7 @@
 
 /* {{{ php_request_shutdown
  */
-void php_request_shutdown(void *dummy)
+void php_request_shutdown(void *operatingMode)
 {
 	zend_bool report_memleaks;
 	TSRMLS_FETCH();
@@ -1661,11 +1679,47 @@
 		zend_unset_timeout(TSRMLS_C);
 	} zend_end_try();
 
-#ifdef PHP_WIN32
-	if (PG(com_initialized)) {
-		CoUninitialize();
+/* Thanga/LTAC: 
+ * For Win32 Thread safe builds(ZTS): allow CoUninit call on each
+ * request shutdown sequence (thread processing the request)
+ *
+ */
+#if defined(PHP_WIN32) && defined(ZTS)
+
+    if (PG(com_initialized)) {
+        CoUninitialize();
 		PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+        {
+            char dbgMsg[1024];
+            sprintf(dbgMsg, "[%d:%d] php_request_Shutdown() ZTS CoUnint() "
+             "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+            OutputDebugString(dbgMsg);
+        }
+#endif /*ZEND_COM_DEBUG*/
 	}
+/* Thanga/LTAC: 
+ * For Win32 non-Thread safe builds: 
+ *
+ * FastCGI mode (operatingMode == 1): Do not uninitialize COM subsystem in order to
+ *                            avoid php crashes induced by PHP scripts using 
+ *                            COM objects intemperately.
+ *
+ * CGI mode (operatingMode != 1): COM uninitialize can be called. 
+ */
+#elif defined(PHP_WIN32) && !defined(ZTS)
+	if (PG(com_initialized) && operatingMode != 1) {        
+        CoUninitialize();
+		PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+        {
+            char dbgMsg[1024];
+            sprintf(dbgMsg, "[%d:%d] php_request_shutdown() nonTS CoUninit() "
+             "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+            OutputDebugString(dbgMsg);
+        }
+#endif /*ZEND_COM_DEBUG*/
+	}
 #endif
 }
 /* }}} */
@@ -1678,6 +1732,14 @@
 	if (!PG(com_initialized)) {
 		if (CoInitialize(NULL) == S_OK) {
 			PG(com_initialized) = 1;
+#ifdef ZEND_COM_DEBUG
+        	{
+	            char dbgMsg[1024];
+	            sprintf(dbgMsg, "[%d:%d]  CoInit() com_initialized=1", 
+	                    GetCurrentProcessId(), GetCurrentThreadId());
+	            OutputDebugString(dbgMsg);
+	        }
+#endif /*ZEND_COM_DEBUG*/
 		}
 	}
 #endif
@@ -1915,6 +1977,21 @@
 	}
 #endif
 
+/* Thanga/LTAC: 
+ * For non-Thread safe Win32 builds: Set/reset com_initilazed flag only during
+ * module/process startup phase. By this method we can call CoUninit call only
+ * during fastcgi process shutdown phase, and thereby adhere to MSDN's 
+ * recommended way of calling CoUnint during process shutdown. Note that this 
+ * approach resolves crashes induced by PHP scripts using COM objects 
+ * intemperately
+ */    
+#if defined(PHP_WIN32) && (!defined(ZTS))
+    PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+    OutputDebugString("php_module_startup()   com_initialized=0");
+#endif /*ZEND_COM_DEBUG*/
+#endif 
+
 	le_index_ptr = zend_register_list_destructors_ex(NULL, NULL, "index pointer", 0);
 
 	/* Register constants */
@@ -2178,6 +2255,26 @@
 		_set_invalid_parameter_handler(old_invalid_parameter_handler);
 	}
 #endif
+
+
+/* Thanga/LTAC: 
+ * For Win32 non-Thread safe builds: Cleanup COM subsystem only during process
+ * shutdown.
+ */     
+#if defined(PHP_WIN32) && !defined(ZTS)
+    if (PG(com_initialized)) {        
+        CoUninitialize();
+        PG(com_initialized) = 0;
+#ifdef ZEND_COM_DEBUG
+        {
+            char dbgMsg[1024];
+            sprintf(dbgMsg, "[%d:%d] php_module_shutdown() CoUninit() "
+             "com_initialized=0", GetCurrentProcessId(), GetCurrentThreadId());
+            OutputDebugString(dbgMsg);
+        }
+#endif /*ZEND_COM_DEBUG*/
+    }
+#endif
 }
 /* }}} */
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Mar 29 15:01:28 2024 UTC