On Wed, Sep 25, 2019 at 11:54 AM Stefan Eissing <stefan.eiss...@greenbytes.de> wrote: > > Looking for help on an issue in mod_watchdog use and child exits. > > Occasionally a httpd child crashes due to races between child pool being > destroyed while watchdog threads are still running. The crash manifests most > likely when OPENSSL_cleanup runs while another thread is generated a private > key (singe that takes relatively long). > > Beside the crash report, nothing else really fails since the child is > terminating anyway and no requests are onoing. But still, it's not a nice > thing. > > Do you see an easy way to avoid this?
AFAICT, clean_child_exit() destroys pchild only, and pconf is still alive at exit() time. Couldn't we use pconf only in child_init hooks of mod_ssl and mod_watchdog? Does something like the attached patch fixes the crash?
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 generation */ +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 }