|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-09-14 07:15 UTC] neko at nekochan dot net
Description: ------------ Bus error during 'Generatring phar.php' phase of build; also occurs if using '--disable-phar' immediately after running 'gmake test'. Bus error occurs with both MIPSpro 7.4.4m and GCC-4.3.1 compilers under IRIX 6.5.30. Also tested with php5.3-200809140030 with same result. ./configure options: './configure' '--prefix=/usr/nekoware/php5' '--enable-dba' '--enable-calendar' '--enable-wddx' '--with-config-file-path=/usr/nekoware/etc/php5' '--with-apxs2=/usr/nekoware/apache2/bin/apxs' '--enable-cli' '--with-libxml-dir=/usr/nekoware' '--with-png-dir=/usr/nekoware' '--with-jpeg-dir=/usr/nekoware' '--with-freetype-dir=/usr/nekoware' '--with-zlib-dir=/usr/nekoware' '--with-zlib' '--with-curlwrappers' '--with-curl=shared,/usr/nekoware' '--with-openssl=shared,/usr/nekoware' '--with-mysql=shared,mysqlnd' '--with-mysqli=shared,mysqlnd' '--with-mhash=shared,/usr/nekoware' '--with-mcrypt=shared,/usr/nekoware' '--with-bz2=shared,/usr/nekoware' '--enable-ftp=shared' '--enable-sockets=shared' '--with-gd=shared' '--enable-exif=shared' '--with-xmlrpc' '--with-gettext=shared,/usr/nekoware' '--with-iconv-dir=/usr/nekoware' '--enable-mbstring=shared' '--enable-sysvsem=shared' '--enable-sysvshm=shared' '--enable-sysvmsg=shared' '--with-xpm-dir=/usr/lib32' '--enable-zip=shared' '--with-pgsql=shared,/usr/nekoware/pgsql' '--with-mm=/usr/nekoware Reproduce code: --------------- gmake or with '--disable-phar': gmake test Expected result: ---------------- Completed build and ability to run php test process. Actual result: -------------- ... Generating phar.php gmake: *** [ext/phar/phar.php] Bus error (core dumped) gmake: *** Deleting file `ext/phar/phar.php' # dbx ./sapi/cli/php core dbx version 7.3.7 (96015_Nov16 MR) Nov 16 2004 07:34:16 Core from signal SIGBUS: Bus error (dbx) where Thread 0x10000 > 0 zend_assign_to_variable(0x14a0, 0x107fde5c, 0x0, 0xc, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php- 5.3.0alpha2/Zend/zend_execute.c":739, 0x1039ebcc] 1 ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(0x107fdde8, 0xd, 0x0, 0xc, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php- 5.3.0alpha2/Zend/zend_vm_execute.h":25843, 0x103ef740] 2 execute(0x106ba598, 0xd, 0x0, 0xc, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php-5.3.0alpha2/Zend/zend_vm_execute.h":104, 0x103a0418] 3 zend_execute_scripts(0x8, 0xd, 0x3, 0x0, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php-5.3.0alpha2/Zend/zend.c":1197, 0x10374a58] 4 php_execute_script(0x14a0, 0xd, 0x0, 0xc, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php-5.3.0alpha2/main/main.c":2074, 0x10313158] 5 main(0xf, 0x7fff2ef4, 0x0, 0xc, 0x21000, 0x1000, 0xc, 0x106bab80) ["/opt/build/php-5.3.0alpha2/sapi/cli/php_cli.c":1130, 0x103fed20] 6 __start() ["/xlv55/kudzu- apr12/work/irix/lib/libc/libc_n32_M4/csu/crt1text.s":177, 0x1004cb88] (dbx) quit PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Nov 08 10:00:01 2025 UTC |
Zend has a lot of struct assignments, the HP, MIPSPro, DEC compilers seem to require that both structs be aligned on an 8 byte boundary, when they're not, we see bus errors at runtime. At first, I started changing a bunch of struct assignments to memcpy() but there were too many for my patience, some may be necessary, some not so much when I changed zend_vm_execute.h to align the Ts member. How can I attach a patch here? Oh well, here is the patch inline. Index: Zend/zend.c =================================================================== --- Zend/zend.c.orig 2009-07-10 02:55:48.761550751 +0000 +++ Zend/zend.c 2009-07-10 16:12:31.586520160 +0000 @@ -271,12 +276,12 @@ } break; case IS_DOUBLE: - *expr_copy = *expr; + memcpy(expr_copy,expr,sizeof(zval)); zval_copy_ctor(expr_copy); zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC); break; default: - *expr_copy = *expr; + memcpy(expr_copy,expr,sizeof(zval)); zval_copy_ctor(expr_copy); convert_to_string(expr_copy); break; Index: Zend/zend_vm_execute.h =================================================================== --- Zend/zend_vm_execute.h.orig 2009-07-10 02:55:48.751766645 +0000 +++ Zend/zend_vm_execute.h 2009-07-10 17:03:37.780192396 +0000 @@ -35,6 +35,22 @@ #undef EX #define EX(element) execute_data->element +#ifndef ZEND_MM_ALIGNMENT +# define ZEND_MM_ALIGNMENT 8 +# define ZEND_MM_ALIGNMENT_LOG2 3 +#elif ZEND_MM_ALIGNMENT < 4 +# undef ZEND_MM_ALIGNMENT +# undef ZEND_MM_ALIGNMENT_LOG2 +# define ZEND_MM_ALIGNMENT 4 +# define ZEND_MM_ALIGNMENT_LOG2 2 +#endif +#ifndef ZEND_MM_ALIGNMENT_MASK +#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1) +#endif +/* Aligned header size */ +#ifndef ZEND_MM_ALIGNED_SIZE +#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK) +#endif ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) { @@ -52,13 +67,15 @@ zend_vm_enter: /* Initialize execute_data */ execute_data = (zend_execute_data *)zend_vm_stack_alloc( + ZEND_MM_ALIGNMENT + ( sizeof(zend_execute_data) + - sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) + - sizeof(temp_variable) * op_array->T TSRMLS_CC); + sizeof(zval**) * op_array->last_var * + (EG(active_symbol_table) ? 1 : 2) + + sizeof(temp_variable) * op_array->T TSRMLS_CC)); EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data)); - memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2)); + memset(EX(CVs), 0, ZEND_MM_ALIGNMENT + (sizeof(zval**) * op_array->last_var)); + EX(Ts) = (temp_variable *) ZEND_MM_ALIGNED_SIZE((size_t)(EX(CVs) + (op_array->last_var) * (EG(active_symbol_table) ? 1 : 2))); EX(fbc) = NULL; EX(called_scope) = NULL; EX(object) = NULL; @@ -9085,7 +9102,7 @@ zend_free_op free_op1; zval *value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - EX_T(opline->result.u.var).tmp_var = *value; + memcpy(&EX_T(opline->result.u.var).tmp_var,value,sizeof(zval)); if (!0) { zval_copy_ctor(&EX_T(opline->result.u.var).tmp_var); } @@ -21620,8 +21637,7 @@ ZEND_VM_NEXT_OPCODE(); } - - EX_T(opline->result.u.var).tmp_var = **var_ptr; + memcpy(&EX_T(opline->result.u.var).tmp_var,*var_ptr,sizeof(zval)); zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); SEPARATE_ZVAL_IF_NOT_REF(var_ptr); Index: Zend/zend_execute_API.c =================================================================== --- Zend/zend_execute_API.c.orig 2009-06-05 18:50:32.000000000 +0000 +++ Zend/zend_execute_API.c 2009-07-10 03:47:15.369819116 +0000 @@ -769,7 +769,7 @@ /* Initialize execute_data */ if (EG(current_execute_data)) { - execute_data = *EG(current_execute_data); + memcpy(&execute_data,EG(current_execute_data),sizeof(zend_execute_data)); EX(op_array) = NULL; EX(opline) = NULL; EX(object) = NULL; Index: Zend/zend_constants.c =================================================================== --- Zend/zend_constants.c.orig 2009-01-12 21:54:37.000000000 +0000 +++ Zend/zend_constants.c 2009-07-10 16:07:17.211430061 +0000 @@ -263,7 +263,7 @@ } if (retval) { - *result = c->value; + memcpy(result,&( c->value ), sizeof(zval)); zval_copy_ctor(result); Z_SET_REFCOUNT_P(result, 1); Z_UNSET_ISREF_P(result); Index: Zend/zend_execute.c =================================================================== --- Zend/zend_execute.c.orig 2009-07-10 02:55:48.000000000 +0000 +++ Zend/zend_execute.c 2009-07-10 15:59:39.100532282 +0000 @@ -135,7 +135,7 @@ #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) #define INIT_PZVAL_COPY(z,v) \ - (z)->value = (v)->value; \ + memcpy(&((z)->value),&((v)->value),sizeof(zvalue_value)); \ Z_TYPE_P(z) = Z_TYPE_P(v); \ Z_SET_REFCOUNT_P(z, 1); \ Z_UNSET_ISREF_P(z); @@ -722,7 +722,7 @@ } else { ALLOC_ZVAL(*variable_ptr_ptr); Z_SET_REFCOUNT_P(value, 1); - **variable_ptr_ptr = *value; + memcpy(*variable_ptr_ptr,value,sizeof(zval)); } } Z_UNSET_ISREF_PP(variable_ptr_ptr);Ok, so the problem is that, by changing the size of execute_data and the alignment of the Ts member, when an exception occurs, zend no longer knows when to stop unwinding the stack. We added another member to execute_data that keeps a record of the stack top at the time of creation, we can no longer get there via the Ts member, because we may have moved it, and the variables used to calculate it, though they are stored in the execute_data struct, are not constant, and may have different values at stack unwind time. We see far fewer problems on ia64-hp-hpux with this patch. Index: Zend/zend.c =================================================================== --- Zend/zend.c.orig 2009-07-11 02:57:58.525910184 +0000 +++ Zend/zend.c 2009-07-11 02:59:39.702014580 +0000 @@ -271,12 +276,12 @@ } break; case IS_DOUBLE: - *expr_copy = *expr; + memcpy(expr_copy,expr,sizeof(zval)); zval_copy_ctor(expr_copy); zend_locale_sprintf_double(expr_copy ZEND_FILE_LINE_CC); break; default: - *expr_copy = *expr; + memcpy(expr_copy,expr,sizeof(zval)); zval_copy_ctor(expr_copy); convert_to_string(expr_copy); break; Index: Zend/zend_vm_execute.h =================================================================== --- Zend/zend_vm_execute.h.orig 2009-07-12 00:32:46.000000000 +0000 +++ Zend/zend_vm_execute.h 2009-07-12 01:38:46.131809202 +0000 @@ -35,6 +35,22 @@ #undef EX #define EX(element) execute_data->element +#ifndef ZEND_MM_ALIGNMENT +# define ZEND_MM_ALIGNMENT 8 +# define ZEND_MM_ALIGNMENT_LOG2 3 +#elif ZEND_MM_ALIGNMENT < 4 +# undef ZEND_MM_ALIGNMENT +# undef ZEND_MM_ALIGNMENT_LOG2 +# define ZEND_MM_ALIGNMENT 4 +# define ZEND_MM_ALIGNMENT_LOG2 2 +#endif +#ifndef ZEND_MM_ALIGNMENT_MASK +#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1) +#endif +/* Aligned header size */ +#ifndef ZEND_MM_ALIGNED_SIZE +#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK) +#endif ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) { @@ -52,13 +68,14 @@ zend_vm_enter: /* Initialize execute_data */ execute_data = (zend_execute_data *)zend_vm_stack_alloc( + (ZEND_MM_ALIGNMENT -1) + ( sizeof(zend_execute_data) + sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) + - sizeof(temp_variable) * op_array->T TSRMLS_CC); - + sizeof(temp_variable) * op_array->T TSRMLS_CC)); EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data)); memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2)); + EX(top) = zend_vm_stack_top(TSRMLS_C); + EX(Ts) = (temp_variable *) ZEND_MM_ALIGNED_SIZE((size_t)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); EX(fbc) = NULL; EX(called_scope) = NULL; EX(object) = NULL; @@ -602,10 +619,7 @@ int catched = 0; zval restored_error_reporting; - void **stack_frame = (void**)EX(Ts) + - (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*); - - while (zend_vm_stack_top(TSRMLS_C) != stack_frame) { + while (zend_vm_stack_top(TSRMLS_C) != EX(top)) { zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C); zval_ptr_dtor(&stack_zval_p); } Index: Zend/zend_execute.c =================================================================== --- Zend/zend_execute.c.orig 2009-07-11 02:57:58.486572714 +0000 +++ Zend/zend_execute.c 2009-07-11 02:59:40.324003151 +0000 @@ -135,7 +135,7 @@ #define IS_TMP_FREE(should_free) ((zend_uintptr_t)should_free.var & 1L) #define INIT_PZVAL_COPY(z,v) \ - (z)->value = (v)->value; \ + memcpy(&((z)->value),&((v)->value),sizeof(zvalue_value)); \ Z_TYPE_P(z) = Z_TYPE_P(v); \ Z_SET_REFCOUNT_P(z, 1); \ Z_UNSET_ISREF_P(z); @@ -722,7 +722,7 @@ } else { ALLOC_ZVAL(*variable_ptr_ptr); Z_SET_REFCOUNT_P(value, 1); - **variable_ptr_ptr = *value; + memcpy(*variable_ptr_ptr,value,sizeof(zval)); } } Z_UNSET_ISREF_PP(variable_ptr_ptr); Index: Zend/zend_compile.h =================================================================== --- Zend/zend_compile.h.orig 2009-07-10 03:47:36.000000000 +0000 +++ Zend/zend_compile.h 2009-07-12 01:37:37.230504746 +0000 @@ -324,6 +324,7 @@ zval *current_this; zval *current_object; struct _zend_op *call_opline; + void **top; }; #define EX(element) execute_data.element