This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Re: dlclose()
- To: kingdon at redhat dot com
- Subject: Re: dlclose()
- From: Jim Kingdon <kingdon at redhat dot com>
- Date: Sun, 20 Feb 2000 00:21:31 -0500
- CC: gdb-patches at sourceware dot cygnus dot com, blizzard at mozilla dot org
- References: <200002161953.OAA07411@devserv.devel.redhat.com>
> 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])
{