php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #74527 Segfault generating phar.php
Submitted: 2017-05-02 03:30 UTC Modified: 2017-05-05 11:24 UTC
From: coypu at sdf dot org Assigned:
Status: Not a bug Package: Compile Failure
PHP Version: 7.1.4 OS: NetBSD
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: coypu at sdf dot org
New email:
PHP Version: OS:

 

 [2017-05-02 03:30 UTC] coypu at sdf dot org
Description:
------------
Hi,

NetBSD 7.0 i386 builds are consistently segfaulting generating phar.php
Example build log: http://nyftp.netbsd.org/pub/pkgsrc/packages/reports/2017Q1/NetBSD-7.0-i386/20170430.0103/php-7.1.3nb1/build.log

(Sorry for reporting a bug against 7.1.3, I didn't notice as I was experimenting, and this is in an extremely slow VM - I don't see relevant changes in 7.1.4)

We have some local modifications to the package, you can view them here:
https://github.com/NetBSD/pkgsrc/tree/trunk/lang/php71
(None of them touch deep PHP internals)

A backtrace of such a segfault is:

(gdb) core ./work/php-7.1.3/php.core                                            
[New process 1]                                                                 
Core was generated by `php'.                                                    
Program terminated with signal SIGSEGV, Segmentation fault.                     
#0  0x0857b17b in zval_get_type (pz=0x7ae11780)                                 
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend_types.h:332                  
332             return pz->u1.v.type;                                           
(gdb) bt
#0  0x0857b17b in zval_get_type (pz=0x7ae11780)
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend_types.h:332
#1  ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER ()
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend_vm_execute.h:39969
#2  0x084f5b20 in execute_ex (ex=0xbb214020)
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend_vm_execute.h:429
#3  0x084f6237 in zend_execute (op_array=0xbb26d080, return_value=0x0)
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend_vm_execute.h:474
#4  0x0847b116 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /pkgsrc/lang/php71/work/php-7.1.3/Zend/zend.c:1476
#5  0x083ec7e0 in php_execute_script (primary_file=0xbfbfdce0)
    at /pkgsrc/lang/php71/work/php-7.1.3/main/main.c:2537
#6  0x085c034c in do_cli (argc=14, argv=0xbfbfded8)
    at /pkgsrc/lang/php71/work/php-7.1.3/sapi/cli/php_cli.c:993
#7  0x085c1228 in main (argc=14, argv=0xbfbfded8)
    at /pkgsrc/lang/php71/work/php-7.1.3/sapi/cli/php_cli.c:1381

I personally attempted to build the package in qemu-system-i386, using GCC 4.8.5.

I've made the following change that made me able to build it:

--- configure.orig      2017-04-11 15:37:37.000000000 +0000
+++ configure
@@ -5737,10 +5737,7 @@ if test "$ZEND_GCC_GLOBAL_REGS" != "no";
 #else
 # define ZEND_GCC_VERSION 0
 #endif
-#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
-# define ZEND_VM_FP_GLOBAL_REG "%esi"
-# define ZEND_VM_IP_GLOBAL_REG "%edi"
-#elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
+#if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__x86_64__)
 # define ZEND_VM_FP_GLOBAL_REG "%r14"
 # define ZEND_VM_IP_GLOBAL_REG "%r15"
 #elif defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(__powerpc64__)

Disabling the use of a global register for i386 (I think).

I don't have a rationale for it, I just found it unbelievable that such a thing works, and disabling it did the trick.

This may be a GCC bug if you believe it should work.


Patches

similar-change-to-zend-m4 (last revision 2017-05-02 03:32 UTC by coypu at sdf dot org)

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-05-02 10:16 UTC] danack@php.net
-Status: Open +Status: Feedback
 [2017-05-02 10:17 UTC] danack@php.net
Please could you post what version of GCC you're using?

Also, please can you test against other versions of PHP? i.e. has this just recently stopped working, or has this never worked for NetBSD?

> Disabling the use of a global register for i386 (I think).
> I don't have a rationale for it, I just found it unbelievable
> that such a thing works, and disabling it did the trick.

It's been a while* since I've touched code that touches registers directly, but I'm pretty sure in this context, 'global register' just means that it doesn't get overwritten when calling a function, which means that it can be used for generating performant code.


* more than a decade, still not long enough.
 [2017-05-02 11:13 UTC] ab@php.net
To add were - if that's a VM, the issue might be exactly that. So yet to check list

- try newer GCC, at least 5.0.0
- try another VM with more resources
- try a real HW

A patch should rather implement a configure option to control the enablement.

Thanks.
 [2017-05-03 12:01 UTC] coypu at sdf dot org
this only occurs with that one GCC version.
other GCC versions I've tried (5.4.0, 6.3.0, 4.9.4) did not exhibit the problem.
so it's a very specific version that had an issue, feel free to close the bug :-) (I would, but I forgot the password already)
(and if you see a similar issue on i386, consider this bug)

I think it's worth considering dropping this global register use in i386 independent of the bug. It's possible it's a performance hit rather than improvement.
i386 has very few registers, it's likely GCC produces worse code when so constrained. I'm surprised it works!
 [2017-05-05 11:24 UTC] ab@php.net
-Status: Feedback +Status: Not a bug
 [2017-05-05 11:24 UTC] ab@php.net
Thanks for the further checks. Given there was already issues with GCC 4.9 before, as well on 32-bit and PHP 7, but in other areas, I'd say it's not a PHP bug in first place. Seems that a specific compiler version has issues.

A register storage specifier should be only applied to stack vars. Possibility to use it globally is obviously a non standard compiler specific feature. Till now there was no performance related reports in this regard. Should you see some issues, it'd be still worth to file a ticket with corresponding benchmarks and possibly a patch to disable global register vars by option.

Thanks.
 [2018-07-31 01:24 UTC] coypu at sdf dot org
GCC bug report against GCC 8.1
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86236
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 12:01:30 2024 UTC