Hi,

as an experiment to see if the segfault I am currently debugging were caused 
by my modifications I found this. Httpd segfaults if its startup is aborted 
because the DYNAMIC_MODULE_LIMIT is hit. The reason is that the module that 
caused the abort is first unloaded as dso and then used in ap_remove_module as 
ap_top_module. Unfortunately, the memory segment where the module is located 
is already wiped from the process' address space at the time.

This happens because both apr_dso_load and mod_so:load_module register a pool 
cleanup to undo their effects. These cleanup functions are called in the wrong 
order.

I see 2 ways how to prevent that:

1) change in mod_so.c line 305 from

  apr_pool_cleanup_register(cmd->pool, modi, unload_module,
                            apr_pool_cleanup_null);

to

  apr_pool_pre_cleanup_register(cmd->pool, modi, unload_module);

This way ap_remove_module will be called before the dso is unloaded.

2) check for possible errors in ap_add_module() before performing any changes:

@@ -541,16 +565,11 @@
                             m->name, m->version, MODULE_MAGIC_NUMBER_MAJOR);
     }
 
-    if (m->next == NULL) {
-        m->next = ap_top_module;
-        ap_top_module = m;
-    }
-
     if (m->module_index == -1) {
         m->module_index = total_modules++;
         dynamic_modules++;
 
         if (dynamic_modules > DYNAMIC_MODULE_LIMIT) {
             return apr_psprintf(p, "Module \"%s\" could not be loaded, "
                                 "because the dynamic module limit was "
                                 "reached. Please increase "
@@ -568,6 +587,13 @@
         }
     }
 
+    if (m->next == NULL) {
+        m->next = ap_top_module;
+        ap_top_module = m;
+    }
+
     if (sym_name) {
         int len = strlen(sym_name);
         int slen = strlen("_module");


Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net

Reply via email to