A few months back i submitted a bug report #21855 and forgotten about it.
In short ...certain complex enough scripts would cause PHP to crash and burn
on HPUX. The gdb backtraces and the fault generated seemed to indicate that
memory access was beging performed in the guard pages located just beyond
stack limits.
The bug has been fixed in our HP Apache distribution for sometime now.
The Problem:
HPUX has a default thread stack limit pitched at 64k on PARISC and 256k on
Itanium. For sufficiently complex scripts, I measured and found that PHP's
execution engine (execute() in zend_engine.c ) gets recursive and consumes
more than this default stack limit. The reason being that dynamic memory
allocation (for the opcodes?)is done on the stack instead of heap (for
performance reasons I guess).
This has showed up on HPUX easily perhaps due to its relatively smaller
default stack size. But in any case one cant count on PHP to be under the
stack limit
for "sufficiently complex" scripts on any OS as such which i beleive is
typically is KiloBytes. Increasing thread stack size at thread creation time
only (in apache)
delays the onset of problem and wastes memory for Apache threads that are
not
servicing PHP requests.
Solution:
Allocate from the heap, and take the performance hit.
<<< file 1: zend_execute.c
file 2: fixed_zend_execute.c
-----[1015 changed to 1015]-----
< EX(Ts) = (temp_variable *)
do_alloca(sizeof(temp_variable)*op_array->T);
EX(Ts) = (temp_variable *)
emalloc(sizeof(temp_variable)*op_array->T);
-----[1711 changed to 1711]-----
< free_alloca(EX(Ts));
efree(EX(Ts));
--Roshan
Possibly better one (not tested):
Index: Zend/zend.h
RCS file: /repository/ZendEngine2/zend.h,v
retrieving revision 1.210
diff -u -r1.210 zend.h
--- Zend/zend.h 10 Jun 2003 20:03:24 -0000 1.210
+++ Zend/zend.h 19 Jul 2003 03:54:19 -0000
@@ -146,7 +146,7 @@
endif
#endif
-#if (HAVE_ALLOCA || (defined (GNUC) && GNUC >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE))
+#if (HAVE_ALLOCA || (defined (GNUC) && GNUC >= 2)) && !(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE)) && !defined(HPUX)
define do_alloca(p) alloca(p)
define free_alloca(p)
#else
Moriyoshi
"NAIK,ROSHAN (HP-Cupertino,ex1)" roshan.naik@hp.com wrote:
Solution:
Allocate from the heap, and take the performance hit.
<<< file 1: zend_execute.c
file 2: fixed_zend_execute.c
-----[1015 changed to 1015]-----
< EX(Ts) = (temp_variable *)
do_alloca(sizeof(temp_variable)*op_array->T);EX(Ts) = (temp_variable *)
emalloc(sizeof(temp_variable)*op_array->T);
-----[1711 changed to 1711]-----
< free_alloca(EX(Ts));efree(EX(Ts));
I commited this patch.
Andi
At 12:58 PM 19/7/2003 +0900, Moriyoshi Koizumi wrote:
Possibly better one (not tested):
Index: Zend/zend.h
RCS file: /repository/ZendEngine2/zend.h,v
retrieving revision 1.210
diff -u -r1.210 zend.h
--- Zend/zend.h 10 Jun 2003 20:03:24 -0000 1.210
+++ Zend/zend.h 19 Jul 2003 03:54:19 -0000
@@ -146,7 +146,7 @@endif
#endif
-#if (HAVE_ALLOCA || (defined (GNUC) && GNUC >= 2)) &&
!(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) && defined(NETWARE))
+#if (HAVE_ALLOCA || (defined (GNUC) && GNUC >= 2)) &&
!(defined(ZTS) && defined(ZEND_WIN32)) && !(defined(ZTS) &&
defined(NETWARE)) && !defined(HPUX)define do_alloca(p) alloca(p)
define free_alloca(p)
#else
Moriyoshi
"NAIK,ROSHAN (HP-Cupertino,ex1)" roshan.naik@hp.com wrote:
Solution:
Allocate from the heap, and take the performance hit.
<<< file 1: zend_execute.c
file 2: fixed_zend_execute.c
-----[1015 changed to 1015]-----
< EX(Ts) = (temp_variable *)
do_alloca(sizeof(temp_variable)*op_array->T);EX(Ts) = (temp_variable *)
emalloc(sizeof(temp_variable)*op_array->T);
-----[1711 changed to 1711]-----
< free_alloca(EX(Ts));efree(EX(Ts));
I commited this patch.
Note that the post concerned the _thread_ stack limit. As
such, !(defined(ZTS) && defined(HPUX)) sounds more
reasonable.
- Sascha