[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Re: DynaLoader/MakeMaker problem? - Apache::ASP: crash when placed in startup.pl



[not on p5p]

On Sun, Jan 16, 2000 at 06:26:55PM +0000, Alan Burlison wrote:
> [p5p folks: I've CC'd this to p5p because I think the proper fix will
> require changes to DynaLoader and/or MakeMaker - sorry for the long
> post, but the root cause of the problem is somewhat complicated]
> 
> That's it! Well done!  I didn't realise that Apache explicitly unloaded
> the mod_perl libpel.so.  I've waltzed around this for hours, sure I was
> in the right area but never convinced that I had the exact cause
> nailed.  That explains all the symptoms, and it also explains why
> LD_PRELOAD or adding a linker dependency to the perl XS .so files also
> works.  On Solaris when an object is dlclose'd, the linker checks to see

This is the icky part of apache's config handling; it unloads and
reloads modules once during startup and again during every restart.

> that both it and any modules pulled in by ld.so as the result of a
> dependency are not used for resolving any symbols before removing
> it/them.  This uses a sort of complicated refcounting mechanism.  Hence
> a dlclose() doesn't necessarily mean that the object will be removed.
> 
> The mod_perl libperl.so has a dependency on the perl libperl.so.  When
> Apache dlopen's the mod_perl libperl.so, ld.so also pulls in the perl
> libperl.so.  When Apache dlclose's the mod_perl libperl.so as part of
> its restart mechanism, the associated perl libperl.so is also unloaded,
> *despite* the fact that it is used to resolve symbols in the perl XS .so
> files.

This part confuses me.  From my dlopen() manpage:

       dlclose  decrements  the  reference  count  on the dynamic
       library handle handle.  If the reference  count  drops  to
       zero and no other loaded libraries use symbols in it, then
       the dynamic library is unloaded.  If the  dynamic  library

But the dynamic linker clearly shows other libraries using symbols in
mod_perl.so.  Perhaps it means 'has it marked as SO_NEEDED' instead of
merely 'using symbols in it'.

> I think it is somewhat of an edge case - you could argue that even
> though there is no explicit dependency between the perl XS .so files and
> the perl libperl.so, the linker should be able to notice that it has
> used symbols from libperl.so and increment the refcounts accordingly. 
> Then again, you could also argue that there should be an explicit
> dependency between the perl XS .so files and the perl libperl.so.

Certainly not.

For my different perspective on this, bear in mind I work on Linux.  We
have a static libperl.a available for embedded applications, and perl
does not use a shared library.

Thus, there can not be a dependency between the modules and the perl
binary, because it is a binary and not a soname; and obviously you do
not want them linked to libperl.a to get symbols from it, as you end up
with private copies of things.  They need to be unresolved and without
a dependency.

> a) Requesting that MakeMaker adds a dependency between the .so files it
> generates and the perl libperl.so
> 
> b) Requesting that a 'remove a module' method is added to DynaLoader

As said, I need to go for (b).

> It worked for me as well.  One slight concern is that in the attached
> "after" file it appears that DynaLoaded .so files are unloaded twice in
> succession - I'll try tracking down exactly why this is.

Doesn't happen here.  I played with ltrace and logged the dl*() calls:

dlopen("/usr/lib/apache/1.3/mod_cgi.so", 258)     = 0x080a4fd8
dlopen("/usr/lib/apache/1.3/mod_mime.so", 258)    = 0x080a5358
dlopen("././mod_perl.so", 258)                    = 0x080a5680
dlopen("/usr/lib/apache/1.3/mod_userdir."..., 258) = 0x080a5a88
dlopen("/usr/lib/perl5/5.005/i386-linux/"..., 1)  = 0x0811cac8
dlclose(0x080a5a88)                               = 0
dlclose(0x080a5680)                               = 0
dlclose(0x080a5358)                               = 0
dlclose(0x080a4fd8)                               = 0
dlopen("/usr/lib/apache/1.3/mod_cgi.so", 258)     = 0x081819a0
dlopen("/usr/lib/apache/1.3/mod_mime.so", 258)    = 0x08181bd0
dlopen("././mod_perl.so", 258)                    = 0x080a4fb0
dlopen("/usr/lib/apache/1.3/mod_userdir."..., 258) = 0x080b20f8
dlopen("/usr/lib/perl5/5.005/i386-linux/"..., 1)  = 0x081f7b20
dlopen("/usr/lib/perl5/5.005/i386-linux/"..., 1)  = 0x08271320



I'm still seeing the problem that perl is not properly destroying
itself, or destroying some sort of symbol from modules; thus every time
I SIGHUP apache, its heap grows by an amount proportional to the number
of loaded modules.  I haven't figured out what isn't getting recovered
yet; I'll keep beating on that.


Dan

/--------------------------------\  /--------------------------------\
|       Daniel Jacobowitz        |__|        SCS Class of 2002       |
|   Debian GNU/Linux Developer    __    Carnegie Mellon University   |
|         dan@debian.org         |  |       dmj+@andrew.cmu.edu      |
\--------------------------------/  \--------------------------------/


Follow-Ups from:
Alan Burlison <Alan.Burlison@uk.sun.com>
References to:
Alan Burlison <Alan.Burlison@uk.sun.com>

[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]