Today I've been debugging a segfault with my namespace patch until I found
that the problem was simply the placement of a variable in a struct. I
still don't see the logic behind it, but I got the segfault both in Windows
2000 and Linux (FC3). The steps to reproduce this segfault are very simple
(using PHP 5.1.0b2):
-
In zend_globals.h, modify the struct _zend_executor_globals and add a
simple HashTable pointer after class_table or zend_constants. It should
look like this:... HashTable *class_table; /* class table */ HashTable *my_hash; HashTable *zend_constants; /* constants table */
-
Compile PHP. Now any script you execute will produce a segmentation
fault. -
Move your hash table to the end of the struct, right before the
"reserved" array:HashTable *my_hash; void *reserved[ZEND_MAX_RESERVED_RESOURCES];
-
make clean (or simply delete all the *.o and *.lo files under Zend/) and
compile PHP again. All executed scripts work as usual, and no segfault is
produced.
Does anyone know why this happens?
Regards,
Jessie Hernandez
Perhaps this is the obvious answer, but I'm pretty sure a fair number of
structures used in the engine are, memory-space wise, portions of larger
structures defined elsewhere. This allows the larger structure to be
type-cast to a smaller structure for certain operations easily. It is
possible that the _zend_executor_globals struct is one of these cases
(although I'm not certain without digging through the code), which means
the placement of variables within the struct is important.
John
Today I've been debugging a segfault with my namespace patch until I found
that the problem was simply the placement of a variable in a struct. I
still don't see the logic behind it, but I got the segfault both in Windows
2000 and Linux (FC3). The steps to reproduce this segfault are very simple
(using PHP 5.1.0b2):
In zend_globals.h, modify the struct _zend_executor_globals and add a
simple HashTable pointer after class_table or zend_constants. It should
look like this:... HashTable *class_table; /* class table */ HashTable *my_hash; HashTable *zend_constants; /* constants table */
Compile PHP. Now any script you execute will produce a segmentation
fault.Move your hash table to the end of the struct, right before the
"reserved" array:HashTable *my_hash; void *reserved[ZEND_MAX_RESERVED_RESOURCES];
make clean (or simply delete all the *.o and *.lo files under Zend/) and
compile PHP again. All executed scripts work as usual, and no segfault is
produced.Does anyone know why this happens?
Regards,
Jessie Hernandez
Did you recompile PHP completely after you changed the struct? If
not, it's very simple. When you insert a new variable into the middle
of the structure, all the subsequent variables are shifted down. The
ones that used to be at a certain offset can no longer be found there
by the code in previously compiled modules and you are very likely to
end up with a segfault.
-Andrei
Does anyone know why this happens?
Andrei,
Yes, I did a make clean before changing the struct on both occasions
(putting it after class_table and at the end of the struct).
--
Jessie
"Andrei Zmievski" andrei@gravitonic.com wrote in message
news:EADB04D5-CC76-4A5D-940C-4D40FBBABE6B@gravitonic.com...
Did you recompile PHP completely after you changed the struct? If
not, it's very simple. When you insert a new variable into the middle
of the structure, all the subsequent variables are shifted down. The
ones that used to be at a certain offset can no longer be found there
by the code in previously compiled modules and you are very likely to
end up with a segfault.-Andrei
Does anyone know why this happens?