On 2007-01-14, at 11:15:33 +0100, Rafael Garcia-Suarez wrote:
> On 13/01/07, Marvin Humphrey <[EMAIL PROTECTED]> wrote:
> > It's been a couple days with no response to this, so it looks like
> > I've been Warnocked. Not too surprising, as this very small memory
> > leak affects very few people: people using Valgrind to debug XS
> > modules, possibly people embedding Perl.
> >
> > Since there doesn't seem to be a burning need to fix this, here's a
> > "do no harm" patch which just adds a note to perlhack.pod:
>
> Thanks, I applied this as change #29803. I suppose that if DynaLoader
> doesn't unload all by default, it's for speed of interpreter shutdown.
> However having that option available only at compile time is a pain.
> Couldn't it be overriden by an environment variable, for example ?
When hunting memory leaks, you need PERL_DESTRUCT_LEVEL=2 anyway.
And this already only works with -DDEBUGGING. So something like the
change below seemed reasonable to me.
However, it unfortunately won't work with threads. Perl will segfault
when a thread terminates. Without having looked into it further, I
guess the problem is that function registered with call_atexit() are
called on thread exit, and unloading the threads module while perl
is still running is probably not a good idea.
(In other words, please don't apply this. ;-)
Marcus
--- ext/DynaLoader/dlutils.c.orig 2007-01-14 21:27:22.000000000 +0100
+++ ext/DynaLoader/dlutils.c 2007-01-14 21:48:49.000000000 +0100
@@ -59,7 +59,7 @@ START_MY_CXT
#define DLDEBUG(level,code) NOOP
#endif
-#ifdef DL_UNLOAD_ALL_AT_EXIT
+#ifdef DEBUGGING
/* Close all dlopen'd files */
static void
dl_unload_all_files(pTHX_ void *unused)
@@ -67,6 +67,10 @@ dl_unload_all_files(pTHX_ void *unused)
CV *sub;
AV *dl_librefs;
SV *dl_libref;
+ const char * const s = getenv("PERL_DESTRUCT_LEVEL");
+
+ if (!s || atoi(s) < 2)
+ return;
if ((sub = get_cv("DynaLoader::dl_unload_file", FALSE)) != NULL) {
dl_librefs = get_av("DynaLoader::dl_librefs", FALSE);
@@ -110,7 +114,7 @@ dl_generic_private_init(pTHX) /* called
if (!dl_loaded_files)
dl_loaded_files = newHV(); /* provide cache for dl_*.xs if needed */
#endif
-#ifdef DL_UNLOAD_ALL_AT_EXIT
+#ifdef DEBUGGING
call_atexit(&dl_unload_all_files, (void*)0);
#endif
}