#35205 [Com]: oci_connect is not closing opened connections after script execution

From: Date: Fri, 25 Nov 2005 06:50:14 +0000
Subject: #35205 [Com]: oci_connect is not closing opened connections after script execution
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-88902@lists.php.net to get a copy of this message
ID: 35205 Comment by: cjbj at hotmail dot com Reported By: robertg2 at hope dot ac dot uk Status: Feedback Bug Type: OCI8 related Operating System: Solaris 8 PHP Version: 5.0.5 Assigned To: tony2001 New Comment: Antony, I've looked at session cleanup. Problem 1: Incorrect order of OCISessionEnd and OCIServerDetach calls in php_oci_connection_close() The "Terminating the Application" section in chapter 2 of the OCI manual: http://download-west.oracle.com/docs/cd/B19306_01/ appdev.102/b14250/oci02bas.htm#sthref217 says to call OCISessionEnd before calling OCIServerDetach. Problem 2: In php_oci_connection_close(), connection->session is used after it has been freed. Problem 3: In php_oci_connection_close() why are there some "free" and some "efree" calls? Problem 4: In php_oci_cleanup_global_handles() the error handle should be of type OCI_HTYPE_ERROR, not OCI_HTYPE_ENV Problem 5 (minor suggestion): Calls to OCIEnvInit, OCIHandleAlloc, OCIErrorGet & OCIHandleFree in php_oci_init_global_handles() could use PHP_OCI_CALL() so debug trace is generated. Call to OCIInitialize in PHP_MINIT_FUNCTION() could use PHP_OCI_CALL(). Call to OCITerminate in PHP_MSHUTDOWN_FUNCTION() could use PHP_OCI_CALL(). A suggested patch is below. Please review and test as I may have misunderstood the solutions for problems 3 and 5, or not have taken care of some special cases. I have been unable to verify the patch solves the problem because I only see the problem on Windows, but can only build on Linux. --- oci8.c.1.283 2005-11-25 15:52:57.000000000 +1100 +++ oci8.c 2005-11-25 17:18:41.006806296 +1100 @@ -396,13 +396,13 @@ sb4 error_code = 0; text tmp_buf[PHP_OCI_ERRBUF_LEN]; - errcode = OCIEnvInit (&OCI_G(env), OCI_DEFAULT, 0, NULL); + errcode = PHP_OCI_CALL(OCIEnvInit, (&OCI_G(env), OCI_DEFAULT, 0, NULL)); if (errcode == OCI_ERROR) { goto oci_error; } - errcode = OCIHandleAlloc (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL); + errcode = PHP_OCI_CALL(OCIHandleAlloc, (OCI_G(env), (dvoid **)&OCI_G(err), OCI_HTYPE_ERROR, 0, NULL)); if (errcode == OCI_ERROR || errcode == OCI_SUCCESS_WITH_INFO) { goto oci_error; @@ -412,7 +412,7 @@ oci_error: - OCIErrorGet(OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR); + PHP_OCI_CALL(OCIErrorGet, (OCI_G(env), (ub4)1, NULL, &error_code, tmp_buf, (ub4)PHP_OCI_ERRBUF_LEN, (ub4)OCI_HTYPE_ERROR)); if (error_code) { int tmp_buf_len = strlen(tmp_buf); @@ -424,7 +424,7 @@ if (errcode != OCI_SUCCESS_WITH_INFO) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_ERROR: %s", tmp_buf); - OCIHandleFree((dvoid *) OCI_G(env), OCI_HTYPE_ENV); + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(env), OCI_HTYPE_ENV)); OCI_G(env) = NULL; OCI_G(err) = NULL; @@ -441,7 +441,7 @@ static void php_oci_cleanup_global_handles(TSRMLS_D) { if (OCI_G(err)) { - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ENV)); + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) OCI_G(err), OCI_HTYPE_ERROR)); OCI_G(err) = NULL; } @@ -480,7 +480,7 @@ #endif #if !HAVE_OCI_ENV_CREATE - OCIInitialize(PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL); + PHP_OCI_CALL(OCIInitialize, (PHP_OCI_INIT_MODE, NULL, NULL, NULL, NULL)); #endif ZEND_INIT_MODULE_GLOBALS(oci, php_oci_init_globals, NULL); @@ -609,7 +609,7 @@ #endif #if !HAVE_OCI_ENV_CREATE - OCITerminate(OCI_DEFAULT); + PHP_OCI_CALL(OCITerminate, (OCI_DEFAULT)); #endif return SUCCESS; @@ -1408,10 +1408,18 @@ } } + if (connection->svc && connection->session && connection->is_open) { + PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0)); + } + if (connection->is_attached) { PHP_OCI_CALL(OCIServerDetach, (connection->server, OCI_G(err), OCI_DEFAULT)); } + if (connection->svc) { + PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); + } + if (connection->err) { PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->err, (ub4) OCI_HTYPE_ERROR)); } @@ -1424,23 +1432,15 @@ PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->server, (ub4) OCI_HTYPE_SERVER)); } - if (connection->svc) { - if (connection->session && connection->is_open) { - PHP_OCI_CALL(OCISessionEnd, (connection->svc, OCI_G(err), connection->session, (ub4) 0)); - } - - PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->svc, (ub4) OCI_HTYPE_SVCCTX)); - } - if (connection->env) { PHP_OCI_CALL(OCIHandleFree, ((dvoid *) connection->env, OCI_HTYPE_ENV)); } if (connection->is_persistent) { if (connection->hash_key) { - free(connection->hash_key); + efree(connection->hash_key); } - free(connection); + efree(connection); } else { if (connection->hash_key) { Previous Comments: ------------------------------------------------------------------------ [2005-11-22 12:10:35] tony2001@php.net Since I can't reproduce it even on Solaris, you have to make a research on your own: Enable oci_internal_debug(true); and check its output. Make sure php_oci_connection_close() function is called on every connection resource. ------------------------------------------------------------------------ [2005-11-22 12:00:39] robertg2 at hope dot ac dot uk We've tried it on Linux with Instant Client 10 - it works fine. I shall speak with my superiors about providing an account but it seems unlikely we will be able to do so. Is there no other way to progress this bug report further? ------------------------------------------------------------------------ [2005-11-22 11:48:40] tony2001@php.net Works fine here, both on Linux and Solaris. Please provide an account on this server or try on a different server yourself. ------------------------------------------------------------------------ [2005-11-21 02:39:34] robertg2 at hope dot ac dot uk Okay, for real this time: Using the 32-bit instantclient 10 doesn't seem to have an effect on the behaviour in question. <? oci_connect('user', 'pw', '//HOST/DBNAME'); ?> After browsing to a script such as this via the web, the connection to the database remains. ------------------------------------------------------------------------ [2005-11-20 13:18:40] robertg2 at hope dot ac dot uk oh and... as for the comment I made at 1:55am... that was a mistake. I hadn't taken the oci_close statement out of the code. Sorry :( ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/35205 -- Edit this bug report at http://bugs.php.net/?id=35205&edit=1

« previous php.bugs (#88902) next »