ID: 32981 User updated by: phpbug at swift-web dot com Reported By: phpbug at swift-web dot com -Status: No Feedback +Status: Open Bug Type: Reproducible crash Operating System: Gentoo 2.6.11 PHP Version: 5.0CVS (2005-05-09) New Comment:
Sorry for the long delay in getting back to this. Tried using just a plain php install as suggested (./configure --enable-debug --with-apxs2=/usr/sbin/apxs2) and I was still getting the seg fault error consistently on two different test boxes. I tried looking at my code again and came up with an idea. if a class has the static variables defined within the class but outside the methods eg: class test { private static $test = true; public function test_method() { // do whatever and access the // static property as: self::$test } } then no seg faults occur when I dump this classes details with my "dump" class which uses ReflectionMethod::getStaticVariables(). If however the above class is done this way instead (with the static value only used in the method not in entire class): class test { public function test_method() { static $test = true; // do whatever and access the // static property just as $test } } Then using my debug dump class to display information about the class causes a seg fault. I haven't given you my debug/dump class, maybe this is what you need to reproduce the seg fault crash. I'll include the class below. To use the dump class I simply call it statically debug::dump($new = new test(),'test class',true,true); *(replace test() with the name of the class you want information about obviously but my test about used the name test) here is the class ////////// start of php code class debug{ /** * dump out variables to easy to read html tables * variable can be array, string, boolean, object or hash mixture * * @param mix $data variable to be dumped * str $label optional top label for table * boo $show_docs true = show documentation for an object item * false (default) = do not show docs for an object item * boo $public_only true (default) = when displaying objects only * show public items * false = show everything about the object * * returns html output */ final public static function dump($data,$label='',$show_docs=false,$public_only=true) { // 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.ss_debug::dump_html_table($data,$style,$show_docs,$public_only).'</td></tr></table><br />'); } /** * used privately by dump method */ final private static function dump_html_table($data,&$style,$show_docs,$public_only) { if (!is_array($data)) { if ($data === NULL) { return('--NULL--'); } switch (gettype($data)) { case 'string': //if ($data === NULL) { //return('--NULL--'); //} return ( isset ( $data ) && !empty ( $data ) ) ? '<pre>'.htmlentities($data)."</pre>" : ' '; 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) { if ($method->isPublic() || $public_only !== true) { $result = array(); $name = '<font color="grey">'; if ($method->isPublic()) { $name .= '<i>public</i> '; } elseif ($method->isPrivate()) { $name .= '<i>private</i> '; } elseif ($method->isProtected()) { $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 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().')'; } /* TODO: this is commented out because of a bug in the gentoo php installation, where if the static variables still contain there * default values then this causes a seg fault error */ $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><default></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']); } } // removed following line interface (not interfaces) as it seemed to always be coming up as class (not sure what an interface is) //$obj_data['interface'] = $class->isInterface() ? 'interface' : 'class'; // removed following line from above as it seemed to display info I already have elsewhere //$obj_data['modifiers'] = sprintf('%d [%s]',$class->getModifiers(),implode(' ', Reflection::getModifierNames($class->getModifiers()))); $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']); } /* commented it out above so no need to clean it out if ($obj_data['modifiers']{0} == '0') { unset($obj_data['modifiers']); } */ if ($obj_data['static properties'] == array()) { unset($obj_data['static properties']); } if ($obj_data['properties'] == array()) { unset($obj_data['properties']); } /* old method used in php4 (did not show extra php5 info like private, public, etc) * and it only showed public properties $object_data = array ( 'class' => get_class($data), 'parent_class' => get_parent_class($data), 'methods' => get_class_methods(get_class($data)), 'properties' => get_object_vars($data) ); // by changing above line to 'properties' => (array)$data // then we could see private, protected properties but it was a mess (and still not php5 info) */ return (ss_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: //if ($data === NULL) { //return('-NULL-'); //} 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>\n <td style=\"%s\">%s</td>\n <td style=\"%s\">%s</td>\n <td style=\"%s\">%s</td>\n</tr>\n", $style['key'], $key, $style['type'], $type, $style['value'], ss_debug::dump_html_table($value,$style,$public_only,$show_docs) ); } $output .= '</table>'; return($output); } // end of ss_debug class } ///////////////////////////// end of script Previous Comments: ------------------------------------------------------------------------ [2005-05-20 01:00:05] php-bugs at lists dot php dot net No feedback was provided for this bug for over a week, so it is being suspended automatically. If you are able to provide the information that was originally requested, please do so and change the status of the bug back to "Open". ------------------------------------------------------------------------ [2005-05-12 19:23:28] [EMAIL PROTECTED] Try it with plain ./configure --enable-debug --with-apxs2=/usr/sbin/apxs2 ------------------------------------------------------------------------ [2005-05-12 18:08:13] phpbug at swift-web dot com 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>' : ' '; 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><default></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--- ------------------------------------------------------------------------ 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