Index: zend.c =================================================================== RCS file: /repository/ZendEngine2/zend.c,v retrieving revision 1.308.2.7 diff -u -r1.308.2.7 zend.c --- zend.c 4 Jan 2006 23:53:03 -0000 1.308.2.7 +++ zend.c 26 Feb 2006 20:02:54 -0000 @@ -29,6 +29,10 @@ #include "zend_builtin_functions.h" #include "zend_ini.h" +#include +#include +#define ALT_STACK_SIZE (2*SIGSTKSZ) + #ifdef ZTS # define GLOBAL_FUNCTION_TABLE global_function_table # define GLOBAL_CLASS_TABLE global_class_table @@ -99,6 +103,8 @@ ZEND_API zval zval_used_for_init; /* True global variable */ +static char altstack[ALT_STACK_SIZE]; /* alternative stack to the SIGSEGV handler*/ + /* version information */ static char *zend_version_info; static uint zend_version_info_length; @@ -553,6 +559,20 @@ void zend_init_opcodes_handlers(); + +static void zend_sigsegv_handler(int signo) { + stack_t stackinfo; + sigaltstack(NULL, &stackinfo); + + /* TODO: use stack_violation() on Solaris */ + if (stackinfo.ss_flags & SS_ONSTACK) { + zend_error(E_ERROR, "stack overflow (probably caused by a recursive function)"); + //zend_bailout(); + } + + exit(0xdead); +} + int zend_startup(zend_utility_functions *utility_functions, char **extensions, int start_builtin_functions) { #ifdef ZTS @@ -675,6 +695,25 @@ tsrm_set_new_thread_end_handler(zend_new_thread_end_handler); #endif + { + /* get an alternative stack */ + stack_t newstack = { + .ss_sp = (void*) altstack, + .ss_size = ALT_STACK_SIZE, + .ss_flags = 0 + }; + sigaltstack(&newstack, NULL); + + /* set signal handlers */ + struct sigaction act = { + .sa_flags = SA_ONSTACK, + .sa_handler = zend_sigsegv_handler, + }; + + sigemptyset(&(act.sa_mask)); + sigaction(SIGSEGV, &act, NULL); + } + return SUCCESS; } @@ -770,7 +809,7 @@ CG(unclean_shutdown) = 1; CG(in_compilation) = EG(in_execution) = 0; EG(current_execute_data) = NULL; - longjmp(EG(bailout), FAILURE); + siglongjmp(EG(bailout), FAILURE); } END_EXTERN_C() Index: zend.h =================================================================== RCS file: /repository/ZendEngine2/zend.h,v retrieving revision 1.293.2.9 diff -u -r1.293.2.9 zend.h --- zend.h 4 Jan 2006 23:53:03 -0000 1.293.2.9 +++ zend.h 26 Feb 2006 20:02:54 -0000 @@ -449,16 +449,16 @@ #define zend_try \ { \ - jmp_buf orig_bailout; \ + sigjmp_buf orig_bailout; \ zend_bool orig_bailout_set=EG(bailout_set); \ \ EG(bailout_set) = 1; \ - memcpy(&orig_bailout, &EG(bailout), sizeof(jmp_buf)); \ - if (setjmp(EG(bailout))==0) + memcpy(&orig_bailout, &EG(bailout), sizeof(sigjmp_buf)); \ + if (sigsetjmp(EG(bailout), 1)==0) #define zend_catch \ else #define zend_end_try() \ - memcpy(&EG(bailout), &orig_bailout, sizeof(jmp_buf)); \ + memcpy(&EG(bailout), &orig_bailout, sizeof(sigjmp_buf)); \ EG(bailout_set) = orig_bailout_set; \ } #define zend_first_try EG(bailout_set)=0; zend_try Index: zend_globals.h =================================================================== RCS file: /repository/ZendEngine2/zend_globals.h,v retrieving revision 1.141.2.3 diff -u -r1.141.2.3 zend_globals.h --- zend_globals.h 4 Jan 2006 23:53:04 -0000 1.141.2.3 +++ zend_globals.h 26 Feb 2006 20:02:54 -0000 @@ -176,7 +176,7 @@ HashTable included_files; /* files already included */ - jmp_buf bailout; + sigjmp_buf bailout; int error_reporting; int orig_error_reporting;