Bug#711213: libapache2-mod-perl2: occasional core dumps after the test suite
Niko Tyni
ntyni at debian.org
Fri Jun 14 06:09:41 UTC 2013
On Sun, Jun 09, 2013 at 11:23:01PM +0300, Niko Tyni wrote:
> On Fri, Jun 07, 2013 at 02:23:43PM +0300, Niko Tyni wrote:
>
> > I can reproduce the SIGSEGV at the end of the main test suite (#711213)
> > on amd64. The armel problem might well be related, as the log ends at
> > the same point.
> I'm somewhat further now: what happens is that register_auth_provider()
> in modperl_util.c calls
> apr_pool_pre_cleanup_register(pool, NULL, cleanup_perl_global_providers);
> once in the parent process, then another time in a child. For some
> reason that I do not understand yet, the cleanup_perl_global_providers()
> function resides at a different memory location (with a 0x2c000 offset
> or so) on the second time. The first location has at that point become
> an invalid memory address, resulting in a SIGSEGV when libapr calls the
> registered cleanup functions and jumps into the old location.
Another progress report. I now mostly understand what's happening.
Contrary to the above, all the interesting stuff happens inside the
parent process.
Cc'ing the apache2 maintainers; any ideas? See below.
(The jump to an invalid address is crashing armel buildds so it's a
rather big problem ATM. See #711167, where this has diverged.)
First, apache2 main() calls read_config() (from main.c:624), which
loads all the modules. Loading mod_perl installs the pre_cleanup
hook cleanup_perl_global_providers() as above.
Then, there's a loop starting at main.c:704 that has this comment:
/* This is a hack until we finish the code so that it only reads
* the config file once and just operates on the tree already in
* memory. rbb
*/
and calls apr_pool_clear(pconf), which unloads the modules and should
do all the cleanup AIUI. A bit later, at main.c:724, ap_read_config() is
called again, and under some conditions (when stack limit is 'unlimited'
and the number of modules is suitable?), mod_perl gets loaded at a
different place than the first time. However, the earlier installed
pre_cleanup hook is still in place, so we jump into an out-of-bounds
location (where cleanup_perl_global_providers() used to reside) in the
end when the cleanups are actually called.
So I suppose mod_perl should somehow register a "module uninstall hook"
that calls apr_pool_cleanup_run(..., cleanup_perl_global_providers, ...)
[or apr_pool_cleanup_kill(), not sure] to remove the to-be-unloaded
pre_cleanup hook. I haven't found a way to do that yet.
--
Niko Tyni ntyni at debian.org
More information about the pkg-perl-maintainers
mailing list