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]

Another revised patch for dlclose


On Wed, Mar 08, 2000 at 09:41:00AM -0500, Jim Kingdon wrote:
> 
> There are a few loose ends in freeing, but it is the tangled logic in
> find_solib that is tripping us up more than the freeing.

Here is a new patch. It seems to work with the testcase. Any
comments?


H.J.
----
2000-03-08  H.J. Lu  <hjl@gnu.org>

	Inspired by patches from Sam Lantinga (slouken@devolution.com):

	* solib.c (solib_verify): New function. Unload the shared
	object when it is deleted and dump symbols from the unloaded
	shared object.

	* solib.h (SOLIB_VERIFY): New. Defined as solib_verify.

	* infrun.c (handle_inferior_event): Also call SOLIB_VERIFY ()
	if it is defined when we hit the internal debug breakpoint for
	shared libraries in the dynamic linker.

Index: solib.c
===================================================================
RCS file: /work/cvs/gnu/gdb/gdb/solib.c,v
retrieving revision 1.1.1.4
retrieving revision 1.7
diff -u -p -r1.1.1.4 -r1.7
--- solib.c	2000/03/07 18:42:17	1.1.1.4
+++ solib.c	2000/03/08 18:36:11	1.7
@@ -950,6 +950,84 @@ open_symbol_file_object (arg)
   return 1;
 }
 #endif /* SVR4_SHARED_LIBS */
+
+/*
+  
+GLOBAL FUNCTION
+
+	solib_verify -- check solib list consistency and dump symbols
+			from unloaded shared objects
+
+SYNOPSIS
+
+	void solib_verify (void)
+
+DESCRIPTION
+
+	This module is called whenever we hit a dynamic linker
+	breakpoint and allows us to check the consistency of our shared 
+	object list and unload objects which are no longer valid in the
+	in the inferior. Without this, dynamic unlinking of objects
+	could crash us. This function should only be called when we
+	hit the internal debug breakpoint for shared libraries in the
+	dynamic linker.
+
+ */
+
+void
+solib_verify (void)
+{
+#ifdef SVR4_SHARED_LIBS
+  if (debug_base)
+    {
+      static int solib_unloading = 0;
+
+      read_memory (debug_base, (char *) &debug_copy,
+		   sizeof (struct r_debug));
+      if (debug_copy.r_state == RT_DELETE)
+        solib_unloading = 1;
+      else if (solib_unloading && debug_copy.r_state == RT_CONSISTENT)
+        {
+	  struct so_list *so = NULL, *next, *so_next, *saved;
+
+	  /* Get the current list of loaded shared libraries. */
+	  saved = so_list_head;
+	  so_list_head = NULL;
+	  while ((so = find_solib (so)) != NULL);
+	  so = so_list_head;
+	  so_list_head = saved;
+
+	  /* We compare the current list against what we have. */
+	  for (next = so_list_head; next; next = next->next)
+	    {
+	      for (so_next = so; so_next; so_next = so_next->next)
+	        if (strcmp (so_next->so_name, next->so_name) == 0)
+		  break;
+
+	      if (!so_next)
+	        {
+		  /* We didn't find it in the current list. Unload it.
+		     Since the dynamic linker can only unload one
+		     shared library at a time, we stop here. Also
+		     free_objfile () will call clear_solib (). It will
+		     clear everything for us.  */
+		  free_objfile (next->objfile);
+		  break;
+	        }
+	    }
+
+	  /* Free the current list of loaded shared libraries. */
+	  for (so_next = so; so_next; so_next = next)
+	    {
+	      next = so_next->next;
+	      free (so_next);
+	    }
+
+	  solib_unloading = 0;
+	}
+    }
+#endif	/* SVR4_SHARED_LIBS */
+}
 
 /*
 
Index: solib.h
===================================================================
RCS file: /work/cvs/gnu/gdb/gdb/solib.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -p -r1.1.1.1 -r1.2
--- solib.h	1999/09/09 00:38:38	1.1.1.1
+++ solib.h	2000/03/07 21:55:11	1.2
@@ -37,6 +37,14 @@ clear_solib PARAMS ((void));
 extern void
 solib_add PARAMS ((char *, int, struct target_ops *));
 
+/* Called to check solib list consistency and dump symbols from
+   unloaded shared objects. */
+
+#define SOLIB_VERIFY() solib_verify ()
+
+extern void
+solib_verify PARAMS ((void));
+
 /* Function to be called when the inferior starts up, to discover the names
    of shared libraries that are dynamically linked, the base addresses to
    which they are linked, and sufficient information to read in their symbols
Index: infrun.c
===================================================================
RCS file: /work/cvs/gnu/gdb/gdb/infrun.c,v
retrieving revision 1.1.1.6
retrieving revision 1.2
diff -u -p -r1.1.1.6 -r1.2
--- infrun.c	2000/03/07 18:42:13	1.1.1.6
+++ infrun.c	2000/03/07 21:55:11	1.2
@@ -2416,6 +2416,9 @@ handle_inferior_event (struct execution_
 		/* Switch terminal for any messages produced by
 		   breakpoint_re_set.  */
 		target_terminal_ours_for_output ();
+#ifdef SOLIB_VERIFY
+		SOLIB_VERIFY ();
+#endif
 		SOLIB_ADD (NULL, 0, NULL);
 		target_terminal_inferior ();
 	      }

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