ID:               32981
 User updated by:  phpbug at swift-web dot com
 Reported By:      phpbug at swift-web dot com
-Status:           Feedback
+Status:           Open
 Bug Type:         Reproducible crash
 Operating System: Gentoo 2.6.11
 PHP Version:      5.0CVS (2005-05-09)
 New Comment:

Tried today's CVS snapshot and it still gives a seg fault error.  I
think I discovered problem with the debugging.  I just noticed when I
compile with --enable-debug I get warning messages in error_log saying
that my modules were not compiled with the debug flag set and they must
be.

I tried with --disable-debug so I didn't get those warnings and apache
starts cleanly (no warning messages).  Still get seg fault error.  I'll
compile the 13 extension modules I need to set the debug flag on for
again as well (opensll, mhash, zlib, gettext, tidy, exif, fam, ncurses,
mbstring, mcrypt, sysvmsg, sysvsem, sysvshm).  I won't have time to do
this for a few days though.

I configured php with:
--prefix=/usr --host=i686-pc-linux-gnu --mandir=/usr/share/man
--infodir=/usr/share/info --datadir=/usr/share --sysconfdir=/etc
--localstatedir=/var/lib --with-jpeg-dir=/usr --with-freetype-dir=/usr
--with-t1lib=/usr --with-ttf=/usr --enable-gd-jis-conf
--enable-gd-native-ttf --with-png-dir=/usr --with-tiff-dir=/usr
--without-xpm-dir --with-gd --with-mysql
--with-mysql-sock=/var/run/mysqld/mysqld.sock --with-mm
--without-msession --enable-sqlite-utf8 --with-apxs2=/usr/sbin/apxs2
--with-config-file-path=/etc/php/apache2-php5 --without-pear
--disable-bcmath --without-bz2 --disable-calendar --without-cpdflib
--disable-ctype --without-curl --without-curlwrappers --disable-dbase
--disable-dio --enable-exif=shared --with-fam=shared --without-fbsql
--without-fdftk --disable-filepro --disable-ftp --with-gettext=shared
--without-gmp --without-hwapi --without-iconv --without-informix
--without-ingres --without-interbase --without-kerberos
--enable-mbstring=shared --with-mcrypt=shared --without-mcve
--disable-memory-limit --with-mhash=shared --without-mime-magic
--without-ming --without-mnogosearch --without-msql --without-mssql
--with-ncurses=shared --without-oci8 --without-oracle
--with-openssl=shared --with-openssl-dir=/usr --without-ovrimos
--disable-pcntl --without-pfpro --without-pgsql --disable-posix
--without-pspell --without-recode --disable-simplexml --enable-shmop
--without-snmp --disable-soap --disable-sockets --without-sybase
--without-sybase-ct --enable-sysvmsg=shared --enable-sysvsem=shared
--enable-sysvshm=shared --with-tidy=shared --disable-tokenizer
--disable-wddx --without-xsl --without-xmlrpc --disable-yp
--with-zlib=shared --disable-debug --disable-dba --with-readline
--without-libedit

I have apache-2.0.54-r3 compiled with mpm-prefork and ssl flags set.

Here is a complete cut 'n paste of the script I run to display class
information along with comments on how I can make it work (*note you'll
also see a comment out where isDestructor() always returns true as
well)

---start of code---
<?php
        // test for php Reflection bug (default static property value crash)
?><html>
<head>
<title>Test for php Reflection bug</title>
</head>
<body>
<center><h1>Test for php Reflection bug</h1></center>
<hr>
<?php
        //      phpinfo(); exit;

        /*
        * works when I call the below method (that overrides default static
property)
        * but when commented out page exits immediately
        */
//      debug::jason();
        echo debug::dump(new debug(),'debug()',0,true);

        // When I either comment out (or activate) line "debug::jason();", 
        // I change the text below to give a quick visual confirmation that
        // page is not actually fully running when I reload the page
        echo 'done';
        
        
        echo '</body></html>';





        // classes defined below
        class debug {
                final public static function jason($jason = true) {
                        static $mark = false;
                        if ($jason !== false) {
                                $mark = $jason;
                        } else {
                                return($mark);
                        }
                }

                final public static function
dump($data,$label='',$public_only=true,$show_docs=false) {
                        // make sure public_only & show_docs is just true or 
false
                        $public_only = ($public_only != false) ? true : false;
                        $show_docs = ($show_docs != false) ? true : false;
                        // setup styles for html output
                        $style['key']   = 'font-family: sans-serif; text-align: 
right;
font-size: 12px; font-weight: bold; background-color: #000; color:
#f0f0f0;';
                        $style['value'] = 'font-family: sans-serif; font-size: 
11px; color:
#009; background-color: #eee'; // monospace
                        $style['type']  = 'font-family: sans-serif; text-align: 
center;
font-size: 12px; background-color: #9cc; color: #600;';//#F6F6F6
                        $output = '<table border="2" bordercolor="#000080" 
cellpadding="0"
cellspacing="0"><tr><td style="font-family: sans-serif; font-size:
14px; background-color: #000080; color: white;">'.($label != '' ?
$label : 'variable dump - no variable name passed').'</td></tr><tr><td
style="font-family: sans-serif; text-align: center; font-size: 12px;
background-color: #9cc; color:
#600;">'.gettype($data).'</td></tr><tr><td>';
                        
return($output.debug::dump_html_table($data,$style,$public_only,$show_docs).'</td></tr></table><br
/>');
                }

                final private static function
dump_html_table($data,&$style,$public_only,$show_docs) {
                        if (!is_array($data)) {
                                switch (gettype($data)) {
                                        case 'string':
                                                return ( isset ( $data ) && 
!empty ( $data ) ) ?
'<pre>'.htmlentities($data).'</pre>' : '&nbsp;';
                                                break; // string
                                        case 'boolean':
                                                return($data ? 'true' : 
'false');
                                                break; // boolean
                                        case 'object':
                                                // search patterns to replace 
wasted front whitespace or empty
lines
                                                $doc_search = array('/^(\t| 
)*\/\*\*/','/^(\t| )*/m','/^(\t|
)*(\*\/)?(\t| )*(\n)?$/m','/^(\w|\*|\r|\n)*$/m');
                                                // convert object to array (so 
we can find private and protected
properties)
                                                $raw_properties = (array)$data;
                                                // Create an instance of the 
ReflectionClass class to give us
more detailed info
                                                $class = new 
ReflectionClass(get_class($data));
                                                $class_name = $class->getName();
                                                // get method info
                                                $methods = $properties = 
array();
                                                foreach ($class->getMethods() 
as $method) {
                                                        $result = array();
                                                        $name = '<font 
color="grey">';
                                                        if 
($method->isPublic()) {
                                                                $name .= 
'<i>public</i> ';
                                                        } elseif 
($method->isPrivate()) {
                                                                if 
($public_only === true) {
                                                                        break;
                                                                }
                                                                $name .= 
'<i>private</i> ';
                                                        } elseif 
($method->isProtected()) {
                                                                if 
($public_only === true) {
                                                                        break;
                                                                }
                                                                $name .= 
'<i>protected</i> ';
                                                        }
                                                        if 
($method->isStatic()) {
                                                                $name .= 
'<i>static</i> ';
                                                        }
                                                        if 
($method->isAbstract()) {
                                                                $name .= 
'<i>abstract</i> ';
                                                        }
                                                        if ($method->isFinal()) 
{
                                                                $name .= 
'<i>final</i> ';
                                                        }
                                                        $name .= 
'</font>'.$method->getName();
                                                        if ($show_docs === 
true) {
                                                                $result['docs'] 
= $method->getDocComment();
                                                                if 
($result['docs'] == false) {
                                                                        
unset($result['docs']);
                                                                } else {
                                                                        
$result['docs'] =
preg_replace($doc_search,'',$result['docs']);
                                                                }
                                                        }
                                                        $result['params'] = '';
                                                        
foreach($method->getParameters() as $parameter) {
                                                                
$result['params'] .= $parameter->__toString().", \n";
                                                        }
                                                        if ($result['params'] 
== false) {
                                                                
unset($result['params']);
                                                        } else {
                                                                
$result['params'] = substr($result['params'],0,-3);
                                                        }
                                                        $result['info'] = '';
                                                        if 
($method->isConstructor()) {
                                                                $result['info'] 
.= 'constructor, ';
                                                        }
                                                        /* does not appear to 
work (it always returns true)
                                                        if 
($method->isDestructor()) {
                                                                $result['info'] 
.= 'destructor, ';
                                                        }
                                                        */
                                                        if 
($method->isInternal()) {
                                                                $result['info'] 
.= 'internal (built-into php)';
                                                        } else {
                                                                $result['info'] 
.= 'user-defined (lines
'.$method->getStartLine().' - '.$method->getEndline().')';
                                                        }
                                                        $result['static vars'] 
= $method->getStaticVariables();
                                                        if ($result['static 
vars'] == array()) {
                                                                
unset($result['static vars']);
                                                        }
                                                        $methods[$name] = 
$result;
                                                }
                                                // get property info
                                                foreach 
($class->getProperties() as $prop) {
                                                        $prop_name = 
$prop->getName();
                                                        $result = array();
                                                        $name = '<font 
color="grey">';
                                                        if ($prop->isDefault()) 
{
                                                                $name .= 
'<i>&lt;default&gt;</i> ';
                                                        }
                                                        if ($prop->isPublic()) {
                                                                $name .= 
'<i>public</i> ';
                                                        } elseif 
($prop->isPrivate()) {
                                                                if 
($public_only === true) {
                                                                        break;
                                                                }
                                                                $name .= 
'<i>private</i> ';
                                                        } elseif 
($prop->isProtected()) {
                                                                if 
($public_only === true) {
                                                                        break;
                                                                }
                                                                $name .= 
'<i>protected</i> ';
                                                        }
                                                        if ($prop->isStatic()) {
                                                                $name .= 
'<i>static</i> ';
                                                        }
                                                        $name .= 
"</font>$prop_name";
                                                        
                                                        $found = false;
                                                        foreach 
($raw_properties as $key => $value) {
                                                                if 
(strpos($key,$prop_name,(strlen($key)-strlen($prop_name))))
{
                                                                        
$properties[$name] = $value;
                                                                        $found 
= true;
                                                                        
unset($raw_properties[$key]);
                                                                        break;
                                                                }
                                                        }
                                                        if ($found === false) {
                                                                
$properties[$name] = NULL;
                                                        }
                                                }
                                                // get class info
                                                $keywords = 
$class->isAbstract() ? 'abstract ' : '';
                                                $keywords .= $class->isFinal() 
? 'final ' : '';
                                                $keywords .= $class_name;
                                                $parent = 
$class->getParentClass();
                                                $parent = (array)$parent;
                                                if (isset($parent['name'])) {
                                                        $keywords .= ' extends 
'.$parent['name'];
                                                }
                                                $obj_data['class'] = $keywords;
                                                $obj_data['declared in'] = 
$class->getFileName().' (lines
'.$class->getStartLine().' - '.$class->getEndline().')';
                                                if ($show_docs === true) {
                                                        $obj_data['docs'] = 
$class->getDocComment();
                                                        if ($obj_data['docs'] 
== false) {
                                                                
unset($obj_data['docs']);
                                                        }  else {
                                                                
$obj_data['docs'] =
preg_replace($doc_search,'',$obj_data['docs']);
                                                        }
                                                }
                                                $obj_data['interfaces'] = 
($class->getInterfaces() == array() &&
count($class->getInterfaces()) > 0) ?
var_export($class->getInterfaces(),1) : 'none';
                                                $obj_data['constants'] = 
(($class->getConstants() == array() &&
count($class->getConstants()) > 0) ? $class->getConstants() : 'none');
                                                $obj_data['static properties'] 
= $class->getStaticProperties();
                                                $obj_data['properties'] = 
$properties;
                                                $obj_data['methods'] = $methods;
                                                // unset empty fields to save 
space
                                                if ($obj_data['interfaces'] == 
'none') {
                                                        
unset($obj_data['interfaces']);
                                                }
                                                if ($obj_data['constants'] == 
'none') {
                                                        
unset($obj_data['constants']);
                                                }
                                                if ($obj_data['static 
properties'] == array()) {
                                                        unset($obj_data['static 
properties']);
                                                }
                                                if ($obj_data['properties'] == 
array()) {
                                                        
unset($obj_data['properties']);
                                                }
                                                return
(debug::dump_html_table($obj_data,$style,$public_only,$show_docs));
                                                break; 
                                        case 'resource':
                                                return sprintf('%s 
(%s)',$data,get_resource_type($data));
                                                break; 
                                        default: 
                                                return $data;
                                                break; 
                                }
                        }
                        $output = '<table border="1" cellpadding="3" 
cellspacing="0">';
                        foreach ($data as $key => $value) {
                                $type = substr(gettype($data[$key]),0,3);
                                $output .= sprintf ( 
                                        '<tr>
                                        <td style="%s">%s</td>
                                        <td style="%s">%s</td>
                                        <td style="%s">%s</td>
                                        </tr>',
                                        $style['key'], $key,
                                        $style['type'], $type,
                                        $style['value'],
debug::dump_html_table($value,$style,$public_only,$show_docs)
                                );
                        } 
                        $output .= '</table>';
                        return($output);
                }
                // end of debug class
        }


?>
---end of code---


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

[2005-05-11 21:46:28] [EMAIL PROTECTED]

Nobody is able to reproduce it (me neither), so try to rebuild PHP
(grab new snapshot for that) and if you're still able to replicate it,
provide more info about your build: configure options, software used
etc.

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

[2005-05-10 17:16:44] phpbug at swift-web dot com

I couldn't make sense of the backtrace either.  phpinfo() confirms I
have --enable-debug flag set.

I have no Zend extensions loaded.

I don't have apache compiled with --enable-debug.  Is that part of the
problem?

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

[2005-05-10 14:40:14] [EMAIL PROTECTED]

That backtrace is useless to us. You really didn't configure with
--enable-debug. 

Are you using any Zend extensions (any extension loaded with
zend_extension in php.ini) ?


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

[2005-05-10 04:55:33] phpbug at swift-web dot com

The script I run that crashes is a class I called ss_debug and it has a
dump method that will use the Reflection methods to output into a easy
to read table information about a class.

I remembered the ss_debug class has methods with static values so I set
it to report/parse itself and it ran, but only if I did it at the end of
a script that ran normally (If I tried dumping the output at the
beginning of a script or just an empty script like entered as an
example earlier, it crashed).

This confused me why it ran at the end and not at the beginning.  I
tried adding a new method to this class that simple was:

function jason() {
  static $me = true;
}

now it crashed all the time (whether I ran it on it's own or after a
page that normally worked).

Pulled a few hairs out and then it dawned on me to override the default
setting in that class before I dumped it and now it works.

So what I have narrowed it down to consistently is if I have static
variables that are still in their default setting of boolean true or
false then it causes a seg fault.  If I override the default setting
before dumping (running the reflection class/methods) then it works. 
Did I explain this clear enough?

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

[2005-05-10 04:01:09] phpbug at swift-web dot com

Couldn't get a core file (even though compiled with --enable-debug) so
I ran httpd -X under gdb
cut 'n paste bt results here:

#0  0xb7cca595 in memcpy () from /lib/libc.so.6
#1  0xb7a90f71 in zif_vprintf () from
/usr/lib/apache2/modules/libphp5.so
#2  0x0822ee7b in ?? ()
#3  0x00000000 in ?? ()
#4  0x00000005 in ?? ()
#5  0xb7b2411e in zend_make_printable_zval () from
/usr/lib/apache2/modules/libphp5.so
#6  0xbffed060 in ?? ()
#7  0xb7b99b20 in php_tiff_bytes_per_format () from
/usr/lib/apache2/modules/libphp5.so
#8  0x00000103 in ?? ()
#9  0xb7b0ea04 in _emalloc () from /usr/lib/apache2/modules/libphp5.so
#10 0xbffec64c in ?? ()
#11 0xbffec648 in ?? ()
#12 0x00000052 in ?? ()
#13 0xb7a903c0 in zif_vprintf () from
/usr/lib/apache2/modules/libphp5.so
#14 0xbffec644 in ?? ()
#15 0xbffec648 in ?? ()
#16 0xbffec64c in ?? ()
#17 0x00000000 in ?? ()
#18 0x00000000 in ?? ()
#19 0x00000000 in ?? ()
#20 0x00000020 in ?? ()
#21 0x00000001 in ?? ()
#22 0x00000004 in ?? ()
#23 0x00000000 in ?? ()
#24 0x00000000 in ?? ()
#25 0x00000000 in ?? ()
#26 0x00000000 in ?? ()
#27 0x00000000 in ?? ()
#28 0x00000000 in ?? ()
#29 0x00000000 in ?? ()
#30 0x00000000 in ?? ()
#31 0x00000000 in ?? ()
#32 0x20000000 in ?? ()
#33 0x081e9cbc in ?? ()
#34 0x00000000 in ?? ()
#35 0x00000007 in ?? ()
#36 0x00000000 in ?? ()
#37 0x00000000 in ?? ()
#38 0x00000001 in ?? ()
#39 0x00000007 in ?? ()
#40 0x00000000 in ?? ()
#41 0x08220dc4 in ?? ()
#42 0x08220324 in ?? ()
#43 0x0822ed04 in ?? ()
#44 0x00000177 in ?? ()
#45 0x000001e0 in ?? ()
#46 0x00000001 in ?? ()
#47 0x00000000 in ?? ()
(line 47 repeats the same until 450)
#451 0xbffecca8 in ?? ()
#452 0x081f2d64 in ?? ()
#453 0x00000000 in ?? ()
(line 453 repeats the same until 596)
#597 0x73000000 in ?? ()
#598 0xb7d572a0 in ?? () from /lib/libc.so.6
#599 0x00000000 in ?? ()
#600 0x00000000 in ?? ()
#601 0x00000000 in ?? ()
#602 0x00000000 in ?? ()
#603 0x00000000 in ?? ()
#604 0x081ff8cc in ?? ()
#605 0x00000000 in ?? ()
#606 0x00000005 in ?? ()
#607 0x19999999 in ?? ()
#608 0x00000000 in ?? ()
#609 0xb7d6eff4 in ?? () from /lib/libc.so.6
#610 0x081ff8cc in ?? ()
#611 0x00000006 in ?? ()
#612 0xbffecf48 in ?? ()
#613 0xb7c8fefa in __strtol_internal () from /lib/libc.so.6
#614 0x00000004 in ?? ()

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

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/32981

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

Reply via email to