unbit / uwsgi

uWSGI application server container
http://projects.unbit.it/uwsgi
Other
3.45k stars 691 forks source link

php_plugin - segfault after disable opcache #2096

Closed pawelrosada closed 4 years ago

pawelrosada commented 4 years ago

Hello,

I received problems with php74 (php-7.4.0RC6), after switching off opcache I getting crash of PHP (works only first request). I test it on fpm and apache2handler - it works fine. PHP developers make some changes on SAPI - maybe this is reason why uwsgi stop working.

Backtrace:

#0  0x00007f70b38a78eb in lex_scan (zendlval=zendlval@entry=0x7ffdd017cc90, elem=0x7ffdd017cd30) at Zend/zend_language_scanner.c:1306
#1  0x00007f70b38c137a in zendlex (elem=elem@entry=0x7ffdd017cd30) at php-src-php-7.4.0RC6/Zend/zend_compile.c:1613
#2  0x00007f70b38a2e84 in zendparse () at php-src-php-7.4.0RC6/Zend/zend_language_parser.c:4055
#3  0x00007f70b38a56ea in zend_compile (type=type@entry=2) at Zend/zend_language_scanner.l:594
#4  0x00007f70b38a6c56 in compile_file (file_handle=0x7ffdd017fd10, type=8) at Zend/zend_language_scanner.l:647
#5  0x00007f70b375898d in phar_compile_file (file_handle=0x7ffdd017fd10, type=8) at php-src-php-7.4.0RC6/ext/phar/phar.c:3299
#6  0x00007f70b38e8de2 in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at php-src-php-7.4.0RC6/Zend/zend.c:1657
#7  0x00007f70b3879c00 in php_execute_script (primary_file=0x7ffdd017fd10) at php-src-php-7.4.0RC6/main/main.c:2619
#8  0x00007f70b53431a3 in uwsgi_php_request () at /usr/lib/uwsgi/php74_plugin.so
#9  0x000000000041af85 in wsgi_req_recv ()
#10 0x0000000000468e59 in simple_loop_run ()
#11 0x0000000000468c6e in simple_loop ()
#12 0x000000000046d818 in uwsgi_ignition ()
#13 0x0000000000472632 in uwsgi_worker_run ()
#14 0x0000000000472b30 in uwsgi_init_worker_mount_apps ()
#15 0x000000000041a58e in  ()

Our configuration:

[uwsgi]
plugins = cheaper_busyness

http-keepalive = true

no-orphans = true
auto-procname = true
vacuum = true
thunder-lock = true
master-as-root = true
close-on-exec = true
close-on-exec2 = true
master = true
memory-report

fastrouter = =0
fastrouter-timeout = 120
fastrouter-events = 256
fastrouter-buffer-size = 8190
fastrouter-cheap = true
fastrouter-defer-connect-timeout = 3
fastrouter-peer-reply-timeout = 60
subscriptions-use-credentials = true

emperor-collect-attr = fork-server
emperor-fork-server-attr = fork-server
buffer-size = 8190
max-fd = 8192

emperor-wait-for-command = ture`

fork server configuration:

plugin = php

early-php = true
lazy-apps = false
cache = 2024
sharedarea = 2024

httpd version: 2.4.39

Any idea what is wrong with it?

nougad commented 4 years ago

I can confirm segfaults with php 7.4 and uwsgi 2.0.18

The segfault happens independent of the opcache setting (of course the stacktrace is different).

related issue in archlinux bugtracker: https://bugs.archlinux.org/task/64696

related issue in php bugracker: https://bugs.php.net/bug.php?id=78828

nougad commented 4 years ago

The problem is the missing php_fopen_primary_script before php_execute_script.

(gdb) bt
#0  0x00007ffff5518660 in __memchr_avx2 () from /usr/lib/libc.so.6
#1  0x00007ffff441dd24 in lex_scan (zendlval=zendlval@entry=0x7fffffff9640, elem=0x7fffffff96c8) at ./packages/php/trunk/src/php-7.4.0/Zend/zend_language_scanner.c:1319
#2  0x00007ffff4432b0b in zendlex (elem=elem@entry=0x7fffffff96c8) at ./packages/php/trunk/src/php-7.4.0/Zend/zend_compile.c:1613
#3  0x00007ffff44161bb in zendparse () at ./packages/php/trunk/src/php-7.4.0/Zend/zend_language_parser.c:4055
#4  0x00007ffff4418b5c in zend_compile (type=type@entry=2) at ./packages/php/trunk/src/php-7.4.0/Zend/zend_language_scanner.c:595
#5  0x00007ffff441a2f2 in compile_file (file_handle=0x7fffffffc6e0, type=8) at ./packages/php/trunk/src/php-7.4.0/Zend/zend_language_scanner.c:648
#6  0x00007ffff42f6bbc in phar_compile_file (file_handle=0x7fffffffc6e0, type=8) at ./packages/php/trunk/src/php-7.4.0/ext/phar/phar.c:3299
#7  0x00007ffff4452e2c in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0, file_count=file_count@entry=3) at ./packages/php/trunk/src/php-7.4.0/Zend/zend.c:1657
#8  0x00007ffff43f3001 in php_execute_script (primary_file=primary_file@entry=0x7fffffffc6e0) at ./packages/php/trunk/src/php-7.4.0/main/main.c:2619
#9  0x00007ffff518f613 in uwsgi_php_request (wsgi_req=<optimized out>) at plugins/php/php_plugin.c:1139
#10 0x0000555555594b04 in wsgi_req_recv (queue=queue@entry=7, wsgi_req=wsgi_req@entry=0x7ffff3e00078) at core/utils.c:1469
#11 0x00005555555e53e8 in simple_loop_run (arg1=0x0) at core/loop.c:146
#12 0x00005555555e51b0 in simple_loop () at core/loop.c:62
#13 0x00005555555ea0c2 in uwsgi_ignition () at core/uwsgi.c:3739
#14 0x00005555555eebfe in uwsgi_worker_run () at core/uwsgi.c:3667
#15 0x00005555555ef182 in uwsgi_run () at core/uwsgi.c:3577
#16 0x00005555555940ae in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at core/uwsgi.c:2115

when I compare

https://github.com/unbit/uwsgi/blob/master/plugins/php/php_plugin.c#L1133-L1135

with php-fpm:

https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_main.c#L1917-L1936

Then the fpm code opens the file_handle first with php_fopen_primary_script. If I add the same to the php_plugin it works without any stack trace:

diff --git a/plugins/php/php_plugin.c b/plugins/php/php_plugin.c
index 72c39022..74bc31c5 100644
--- a/plugins/php/php_plugin.c
+++ b/plugins/php/php_plugin.c
@@ -1125,6 +1125,11 @@ secure3:
                 return -1;
         }

+
+        if (php_fopen_primary_script(&file_handle) == FAILURE) {
+                return -1;
+        }
+
        struct uwsgi_string_list *usl=NULL;

        uwsgi_foreach(usl, uphp.exec_before) {

I don't know enough about php or uwsgi to tell why it happens but it fixes the problem.

awelzel commented 4 years ago

Hey @pawelrosada and @nougad ,

I believe the actual root cause (based on the archlinux/php bugtracker stacktraces) is that the zend_file_handle isn't properly initialized.

Mind trying the branch/patch in #2105 ?

Thanks, Arne

awelzel commented 4 years ago

@nougad , your proposal seems sensible, too: it appears php_fopen_primary_script calls zend_stream_init_fp which will also properly initialize the zend_file_handle. It does a lot of things in addition to that which I'm not clear are needed, so If just adding the memset() works, that might be a good minimal fix.

xrmx commented 4 years ago

Patch from @awelzel reached uwsgi-2.0, you can test that branch to confirm it fixes the issue for you.