Bug 1730544 - Abort when reloading with a php module reloaded twice
Summary: Abort when reloading with a php module reloaded twice
Alias: None
Product: Red Hat Software Collections
Classification: Red Hat
Component: php
Version: rh-php71
Hardware: Unspecified
OS: Unspecified
Target Milestone: alpha
: 3.4
Assignee: Remi Collet
QA Contact: RHEL Stacks Subsystem QE
Depends On:
TreeView+ depends on / blocked
Reported: 2019-07-17 05:59 UTC by Hisanobu Okuda
Modified: 2021-01-14 09:19 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Last Closed: 2019-11-01 15:52:01 UTC
Target Upstream Version:

Attachments (Terms of Use)

Description Hisanobu Okuda 2019-07-17 05:59:40 UTC
Description of problem:
If a php module is loaded twice, i.e., the "extension" line is duplicated as follows:

# cat /etc/opt/rh/rh-php71/php.d/20-curl.ini
; Enable curl extension module

httpd/php is aborted when reloaded:

# systemctl reload httpd24-httpd

Version-Release number of selected component (if applicable):


How reproducible:

Steps to Reproduce:
1. modify /etc/opt/rh/rh-php71/php.d/20-curl.ini:

# cat /etc/opt/rh/rh-php71/php.d/20-curl.ini
; Enable curl extension module

2. systemctl start httpd24-httpd
3. systemctl reload httpd24-httpd
4. httpd aborted:

*** Error in `/opt/rh/httpd24/root/usr/sbin/httpd': free(): invalid pointer: 0x0000558e06d423b0 ***                                                            
======= Backtrace: =========                                                                                                                                   

Actual results:

Expected results:

Additional info:

Comment 2 Hisanobu Okuda 2019-07-17 06:12:32 UTC
When `systemctl reload httpd24-httpd`, core_globals_dtor is invoked at shutting down php engine, and `core_globals.last_error_message` is freed in core_globald_dtor:1958 but still keeps its pointer value.

(gdb) break main.c:1039
Breakpoint 1 at 0x7f8854a85225: file /usr/src/debug/php-7.1.8/main/main.c, line 1039.
(gdb) break main.c:1958
Breakpoint 2 at 0x7f8854baa1fd: file /usr/src/debug/php-7.1.8/main/main.c, line 1958.
(gdb) c
(gdb) break main.c:1039
Breakpoint 1 at 0x7f8854a85225: file /usr/src/debug/php-7.1.8/main/main.c, line 1039.
(gdb) break main.c:1958
Breakpoint 2 at 0x7f8854baa1fd: file /usr/src/debug/php-7.1.8/main/main.c, line 1958.
(gdb) c

Program received signal SIGUSR1, User defined signal 1.
0x00007fe27bf89f53 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:81
(gdb) c

Breakpoint 1, core_globals_dtor (core_globals=0x7fe26ed9fb00 <core_globals>) at /usr/src/debug/php-7.1.8/main/main.c:1958
1958                    free(core_globals->last_error_message);
(gdb) print core_globals.last_error_message 
$1 = 0x55badd590de0 "Module 'sqlsrv' already loaded"
(gdb) l
1953    /* {{{ core_globals_dtor
1954     */
1955    static void core_globals_dtor(php_core_globals *core_globals)
1956    {
1957            if (core_globals->last_error_message) {
1958                    free(core_globals->last_error_message);
1959            }
1960            if (core_globals->last_error_file) {
1961                    free(core_globals->last_error_file);

Then, the process is restared. At this time, `core_globals.last_error_message` keeps non-null value and is freed again in php_error_cb#1041:

(gdb) c

Breakpoint 2, php_error_cb (type=32, error_filename=0x7fe26ea59802 "Unknown", error_lineno=0, format=<optimized out>, args=<optimized out>)
    at /usr/src/debug/php-7.1.8/main/main.c:1040
1040                            PG(last_error_message) = NULL;
(gdb) print core_globals.last_error_message 
$2 = 0x55badd590de0 ""
(gdb) s
1041                            free(s);
(gdb) l
1036            /* store the error if it has changed */
1037            if (display) {
1038                    if (PG(last_error_message)) {
1039                            char *s = PG(last_error_message);
1040                            PG(last_error_message) = NULL;
1041                            free(s);
1042                    }
1043                    if (PG(last_error_file)) {
1044                            char *s = PG(last_error_file);
1045                            PG(last_error_file) = NULL;

Comment 3 Hisanobu Okuda 2019-07-17 06:16:04 UTC
core_globals->last_error_message should be clear with NULL:

[hokuda@dhcp-193-78 php-7.1.8]$ diff -u main/main.c.org main/main.c
--- main/main.c.org     2017-08-02 02:36:55.000000000 +0900
+++ main/main.c 2019-07-17 15:14:43.463973027 +0900
@@ -1956,6 +1956,7 @@
        if (core_globals->last_error_message) {
+               core_globals->last_error_message = NULL;
        if (core_globals->last_error_file) {
[hokuda@dhcp-193-78 php-7.1.8]$

Comment 4 Remi Collet 2019-07-17 07:47:22 UTC
About duplicate module, this is detected and reported in httpd error_log

     PHP Warning:  Module 'curl' already loaded in Unknown on line 0

So easy to fix

BTW, I'm unable to reproduce this segfault, with all rh-* packages installed.
What is the installed extensions ?

$ rpm -qa rh-php71\* | sort
$ scl enable rh-php71 "php -m"

Comment 5 Remi Collet 2019-07-17 08:33:10 UTC
I suspect some extension to badly log some message during its shutdown script.

PR open for upstream discussion

Comment 8 Remi Collet 2019-07-19 05:03:49 UTC
Fixed upstream by https://github.com/php/php-src/commit/e5beb4e828b2b9b3d79642bd407813c824950310 (in 7.1.9)

Comment 12 Joe Orton 2019-11-01 15:52:01 UTC
In accordance with the Red Hat Software Collections Product Life Cycle, the support period for this collection has ended.

New bug fix, enhancement, and security errata updates, as well as technical support services will no longer be made available for this collection.

Customers are encouraged to upgrade to a later release.

Please contact Red Hat Support if you have further questions, or refer to the support lifecycle page for more information. https://access.redhat.com/support/policy/updates/rhscl/

Note You need to log in before you can comment on or make changes to this bug.