This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
Re: memory leak on glibc 2.0.7
- To: gafton@redhat.com (Cristian Gafton)
- Subject: Re: memory leak on glibc 2.0.7
- From: hjl@lucon.org (H.J. Lu)
- Date: Wed, 7 Oct 1998 11:03:44 -0700 (PDT)
- Cc: drepper@cygnus.com (Ulrich Drepper), libc-hacker@cygnus.com (GNU C Library)
>
>
> I think you already know this one ?
No, I don't. Here is a patch for glibc 2.0. It also has a patch for
an old bug. Ulrich, please only put the memory leak fix in glibc
2.1. Thanks.
>
> /*
> * memory leak in libdl.1.7.14 and /lib/libdl.so.2
> * (under libc and glibc).
> */
>
> #include <dlfcn.h>
>
> main()
> {
> int i=10000;
>
> mtrace();
> while (i-->0) {
> void *x = dlopen("/lib/libtermcap.so.2", RTLD_GLOBAL);
> printf("x=%p\n", x);
> dlclose(x);
> }
> muntrace();
> }
>
H.J.
-----
Wed Oct 7 07:57:00 1998 H.J. Lu <hjl@gnu.org>
* elf/dl-close.c (_dl_close): Fix a memory leak.
Wed Sep 2 19:18:43 1998 H.J. Lu <hjl@gnu.org>
* elf/dl-open.c (_dl_open): Don't put the shared object on the
global scope list twice.
* elf/dl-close.c (_dl_close): Update _dl_global_scope[2] if the
first object on the list is removed.
Index: elf/dl-open.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/elf/dl-open.c,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 dl-open.c
--- dl-open.c 1998/08/30 14:59:02 1.1.1.6
+++ dl-open.c 1998/09/02 18:58:03
@@ -110,11 +110,22 @@ _dl_open (const char *file, int mode)
_dl_close (new);
_dl_signal_error (ENOMEM, file, "cannot extend global scope");
}
- _dl_global_scope[2] = _dl_default_scope[2];
- _dl_global_scope[3] = new;
- _dl_global_scope[4] = NULL;
- _dl_global_scope[5] = NULL;
- _dl_global_scope_end = &_dl_global_scope [4];
+
+ if (_dl_default_scope [2] == new)
+ {
+ _dl_global_scope[2] = new;
+ _dl_global_scope[3] = NULL;
+ _dl_global_scope[4] = NULL;
+ _dl_global_scope_end = &_dl_global_scope [3];
+ }
+ else
+ {
+ _dl_global_scope[2] = _dl_default_scope[2];
+ _dl_global_scope[3] = new;
+ _dl_global_scope[4] = NULL;
+ _dl_global_scope[5] = NULL;
+ _dl_global_scope_end = &_dl_global_scope [4];
+ }
}
else
{
Index: elf/dl-close.c
===================================================================
RCS file: /home/work/cvs/gnu/glibc-2.0/elf/dl-close.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 dl-close.c
--- dl-close.c 1998/09/02 14:27:29 1.1.1.7
+++ dl-close.c 1998/10/07 17:34:03
@@ -117,11 +117,19 @@ _dl_close (struct link_map *map)
if (imap->l_prev)
imap->l_prev->l_next = imap->l_next;
else
- _dl_loaded = imap->l_next;
+ {
+ if (_dl_global_scope[2] == imap)
+ _dl_global_scope[2] = imap->l_next;
+ _dl_loaded = imap->l_next;
+ }
if (imap->l_next)
imap->l_next->l_prev = imap->l_prev;
if (imap->l_searchlist && imap->l_searchlist != list)
free (imap->l_searchlist);
+ if (map->l_name && imap->l_name [0] != '\0')
+ free (imap->l_name);
+ if (imap->l_libname && imap->l_libname [0] != '\0')
+ free ((char *) imap->l_libname);
free (imap);
}
}