This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: dlclose()


> Here's another patch for the dlclose() problem we've been talking
> about (5130 in bugzilla.redhat.com and all).

Early feedback seems to be positive (thanks Chris), so here is a
slightly revised version (cleans up some of the free'ing).  As far as
I know this is ready to check in.  Of course, if people want to weigh
in that could help make it clear.

2000-02-20  Jim Kingdon  <kingdon@redhat.com>

	* solib.c (find_solib): New argument recheck.
	* solib.c (solib_add): Pass it as 1, and add logic to delete
	shared libraries which aren't still in the inferior.
	(struct so_list): New field found_me, for solib_add.
	* solib.c (other find_solib callers): Pass recheck as 0.

Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.1.1.10
diff -u -r1.1.1.10 solib.c
--- solib.c	1999/11/17 02:30:28	1.1.1.10
+++ solib.c	2000/02/20 05:17:18
@@ -31,6 +31,7 @@
 #include "gdb_string.h"
 #include <sys/param.h>
 #include <fcntl.h>
+#include <assert.h>
 
 #ifndef SVR4_SHARED_LIBS
  /* SunOS shared libs need the nlist structure.  */
@@ -143,6 +144,11 @@
     char so_name[MAX_PATH_SIZE];	/* shared object lib name (FIXME) */
     char symbols_loaded;	/* flag: symbols read in yet? */
     char from_tty;		/* flag: print msgs? */
+
+    /* Flag for use within solib_add: have we seen this library actually
+       still mapped in the inferior this pass?  */
+    char found_me;
+
     struct objfile *objfile;	/* objfile for loaded lib */
     struct section_table *sections;
     struct section_table *sections_end;
@@ -181,8 +187,7 @@
 
 static int symbol_add_stub PARAMS ((PTR));
 
-static struct so_list *
-  find_solib PARAMS ((struct so_list *));
+static struct so_list *find_solib (struct so_list *, int);
 
 static struct link_map *
   first_link_map_member PARAMS ((void));
@@ -975,8 +980,10 @@
  */
 
 static struct so_list *
-find_solib (so_list_ptr)
-     struct so_list *so_list_ptr;	/* Last lm or NULL for first one */
+find_solib (struct so_list *so_list_ptr,
+	    /* Nonzero if we should read all the entries from the inferior,
+	       not just the ones at the end of the list.  */
+	    int recheck)
 {
   struct so_list *so_list_next = NULL;
   struct link_map *lm = NULL;
@@ -985,7 +992,9 @@
   if (so_list_ptr == NULL)
     {
       /* We are setting up for a new scan through the loaded images. */
-      if ((so_list_next = so_list_head) == NULL)
+      so_list_next = so_list_head;
+      if (so_list_next == NULL
+	  || recheck)
 	{
 	  /* We have not already read in the dynamic linking structures
 	     from the inferior, lookup the address of the base structure. */
@@ -1002,7 +1011,8 @@
     {
       /* We have been called before, and are in the process of walking
          the shared library list.  Advance to the next shared object. */
-      if ((lm = LM_NEXT (so_list_ptr)) == NULL)
+      lm = LM_NEXT (so_list_ptr);
+      if (recheck || lm == NULL)
 	{
 	  /* We have hit the end of the list, so check to see if any were
 	     added, but be quiet if we can't read from the target any more. */
@@ -1020,7 +1030,7 @@
 	}
       so_list_next = so_list_ptr->next;
     }
-  if ((so_list_next == NULL) && (lm != NULL))
+  if ((so_list_next == NULL || recheck) && (lm != NULL))
     {
       /* Get next link map structure from inferior image and build a local
          abbreviated load_map structure */
@@ -1188,7 +1198,7 @@
       /* Count how many new section_table entries there are.  */
       so = NULL;
       count = 0;
-      while ((so = find_solib (so)) != NULL)
+      while ((so = find_solib (so, 0)) != NULL)
 	{
 	  if (so->so_name[0] && !match_main (so->so_name))
 	    {
@@ -1201,7 +1211,7 @@
 	  
 	  /* Add these section table entries to the target's table.  */
 	  old = target_resize_to_sections (target, count);
-	  while ((so = find_solib (so)) != NULL)
+	  while ((so = find_solib (so, 0)) != NULL)
 	    {
 	      if (so->so_name[0])
 		{
@@ -1215,9 +1225,13 @@
 	}
     }
 
+  for (so = so_list_head; so != NULL; so = so->next)
+    so->found_me = 0;
+
   /* Now add the symbol files.  */
-  while ((so = find_solib (so)) != NULL)
+  while ((so = find_solib (so, 1)) != NULL)
     {
+      so->found_me = 1;
       if (so->so_name[0] && re_exec (so->so_name) &&
 	  !match_main (so->so_name))
 	{
@@ -1240,6 +1254,42 @@
 	}
     }
 
+  {
+    struct so_list *prev;
+    prev = NULL;
+    for (so = so_list_head; so != NULL; so = so->next)
+      {
+	if (!so->found_me)
+	  {
+	    /* FIXME: need analogue to disable_breakpoints_in_shlibs but
+	       just for this one struct so_list.  */
+
+	    if (so->sections != NULL)
+	      free (so->sections);
+
+	    free_objfile (so->objfile);
+
+	    /* Punt the issue of the section tables that we put in the
+	       target vector.  The excuse is that they are basically
+	       used for coredumps rather than running programs, and
+	       with coredumps we don't unload shared libraries.  */
+
+	    assert (so->abfd != NULL);
+	    if (!bfd_close (so->abfd))
+	      warning ("cannot close \"%s\": %s",
+		       so->so_name, bfd_errmsg (bfd_get_error ()));
+
+	    if (prev == NULL)
+	      so_list_head = so->next;
+	    else
+	      prev->next = so->next;
+
+	    free (so);
+	  }
+	prev = so;
+      }
+  }
+
   /* Getting new symbols may change our opinion about what is
      frameless.  */
   if (so_last)
@@ -1289,7 +1339,7 @@
   addr_fmt = "016l";
 #endif
 
-  while ((so = find_solib (so)) != NULL)
+  while ((so = find_solib (so, 0)) != NULL)
     {
       if (so->so_name[0])
 	{
@@ -1347,7 +1397,7 @@
 {
   register struct so_list *so = 0;	/* link map state variable */
 
-  while ((so = find_solib (so)) != NULL)
+  while ((so = find_solib (so, 0)) != NULL)
     {
       if (so->so_name[0])
 	{

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]