ID: 11990
Updated by: stas
Reported By: [EMAIL PROTECTED]
Old Status: Open
Status: Feedback
Bug Type: Scripting Engine problem
Operating System: RedHat Linux 6.2
PHP Version: 4.0.5, 4.0.6
New Comment:

I get a crash too, but in different place. I fear it might be just you getting out of 
memory. The script like this has pretty aggressive memory requirements. How much 
memory do you have?

Previous Comments:
------------------------------------------------------------------------

[2001-07-16 19:08:56] [EMAIL PROTECTED]

I've spent a better part of the last week trying to dig into this problem.
What I've come up with is rather interesting.  The source of the problem
seems to be that after the first request handled by an Apache child
process, PHP doesn't properly clean up, and much of the memory space is
polluted.  I don't know enough about the Zend internals to be able to
figure out exactly happens, but I've deduced that after the first request
handled by a process, some defines (entries in the zend_constants hash
table) already have some data associated with them.  When
zend_register_constant() is called, it finds data for a given key and
doesn't reassign it.  Typically, when a process starts having problems
with defines, it segfaults after processing the script.

The following is a snippet from  /var/log/httpd/error_log with the patch below 
applied:

[11074] Registering string constant HREF_SEC_BASE: 
https://webtech13.hq.insight.com/web
[11074] Constant HREF_SEC_BASE already defined: gnome-terminal
[11074] Constant href_sec_base already defined
[11074] Beginning compare of data
[11074] data1:          https://webtech13.hq.insight.com/web
[11074] pData(...).val: gnome-terminal
[11074] *** Match failed!  Data for HREF_SEC_BASE corrupted!


As the script is invoked, HREF_SEC_BASE already has (bad) data, in this case 
"gnome-terminal".

diff -urb php-4.0.6.orig/Zend/zend_constants.c php-4.0.6/Zend/zend_constants.c
--- php-4.0.6.orig/Zend/zend_constants.c        Sun Feb 25 22:43:26 2001
+++ php-4.0.6/Zend/zend_constants.c     Mon Jul 16 13:29:21 2001
@@ -23,7 +23,7 @@
 #include "zend_variables.h"
 #include "zend_operators.h"
 #include "zend_globals.h"
-
+#include <unistd.h>
 
 void free_zend_constant(zend_constant *c)
 {
@@ -243,17 +243,82 @@
 {
        char *lowercase_name = zend_strndup(c->name, c->name_len);
        int ret = SUCCESS;
+    zend_constant *pData = NULL;
+    char *data1 = NULL;
+    int data1_len;
 
 #if 0
        printf("Registering constant for module %d\n",c->module_number);
 #endif
 
        zend_str_tolower(lowercase_name, c->name_len);
+
+    switch(c->value.type) {
+    case IS_STRING:
+        data1_len = c->value.value.str.len;
+        data1 = zend_strndup(c->value.value.str.val, data1_len);
+
+        fprintf(stderr, "[%d] Registering string constant %s: %s\n",
+                getpid(), c->name, c->value.value.str.val);
+
+        if(zend_hash_find(EG(zend_constants), lowercase_name, c->name_len, (void 
+*)&pData) == SUCCESS) {
+            fprintf(stderr, "[%d] Constant %s already defined: %s\n",
+                    getpid(),
+                    c->name,
+                    pData->value.value.str.val);
+            
+            pData = NULL;
+        }
+        break;
+        
+    default:
+        if(zend_hash_find(EG(zend_constants), lowercase_name, c->name_len, (void 
+*)&pData) == SUCCESS) {
+            fprintf(stderr, "[%d] Constant %s already defined\n",
+                    getpid(),
+                    c->name);
+            
+            pData = NULL;
+        }
+        break;
+    }
+
        if (zend_hash_add(EG(zend_constants), lowercase_name, c->name_len, (void *) c, 
sizeof(zend_constant), NULL)==FAILURE) {
                zval_dtor(&c->value);
                zend_error(E_NOTICE,"Constant %s already defined",lowercase_name);
                ret = FAILURE;
        }
+
+    // retrieve data and compare data
+    if(c->value.type == IS_STRING) {
+        if(data1 != NULL) {
+            if(zend_hash_find(EG(zend_constants), lowercase_name, c->name_len, (void 
+*)&pData) == SUCCESS) {
+                // compare data
+                fprintf(stderr, "[%d] Beginning compare of data\n", getpid());
+                fprintf(stderr, "[%d] data1:          %s\n", getpid(), data1);
+                fprintf(stderr, "[%d] pData(...).val: %s\n", getpid(), 
+pData->value.value.str.val);
+        
+                if(pData->value.value.str.len != data1_len)
+                    fprintf(stderr, "[%d] *** String lengths different!\n", 
+getpid());
+                else {
+                    int ind;
+                    char *data2 = pData->value.value.str.val;
+                    
+                    for(ind = 0; ind < pData->value.value.str.len; ind++) {
+                        if(data1[ind] != data2[ind]) {
+                            fprintf(stderr, "[%d] *** Match failed!  Data for %s 
+corrupted!\n",
+                                    getpid(), c->name);
+                            break;
+                        }
+                    }
+                }
+            } else {
+                fprintf(stderr, "[%d] Couldn't retrieve data for %s\n", getpid(), 
+c->name);
+            }
+
+            free(data1);
+        }
+    }
+
        free(lowercase_name);
        return ret;
 }


------------------------------------------------------------------------

[2001-07-10 17:45:20] [EMAIL PROTECTED]

Well, I haven't succeeded yet in reproducing the corrupted define, but I have managed 
to repeatably kill PHP with a 200002 line script generated by the following shell 
script:

        echo "<?php" 

        define="this is a very long define, indeed! asdf asdf asdf asdf asdf asdf asdf 
asdf asdf asdf asdf asdf asdf asdf asdf asdf"

        count=0 
        while [ $count -lt 100000 ]; do 
            echo "define(\"DEF_${count}\", \"$define\");" 
            echo "if(DEF_${count} != \"$define\") { print(\"bad\"); }" 
        
            count=$(($count + 1)) 
        done 
        echo "?>" 

I redirected that to a file and ran php through gdb.  here's the resulting stack 
trace: 

(gdb) run 
Starting program: /home/blalor/redhat/BUILD/php-4.0.6/php_standalone ../test.php 

Program received signal SIGSEGV, Segmentation fault. 
0x812770b in execute (op_array=0x81dc6c4) at ./zend_execute.c:1639 
(gdb) bt 
#0  0x812770b in execute (op_array=0x81dc6c4) at ./zend_execute.c:1639 
#1  0x80ee58b in zend_execute_scripts (type=8, file_count=3) at zend.c:752 
#2  0x80635a1 in php_execute_script (primary_file=0xbffff554) at main.c:1206 
#3  0x80615c9 in main (argc=2, argv=0xbffff5b4) at cgi_main.c:718 
[snip] 
(gdb) print valptr->value 
$1 = {lval = 136194132, dval = 1.067726779661273e-313, str = { 
    val = 0x81e2854 "DEF_0", len = 5}, ht = 0x81e2854, obj = {ce = 0x81e2854, 
    properties = 0x5}} 

Note that it appears that PHP is trying to access the data for DEF_0 at 
zend_execute.c:1639. 

Note that I did this with php 4.0.6, not 4.0.5.  *Some* kind of problem still exists 
there... 

------------------------------------------------------------------------

[2001-07-10 17:43:05] [EMAIL PROTECTED]

Configure options:

./configure --prefix=/usr --with-config-file-path=/etc --with-apxs=/usr/sbin/apxs 
--with-exec-dir=/usr/bin --disable-magic-quotes --enable-track-vars --enable-wddx 
--without-mysql --with-oci8=/home/oracle/product/8.0.5 
--with-esoob=/usr/local/easysoft/oob/client --enable-sockets --disable-pear --with-xml 
--enable-inline-optimization

Having difficulty reproducing bug; it is very intermittent...

------------------------------------------------------------------------

[2001-07-09 19:51:36] [EMAIL PROTECTED]

Would it be possible to test this same script with PHP 4.0.6? I don't remember anyone 
reporting anything like this before and I have never experienced anything like this 
myself.

Also, if you could create a short bug complete script
which could be used to reproduce this, it would
be a lot easier to debug this issue.

And what was your configure line used to configure PHP ?

--Jani


------------------------------------------------------------------------

[2001-07-09 18:13:11] [EMAIL PROTECTED]

We're seeing severe data corruption problems with defines.

For example, the following snippet is from a PHP script that uses defined constants to 
build up a filename.  The resulting variable contains junk data.

no exist :ieldp/c­├<─classsupport/getproductlist.php
Warning: Failed opening 'ield' for inclusion (include_path='.:/u/php:/u/htdocs') in 
/u/php/corelib/sp/procedure.php on line 57
no exist :ieldp/c­├<─classsupport/getfullproduct.php
Warning: Failed opening 'ield' for inclusion (include_path='.:/u/php:/u/htdocs') in 
/u/php/corelib/sp/procedure.php on line 57

PHP doesn't seem to crash.

------------------------------------------------------------------------



Edit this bug report at http://bugs.php.net/?id=11990&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to