On Wed, Sep 25, 2019 at 3:07 PM Stefan Eissing
<stefan.eiss...@greenbytes.de> wrote:
>
> Hmm, far less likely, but still:

Likewise, I think the MPMs themselves shouldn't use pchild for their
internal allocations possibly still in use at exit().
So v2 (attached) may be the thing..
Index: include/http_main.h
===================================================================
--- include/http_main.h	(revision 1866998)
+++ include/http_main.h	(working copy)
@@ -52,6 +52,8 @@ AP_DECLARE_DATA extern const char *ap_runtime_dir;
 AP_DECLARE_DATA extern server_rec *ap_server_conf;
 /** global pool, for access prior to creation of server_rec */
 AP_DECLARE_DATA extern apr_pool_t *ap_pglobal;
+/** configuration pool, cleared for each reload */
+AP_DECLARE_DATA extern apr_pool_t *ap_pconf;
 /** state of the server (startup, exiting, ...) */
 AP_DECLARE_DATA extern int ap_main_state;
 /** run mode (normal, config test, config dump, ...) */
Index: server/config.c
===================================================================
--- server/config.c	(revision 1866998)
+++ server/config.c	(working copy)
@@ -62,6 +62,7 @@ AP_DECLARE_DATA const char *ap_server_root = NULL;
 AP_DECLARE_DATA const char *ap_runtime_dir = NULL;
 AP_DECLARE_DATA server_rec *ap_server_conf = NULL;
 AP_DECLARE_DATA apr_pool_t *ap_pglobal = NULL;
+AP_DECLARE_DATA apr_pool_t *ap_pconf = NULL;
 
 AP_DECLARE_DATA apr_array_header_t *ap_server_pre_read_config = NULL;
 AP_DECLARE_DATA apr_array_header_t *ap_server_post_read_config = NULL;
Index: server/main.c
===================================================================
--- server/main.c	(revision 1866998)
+++ server/main.c	(working copy)
@@ -513,7 +513,7 @@ static void usage(process_rec *process)
 
     process = init_process(&argc, &argv);
     ap_pglobal = process->pool;
-    pconf = process->pconf;
+    ap_pconf = pconf = process->pconf;
     ap_server_argv0 = process->short_name;
     ap_init_rng(ap_pglobal);
 
Index: modules/core/mod_watchdog.c
===================================================================
--- modules/core/mod_watchdog.c	(revision 1866998)
+++ modules/core/mod_watchdog.c	(working copy)
@@ -567,8 +567,8 @@ static void wd_child_init_hook(apr_pool_t *p, serv
                      "Watchdog: nothing configured?");
         return;
     }
-    if ((wl = ap_list_provider_names(p, AP_WATCHDOG_PGROUP,
-                                        AP_WATCHDOG_CVERSION))) {
+    if ((wl = ap_list_provider_names(wd_server_conf->pool, AP_WATCHDOG_PGROUP,
+                                     AP_WATCHDOG_CVERSION))) {
         const ap_list_provider_names_t *wn;
         int i;
         wn = (ap_list_provider_names_t *)wl->elts;
Index: modules/ssl/ssl_engine_init.c
===================================================================
--- modules/ssl/ssl_engine_init.c	(revision 1866998)
+++ modules/ssl/ssl_engine_init.c	(working copy)
@@ -2159,14 +2159,15 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
 {
     SSLModConfigRec *mc = myModConfig(s);
     mc->pid = getpid(); /* only call getpid() once per-process */
+    (void)p;
 
     /* XXX: there should be an ap_srand() function */
     srand((unsigned int)time(NULL));
 
     /* open the mutex lockfile */
-    ssl_mutex_reinit(s, p);
+    ssl_mutex_reinit(s, ap_pconf);
 #ifdef HAVE_OCSP_STAPLING
-    ssl_stapling_mutex_reinit(s, p);
+    ssl_stapling_mutex_reinit(s, ap_pconf);
 #endif
 }
 
Index: server/mpm/event/event.c
===================================================================
--- server/mpm/event/event.c	(revision 1866998)
+++ server/mpm/event/event.c	(working copy)
@@ -2760,10 +2760,10 @@ static void child_main(int child_num_arg, int chil
     }
 
     /*stuff to do before we switch id's, so we have permissions. */
-    ap_reopen_scoreboard(pchild, NULL, 0);
+    ap_reopen_scoreboard(pconf, NULL, 0);
 
     /* done with init critical section */
-    if (ap_run_drop_privileges(pchild, ap_server_conf)) {
+    if (ap_run_drop_privileges(pconf, ap_server_conf)) {
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
@@ -2799,9 +2799,9 @@ static void child_main(int child_num_arg, int chil
      * and we want a 0 entry to indicate a thread which was not created
      */
     threads = ap_calloc(threads_per_child, sizeof(apr_thread_t *));
-    ts = apr_palloc(pchild, sizeof(*ts));
+    ts = apr_palloc(pconf, sizeof(*ts));
 
-    apr_threadattr_create(&thread_attr, pchild);
+    apr_threadattr_create(&thread_attr, pconf);
     /* 0 means PTHREAD_CREATE_JOINABLE */
     apr_threadattr_detach_set(thread_attr, 0);
 
@@ -2821,7 +2821,7 @@ static void child_main(int child_num_arg, int chil
     ts->threadattr = thread_attr;
 
     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
-                           ts, pchild);
+                           ts, pconf);
     if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00480)
                      "apr_thread_create: unable to create worker thread");
Index: server/mpm/motorz/motorz.c
===================================================================
--- server/mpm/motorz/motorz.c	(revision 1866998)
+++ server/mpm/motorz/motorz.c	(working copy)
@@ -812,7 +812,7 @@ static void child_main(motorz_core_t *mz, int chil
 
     ap_run_child_init(pchild, ap_server_conf);
 
-    ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
+    ap_create_sb_handle(&sbh, pconf, my_child_num, 0);
 
     ap_update_child_status(sbh, SERVER_READY, NULL);
 
Index: server/mpm/prefork/prefork.c
===================================================================
--- server/mpm/prefork/prefork.c	(revision 1866998)
+++ server/mpm/prefork/prefork.c	(working copy)
@@ -414,7 +414,7 @@ static void child_main(int child_num_arg, int chil
 
 #if APR_HAS_THREADS
     osthd = apr_os_thread_current();
-    apr_os_thread_put(&thd, &osthd, pchild);
+    apr_os_thread_put(&thd, &osthd, pconf);
 #endif
 
     apr_pool_create(&ptrans, pchild);
@@ -429,10 +429,10 @@ static void child_main(int child_num_arg, int chil
     }
 
     /* needs to be done before we switch UIDs so we have permissions */
-    ap_reopen_scoreboard(pchild, NULL, 0);
+    ap_reopen_scoreboard(pconf, NULL, 0);
     status = SAFE_ACCEPT(apr_proc_mutex_child_init(&my_bucket->mutex,
                                     apr_proc_mutex_lockfile(my_bucket->mutex),
-                                    pchild));
+                                    pconf));
     if (status != APR_SUCCESS) {
         lockfile = apr_proc_mutex_lockfile(my_bucket->mutex);
         ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00155)
@@ -443,18 +443,18 @@ static void child_main(int child_num_arg, int chil
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
-    if (ap_run_drop_privileges(pchild, ap_server_conf)) {
+    if (ap_run_drop_privileges(pconf, ap_server_conf)) {
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
     ap_run_child_init(pchild, ap_server_conf);
 
-    ap_create_sb_handle(&sbh, pchild, my_child_num, 0);
+    ap_create_sb_handle(&sbh, pconf, my_child_num, 0);
 
     (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL);
 
     /* Set up the pollfd array */
-    status = apr_pollset_create(&pollset, num_listensocks, pchild,
+    status = apr_pollset_create(&pollset, num_listensocks, pconf,
                                 APR_POLLSET_NOCOPY);
     if (status != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00156)
@@ -463,7 +463,7 @@ static void child_main(int child_num_arg, int chil
     }
 
     for (lr = my_bucket->listeners, i = num_listensocks; i--; lr = lr->next) {
-        apr_pollfd_t *pfd = apr_pcalloc(pchild, sizeof *pfd);
+        apr_pollfd_t *pfd = apr_pcalloc(pconf, sizeof *pfd);
 
         pfd->desc_type = APR_POLL_SOCKET;
         pfd->desc.s = lr->sd;
@@ -489,7 +489,7 @@ static void child_main(int child_num_arg, int chil
 
     retained->mpm->mpm_state = AP_MPMQ_RUNNING;
 
-    bucket_alloc = apr_bucket_alloc_create(pchild);
+    bucket_alloc = apr_bucket_alloc_create(pconf);
 
     /* die_now is set when AP_SIG_GRACEFUL is received in the child;
      * {shutdown,restart}_pending are set when a signal is received while
Index: server/mpm/simple/simple_children.c
===================================================================
--- server/mpm/simple/simple_children.c	(revision 1866998)
+++ server/mpm/simple/simple_children.c	(working copy)
@@ -54,7 +54,7 @@ static void simple_kill_random_child(simple_core_t
 static void clean_child_exit(int code) __attribute__ ((noreturn));
 static void clean_child_exit(int code)
 {
-    /* TODO: Pool cleanups.... sigh. */
+    /* pchild created/destroyed by simple_child_loop() */
     exit(code);
 }
 
Index: server/mpm/simple/simple_run.c
===================================================================
--- server/mpm/simple/simple_run.c	(revision 1866998)
+++ server/mpm/simple/simple_run.c	(working copy)
@@ -279,6 +279,7 @@ static int simple_setup_pollcb(simple_core_t * sc)
 int simple_child_loop(simple_core_t * sc)
 {
     apr_status_t rv;
+    apr_pool_t *pchild;
 
     rv = simple_setup_pollcb(sc);
     if (rv) {
@@ -310,9 +311,22 @@ int simple_child_loop(simple_core_t * sc)
         return !OK;
     }
 
-    ap_run_child_init(sc->pool, ap_server_conf);
+    /* Get a sub context for global allocations in this child, so that
+     * we can have cleanups occur when the child exits.
+     */
+    rv = apr_pool_create(&pchild, sc->pool);
+    if (rv) {
+        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO()
+                     "simple_child_loop: creating pchild failed");
+        return !OK;
+    }
+    apr_pool_tag(pchild, "pchild");
+    ap_run_child_init(pchild, ap_server_conf);
 
-    return simple_run_loop(sc);
+    rv = simple_run_loop(sc);
+
+    apr_pool_destroy(pchild);
+    return rv;
 }
 
 int simple_main_loop(simple_core_t * sc)
Index: server/mpm/worker/worker.c
===================================================================
--- server/mpm/worker/worker.c	(revision 1866998)
+++ server/mpm/worker/worker.c	(working copy)
@@ -1123,11 +1123,11 @@ static void child_main(int child_num_arg, int chil
     }
 
     /*stuff to do before we switch id's, so we have permissions.*/
-    ap_reopen_scoreboard(pchild, NULL, 0);
+    ap_reopen_scoreboard(pconf, NULL, 0);
 
     rv = SAFE_ACCEPT(apr_proc_mutex_child_init(&my_bucket->mutex,
                                     apr_proc_mutex_lockfile(my_bucket->mutex),
-                                    pchild));
+                                    pconf));
     if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00280)
                      "Couldn't initialize cross-process lock in child");
@@ -1135,7 +1135,7 @@ static void child_main(int child_num_arg, int chil
     }
 
     /* done with init critical section */
-    if (ap_run_drop_privileges(pchild, ap_server_conf)) {
+    if (ap_run_drop_privileges(pconf, ap_server_conf)) {
         clean_child_exit(APEXIT_CHILDFATAL);
     }
 
@@ -1172,9 +1172,9 @@ static void child_main(int child_num_arg, int chil
      */
     threads = (apr_thread_t **)ap_calloc(1,
                                   sizeof(apr_thread_t *) * threads_per_child);
-    ts = (thread_starter *)apr_palloc(pchild, sizeof(*ts));
+    ts = (thread_starter *)apr_palloc(pconf, sizeof(*ts));
 
-    apr_threadattr_create(&thread_attr, pchild);
+    apr_threadattr_create(&thread_attr, pconf);
     /* 0 means PTHREAD_CREATE_JOINABLE */
     apr_threadattr_detach_set(thread_attr, 0);
 
@@ -1194,7 +1194,7 @@ static void child_main(int child_num_arg, int chil
     ts->threadattr = thread_attr;
 
     rv = apr_thread_create(&start_thread_id, thread_attr, start_threads,
-                           ts, pchild);
+                           ts, pconf);
     if (rv != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf, APLOGNO(00282)
                      "apr_thread_create: unable to create worker thread");

Reply via email to