libtool-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fix ltdl memory handling


From: Ralf Wildenhues
Subject: Fix ltdl memory handling
Date: Wed, 1 Sep 2004 14:22:33 +0200
User-agent: Mutt/1.4.1i

Besides the memory leaks fixed with this patch, try_dlopen allocates one
*phandle which does not get freed eventually (try a current valgrind on
mdemo_static for example).  The logic is too involved for me to see a
simple fix without understanding all the code.

Regarding this patch:  In conformance with slist.[ch] comments, I went
without changing the semantics of slist_remove although I would have
found that a more natural way (i.e., to free(stale) from within
slist_remove).  Patch below leaves an unpleasant cast-away-const in
lt_dlloader_remove.

Regards,
Ralf

2004-09-01 Ralf Wildenhues <address@hidden>

        libltdl/slist.c (slist_new): Handle malloc failure gracefully.
        libltdl/lt_dlloader.c (lt_dlloader_add): Likewise for caller.
        (loader_cmp): Return node instead of userdata..
        (lt_dlloader_remove) ..so we can free it here.  Remove unused
        variable.  (lt_dlloader_find): Adjust for new loader_cmp
        semantics.
        libltdl/ltdl.c (lt_dlexit): While cleaning up, consider that the
        global `loaders' list is changed by `lt_dlloader_remove' while
        cleaning up, so target of local variable `loader' is invalidated.
        This is necessitated by the changes in lt_dlloader_remove.
        (try_dlopen): Fix memleak.

Index: libltdl/lt_dlloader.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/lt_dlloader.c,v
retrieving revision 1.3
diff -u -r1.3 lt_dlloader.c
--- libltdl/lt_dlloader.c       30 Aug 2004 12:33:09 -0000      1.3
+++ libltdl/lt_dlloader.c       1 Sep 2004 11:47:31 -0000
@@ -50,7 +50,7 @@
 
   assert (vtable);
 
-  return streq (vtable->name, name) ? (void *) vtable : 0;
+  return streq (vtable->name, name) ? (void *) node : 0;
 }
 
 
@@ -59,6 +59,7 @@
 int
 lt_dlloader_add (const lt_dlvtable *vtable)
 {
+  SList *new;
   if ((vtable == 0)    /* diagnose null parameters */
       || (vtable->module_open == 0)
       || (vtable->module_close == 0)
@@ -71,11 +72,11 @@
   switch (vtable->priority)
     {
     case LT_DLLOADER_PREPEND:
-      loaders = slist_cons (slist_new (vtable), loaders);
+      loaders = slist_cons (new = slist_new (vtable), loaders);
       break;
 
     case LT_DLLOADER_APPEND:
-      loaders = slist_concat (loaders, slist_new (vtable));
+      loaders = slist_concat (loaders, new = slist_new (vtable));
       break;
 
     default:
@@ -83,7 +84,10 @@
       return RETURN_FAILURE;
       /*NOTREACHED*/
     }
-
+  if (!new) {
+    LT__SETERROR (INVALID_LOADER);
+    return RETURN_FAILURE;
+  }
   return RETURN_SUCCESS;
 }
 
@@ -114,7 +118,7 @@
 {
   const lt_dlvtable *  vtable  = lt_dlloader_find (name);
   lt__handle *         handle  = 0;
-  int                  errors  = 0;
+  SList *              stale;
 
   if (!vtable)
     {
@@ -145,12 +149,19 @@
     }
 
   /* If we got this far, remove the loader from our global list.  */
-  return slist_remove (&loaders, name, loader_cmp);
+  stale = slist_remove (&loaders, name, loader_cmp);
+  if (stale) {
+    vtable = lt_dlloader_get(stale);
+    free(stale);
+    return vtable;
+  }
+  return 0;
 }
 
 
 const lt_dlvtable *
 lt_dlloader_find (const char *name)
 {
-  return slist_find (loaders, name, loader_cmp);
+  SList *node = slist_find (loaders, name, loader_cmp);
+  return node ? lt_dlloader_get(node) : NULL;
 }
Index: libltdl/ltdl.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/ltdl.c,v
retrieving revision 1.210
diff -u -r1.210 ltdl.c
--- libltdl/ltdl.c      1 Sep 2004 08:51:35 -0000       1.210
+++ libltdl/ltdl.c      1 Sep 2004 11:47:31 -0000
@@ -288,7 +288,7 @@
        }
 
       /* close all loaders */
-      while ((loader = lt_dlloader_next (loader)))
+      while ((loader = lt_dlloader_next (NULL)))
        {
          lt_dlvtable *vtable = (lt_dlvtable *) lt_dlloader_get (loader);
 
@@ -1296,6 +1296,8 @@
  cleanup:
   FREE (dir);
   FREE (name);
+  if (!canonical)      /* was MEMREASSIGNed */
+    FREE (base_name);
   FREE (canonical);
 
   return errors;
Index: libltdl/slist.c
===================================================================
RCS file: /cvsroot/libtool/libtool/libltdl/slist.c,v
retrieving revision 1.1
diff -u -r1.1 slist.c
--- libltdl/slist.c     15 Jul 2004 12:33:19 -0000      1.1
+++ libltdl/slist.c     1 Sep 2004 11:47:31 -0000
@@ -37,8 +37,10 @@
 {
   SList *node = malloc (sizeof *node);
 
-  node->next    = 0;
-  node->userdata = userdata;
+  if (node) {
+    node->next  = 0;
+    node->userdata = userdata;
+  }
 
   return node;
 }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]