core: deregister all hooks before leaving pconf, otherwise some late cleanup
or function call (e.g. ap_log) may use one while DSOs are unloaded.
See PR 61558 (double/second fault).
@@ -295,6 +295,13 @@ static int abort_on_oom(int retcode)
return retcode; /* unreachable, hopefully. */
}
+static apr_status_t deregister_all_hooks(void *unused)
+{
+ (void)unused;
+ apr_hook_deregister_all();
+ return APR_SUCCESS;
+}
+
static process_rec *init_process(int *argc, const char * const * *argv)
{
process_rec *process;
@@ -497,6 +504,10 @@ int main(int argc, const char * const argv[])
}
#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,
@@ -743,10 +754,13 @@ int main(int argc, const char * const argv[])
do {
ap_main_state = AP_SQ_MS_DESTROY_CONFIG;
- apr_hook_deregister_all();
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);
+
ap_main_state = AP_SQ_MS_CREATE_CONFIG;
ap_config_generation++;
for (mod = ap_prelinked_modules; *mod != NULL; mod++) {
