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 }