You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by yl...@apache.org on 2017/09/28 11:08:09 UTC

svn commit: r1809973 - in /httpd/httpd/trunk: os/unix/unixd.c server/main.c server/mpm/event/event.c server/mpm/motorz/motorz.c server/mpm/prefork/prefork.c server/mpm/worker/worker.c server/mpm_unix.c

Author: ylavic
Date: Thu Sep 28 11:08:09 2017
New Revision: 1809973

URL: http://svn.apache.org/viewvc?rev=1809973&view=rev
Log:
core, MPMs unix: follow up to r1809881.

Deregister all hooks first (in pre_cleanup), by doing it last we could still
have had them run when DSOs were unloaded.

Likewise, avoid double faults when handling fatal signals by restoring the
default handler before pconf is cleared (we can't ap_log_error there).

Finally, we need to ignore sig_term/restart (do nothing) when the main
process is exiting (i.e. ap_pglobal is destroyed), since retained_data are
freed.

Aimed to fix all faults in PR 61558.


Modified:
    httpd/httpd/trunk/os/unix/unixd.c
    httpd/httpd/trunk/server/main.c
    httpd/httpd/trunk/server/mpm/event/event.c
    httpd/httpd/trunk/server/mpm/motorz/motorz.c
    httpd/httpd/trunk/server/mpm/prefork/prefork.c
    httpd/httpd/trunk/server/mpm/worker/worker.c
    httpd/httpd/trunk/server/mpm_unix.c

Modified: httpd/httpd/trunk/os/unix/unixd.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/os/unix/unixd.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/os/unix/unixd.c (original)
+++ httpd/httpd/trunk/os/unix/unixd.c Thu Sep 28 11:08:09 2017
@@ -437,11 +437,19 @@ AP_DECLARE(apr_status_t) ap_unixd_accept
 /* Unixes MPMs' */
 
 static ap_unixd_mpm_retained_data *retained_data = NULL;
+static apr_status_t retained_data_cleanup(void *unused)
+{
+    (void)unused;
+    retained_data = NULL;
+    return APR_SUCCESS;
+}
+
 AP_DECLARE(ap_unixd_mpm_retained_data *) ap_unixd_mpm_get_retained_data()
 {
     if (!retained_data) {
         retained_data = ap_retained_data_create("ap_unixd_mpm_retained_data",
                                                 sizeof(*retained_data));
+        apr_pool_pre_cleanup_register(ap_pglobal, NULL, retained_data_cleanup);
         retained_data->mpm_state = AP_MPMQ_STARTING;
     }
     return retained_data;
@@ -449,6 +457,10 @@ AP_DECLARE(ap_unixd_mpm_retained_data *)
 
 static void sig_term(int sig)
 {
+    if (!retained_data) {
+        /* Main process (ap_pglobal) is dying */
+        return;
+    }
     retained_data->mpm_state = AP_MPMQ_STOPPING;
     if (retained_data->shutdown_pending
             && (retained_data->is_ungraceful
@@ -465,6 +477,10 @@ static void sig_term(int sig)
 
 static void sig_restart(int sig)
 {
+    if (!retained_data) {
+        /* Main process (ap_pglobal) is dying */
+        return;
+    }
     retained_data->mpm_state = AP_MPMQ_STOPPING;
     if (retained_data->restart_pending
             && (retained_data->is_ungraceful
@@ -494,6 +510,10 @@ AP_DECLARE(void) ap_unixd_mpm_set_signal
     struct sigaction sa;
 #endif
 
+    if (!one_process) {
+        ap_fatal_signal_setup(ap_server_conf, pconf);
+    }
+
     /* Signals' handlers depend on retained data */
     (void)ap_unixd_mpm_get_retained_data();
 

Modified: httpd/httpd/trunk/server/main.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/main.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/main.c (original)
+++ httpd/httpd/trunk/server/main.c Thu Sep 28 11:08:09 2017
@@ -295,13 +295,30 @@ static int abort_on_oom(int retcode)
     return retcode; /* unreachable, hopefully. */
 }
 
+/* Deregister all hooks when clearing pconf (pre_cleanup).
+ * TODO: have a hook to deregister and run them from here?
+ *       ap_clear_auth_internal() is already a candidate.
+ */
 static apr_status_t deregister_all_hooks(void *unused)
 {
     (void)unused;
+    ap_clear_auth_internal();
     apr_hook_deregister_all();
     return APR_SUCCESS;
 }
 
+static void reset_process_pconf(process_rec *process)
+{
+    if (process->pconf) {
+        apr_pool_clear(process->pconf);
+    }
+    else {
+        apr_pool_create(&process->pconf, process->pool);
+        apr_pool_tag(process->pconf, "pconf");
+    }
+    apr_pool_pre_cleanup_register(process->pconf, NULL, deregister_all_hooks);
+}
+
 static process_rec *init_process(int *argc, const char * const * *argv)
 {
     process_rec *process;
@@ -346,8 +363,9 @@ static process_rec *init_process(int *ar
     process = apr_palloc(cntx, sizeof(process_rec));
     process->pool = cntx;
 
-    apr_pool_create(&process->pconf, process->pool);
-    apr_pool_tag(process->pconf, "pconf");
+    process->pconf = NULL;
+    reset_process_pconf(process);
+
     process->argc = *argc;
     process->argv = *argv;
     process->short_name = apr_filepath_name_get((*argv)[0]);
@@ -504,10 +522,6 @@ int main(int argc, const char * const ar
     }
 #endif
 
-    /* Deregister all hooks (lastly) when done with pconf */
-    apr_pool_cleanup_register(pconf, NULL, deregister_all_hooks,
-                              apr_pool_cleanup_null);
-
     apr_pool_create(&pcommands, ap_pglobal);
     apr_pool_tag(pcommands, "pcommands");
     ap_server_pre_read_config  = apr_array_make(pcommands, 1,
@@ -754,12 +768,7 @@ int main(int argc, const char * const ar
 
     do {
         ap_main_state = AP_SQ_MS_DESTROY_CONFIG;
-        apr_pool_clear(pconf);
-        ap_clear_auth_internal();
-
-        /* Deregister all hooks (lastly) when done with pconf */
-        apr_pool_cleanup_register(pconf, NULL, deregister_all_hooks,
-                                  apr_pool_cleanup_null);
+        reset_process_pconf(process);
 
         ap_main_state = AP_SQ_MS_CREATE_CONFIG;
         ap_config_generation++;

Modified: httpd/httpd/trunk/server/mpm/event/event.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/event/event.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/event/event.c (original)
+++ httpd/httpd/trunk/server/mpm/event/event.c Thu Sep 28 11:08:09 2017
@@ -3149,9 +3149,6 @@ static int event_run(apr_pool_t * _pconf
         ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
     }
 
-    if (!one_process) {
-        ap_fatal_signal_setup(ap_server_conf, pconf);
-    }
     ap_unixd_mpm_set_signals(pconf, one_process);
 
     /* Don't thrash since num_buckets depends on the

Modified: httpd/httpd/trunk/server/mpm/motorz/motorz.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/motorz/motorz.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/motorz/motorz.c (original)
+++ httpd/httpd/trunk/server/mpm/motorz/motorz.c Thu Sep 28 11:08:09 2017
@@ -1104,9 +1104,6 @@ static int motorz_run(apr_pool_t *_pconf
         ap_scoreboard_image->global->running_generation = mz->mpm->my_generation;
     }
 
-    if (!one_process) {
-        ap_fatal_signal_setup(ap_server_conf, pconf);
-    }
     ap_unixd_mpm_set_signals(pconf, one_process);
 
     if (one_process) {

Modified: httpd/httpd/trunk/server/mpm/prefork/prefork.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/prefork/prefork.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/prefork/prefork.c (original)
+++ httpd/httpd/trunk/server/mpm/prefork/prefork.c Thu Sep 28 11:08:09 2017
@@ -864,9 +864,6 @@ static int prefork_run(apr_pool_t *_pcon
         ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
     }
 
-    if (!one_process) {
-        ap_fatal_signal_setup(ap_server_conf, pconf);
-    }
     ap_unixd_mpm_set_signals(pconf, one_process);
 
     if (one_process) {

Modified: httpd/httpd/trunk/server/mpm/worker/worker.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm/worker/worker.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm/worker/worker.c (original)
+++ httpd/httpd/trunk/server/mpm/worker/worker.c Thu Sep 28 11:08:09 2017
@@ -1672,9 +1672,6 @@ static int worker_run(apr_pool_t *_pconf
         ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
     }
 
-    if (!one_process) {
-        ap_fatal_signal_setup(ap_server_conf, pconf);
-    }
     ap_unixd_mpm_set_signals(pconf, one_process);
 
     /* Don't thrash since num_buckets depends on the

Modified: httpd/httpd/trunk/server/mpm_unix.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/mpm_unix.c?rev=1809973&r1=1809972&r2=1809973&view=diff
==============================================================================
--- httpd/httpd/trunk/server/mpm_unix.c (original)
+++ httpd/httpd/trunk/server/mpm_unix.c Thu Sep 28 11:08:09 2017
@@ -1009,6 +1009,33 @@ AP_DECLARE(apr_status_t) ap_fatal_signal
     return APR_SUCCESS;
 }
 
+/* We can't call sig_coredump (ap_log_error) once pconf is destroyed, so
+ * avoid double faults by restoring each default signal handler on cleanup.
+ */
+static apr_status_t fatal_signal_cleanup(void *unused)
+{
+    (void)unused;
+
+    apr_signal(SIGSEGV, SIG_DFL);
+#ifdef SIGBUS
+    apr_signal(SIGBUS, SIG_DFL);
+#endif /* SIGBUS */
+#ifdef SIGABORT
+    apr_signal(SIGABORT, SIG_DFL);
+#endif /* SIGABORT */
+#ifdef SIGABRT
+    apr_signal(SIGABRT, SIG_DFL);
+#endif /* SIGABRT */
+#ifdef SIGILL
+    apr_signal(SIGILL, SIG_DFL);
+#endif /* SIGILL */
+#ifdef SIGFPE
+    apr_signal(SIGFPE, SIG_DFL);
+#endif /* SIGFPE */
+
+    return APR_SUCCESS;
+}
+
 AP_DECLARE(apr_status_t) ap_fatal_signal_setup(server_rec *s,
                                                apr_pool_t *in_pconf)
 {
@@ -1071,6 +1098,8 @@ AP_DECLARE(apr_status_t) ap_fatal_signal
 
     pconf = in_pconf;
     parent_pid = my_pid = getpid();
+    apr_pool_cleanup_register(pconf, NULL, fatal_signal_cleanup,
+                              fatal_signal_cleanup);
 
     return APR_SUCCESS;
 }