dev-lang/php-5.3.2 fails to build on arm with -O2 optimization options in CFLAGS. Analyzing gdb backtrace and the generated code for 'zend_ptr_stack_clear_multiple' function makes it clear that the cause is a pointer aliasing issue. Searching php bugtracker shows that this bug has been reported already and it describes the problem precisely: http://bugs.php.net/bug.php?id=46311 Program terminated with signal 11, Segmentation fault. #0 zval_delref_p (zval_ptr=0xbedc8ebc) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend.h:385 385 return --pz->refcount__gc; (gdb) bt #0 zval_delref_p (zval_ptr=0xbedc8ebc) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend.h:385 #1 _zval_ptr_dtor (zval_ptr=0xbedc8ebc) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend_execute_API.c:433 #2 0x0022cd1c in zend_vm_stack_clear_multiple (execute_data=0x79a120) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend_execute.h:316 #3 zend_do_fcall_common_helper_SPEC (execute_data=0x79a120) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend_vm_execute.h:403 #4 0x00227428 in execute (op_array=0x7762c8) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend_vm_execute.h:104 #5 0x00205f44 in zend_execute_scripts (type=8, retval=<value optimized out>, file_count=3) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/Zend/zend.c:1194 #6 0x001bb934 in php_execute_script (primary_file=<value optimized out>) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/main/main.c:2260 #7 0x002875a4 in main (argc=<value optimized out>, argv=<value optimized out>) at /var/tmp/portage/dev-lang/php-5.3.2/work/php-5.3.2/sapi/cli/php_cli.c:1192 static inline void zend_vm_stack_clear_multiple(TSRMLS_D) { void **p = EG(argument_stack)->top - 1; int delete_count = (int)(zend_uintptr_t) *p; while (--delete_count>=0) { zval *q = *(zval **)(--p); *p = NULL; zval_ptr_dtor(&q); } zend_vm_stack_free_int(p TSRMLS_CC); } Dump of assembler code for function zend_vm_stack_clear_multiple: 0x001fb900 <zend_vm_stack_clear_multiple+0>: push {r4, r5, r6, r7, r8, r9, r10, lr} 0x001fb904 <zend_vm_stack_clear_multiple+4>: ldr r9, [pc, #112] ; 0x1fb97c <zend_vm_stack_clear_multiple+124> 0x001fb908 <zend_vm_stack_clear_multiple+8>: sub sp, sp, #8 0x001fb90c <zend_vm_stack_clear_multiple+12>: ldr r3, [r9, #444] ; 0x1bc 0x001fb910 <zend_vm_stack_clear_multiple+16>: ldr r4, [r3] 0x001fb914 <zend_vm_stack_clear_multiple+20>: ldr r10, [r4, #-4] 0x001fb918 <zend_vm_stack_clear_multiple+24>: sub r8, r4, #4 0x001fb91c <zend_vm_stack_clear_multiple+28>: subs r5, r10, #1 0x001fb920 <zend_vm_stack_clear_multiple+32>: bmi 0x1fb950 <zend_vm_stack_clear_multiple+80> 0x001fb924 <zend_vm_stack_clear_multiple+36>: add r7, sp, #4 ^ here r7 register points to 'q' variable 0x001fb928 <zend_vm_stack_clear_multiple+40>: mov r6, #0 0x001fb92c <zend_vm_stack_clear_multiple+44>: str r6, [r4, #-8] 0x001fb930 <zend_vm_stack_clear_multiple+48>: mov r0, r7 0x001fb934 <zend_vm_stack_clear_multiple+52>: str r6, [sp, #4] ^ here the content of 'q' variable is cleared to zero 0x001fb938 <zend_vm_stack_clear_multiple+56>: bl 0x1fb874 <_zval_ptr_dtor> ^ one of the first things that '_zval_ptr_dtor' function does is dereferencing zero pointer 0x001fb93c <zend_vm_stack_clear_multiple+60>: subs r5, r5, #1 0x001fb940 <zend_vm_stack_clear_multiple+64>: sub r4, r4, #4 0x001fb944 <zend_vm_stack_clear_multiple+68>: bpl 0x1fb92c <zend_vm_stack_clear_multiple+44> 0x001fb948 <zend_vm_stack_clear_multiple+72>: ldr r3, [r9, #444] ; 0x1bc 0x001fb94c <zend_vm_stack_clear_multiple+76>: sub r8, r8, r10, lsl #2 0x001fb950 <zend_vm_stack_clear_multiple+80>: add r2, r3, #16 0x001fb954 <zend_vm_stack_clear_multiple+84>: cmp r8, r2 0x001fb958 <zend_vm_stack_clear_multiple+88>: strne r8, [r3] 0x001fb95c <zend_vm_stack_clear_multiple+92>: beq 0x1fb968 <zend_vm_stack_clear_multiple+104> 0x001fb960 <zend_vm_stack_clear_multiple+96>: add sp, sp, #8 0x001fb964 <zend_vm_stack_clear_multiple+100>: pop {r4, r5, r6, r7, r8, r9, r10, pc} 0x001fb968 <zend_vm_stack_clear_multiple+104>: mov r0, r3 0x001fb96c <zend_vm_stack_clear_multiple+108>: ldr r3, [r3, #8] 0x001fb970 <zend_vm_stack_clear_multiple+112>: str r3, [r9, #444] ; 0x1bc 0x001fb974 <zend_vm_stack_clear_multiple+116>: bl 0x1ed154 <_efree> 0x001fb978 <zend_vm_stack_clear_multiple+120>: b 0x1fb960 <zend_vm_stack_clear_multiple+96> 0x001fb97c <zend_vm_stack_clear_multiple+124>: strdeq r6, [r7], #-240 ; 0xffffff10 Reproducible: Always Steps to Reproduce:
Actually bug 295682 *might* be caused by the same issue, but I'm not completely sure (SIGBUS instead of segfault and somewhat similar, but not precisely the same backtrace). Hence reported this issue separately.
Does using the patch described upstream fix the issue for you? It wasn't clear from your report. Otherwise, thanks for digging into this.
(In reply to comment #2) > Does using the patch described upstream fix the issue for you? It wasn't clear > from your report. Yes, it does fix the issue. Though it might have been better to have that problematic line changed to "zval *q = (zval *) *(--p);" (still have the cast, but do it after pointer dereference, not before). I'm not familiar with php, but this particular header file uses BEGIN_EXTERN_C macro, which implies that it might be used from C++ code sometimes. And the patch from php bugtracker fails to compile as C++ without adding the explicit cast.
I've included your fix into the php-5.3.3 patch tarball. Please reopen this bug if the issue is not fixed.