This is the mail archive of the gdb@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]

A revised patch for dlclose


Here is a revised patch for dlclose. If you take a look at the
dynamic linker in glibc 2.1 or above, you will find that it informs
gdb about loading/unloading a shared library via an internal debug
function, _dl_debug_state (). gdb already handles the loading in
handle_inferior_event () with BPSTAT_WHAT_CHECK_SHLIBS and
BPSTAT_WHAT_CHECK_SHLIBS_RESUME_FROM_HOOK. However, we need also
check the unloading event. solib_verify () will be called only when the
dynamic linker calls _dl_debug_state (). It shouldn't introduce any
overhead. I believe it is on the right track although it may be further
optimized.


-- 
H.J. Lu (hjl@gnu.org)
---
2000-03-07  H.J. Lu  <hjl@gnu.org>

	Based on patches from Sam Lantinga (slouken@devolution.com):

	* solib.c (solib_verify): New function. Reload list of shared
	objects when they are added or deleted and dump symbols from
	unloaded shared objects.

	* 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
diff -u -p -r1.1.1.4 solib.c
--- solib.c	2000/03/07 18:42:17	1.1.1.4
+++ solib.c	2000/03/07 19:58:49
@@ -950,6 +954,70 @@ 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.
+
+AUTHOR
+	Sam Lantinga <hercules@lokigames.com>
+ */
+
+void
+solib_verify (void)
+{
+#ifdef SVR4_SHARED_LIBS
+  struct objfile *current;
+
+  if (debug_base)
+    {
+      read_memory (debug_base, (char *) &debug_copy,
+		   sizeof (struct r_debug));
+      /* If the shared object state is consistent, we can reload our
+	 list */
+      if ( debug_copy.r_state == RT_CONSISTENT )
+	clear_solib();
+   }
+
+  for (current = symfile_objfile; current; current = current->next)
+    {
+      struct so_list *so;
+      char *bfd_filename;
+      for (so = so_list_head; so; so = so->next)
+	{
+	  if (so->abfd)
+	    {
+	      bfd_filename = bfd_get_filename (so->abfd);
+	      if (bfd_filename 
+	          && strcmp(bfd_filename, current->name) == 0)
+		break;
+            }
+        }
+      if ((current != symfile_objfile) && (so == NULL))
+	{
+	  free_objfile(current);
+	  break;
+	}
+    }
+#endif	/* SVR4_SHARED_LIBS */
+}
 
 /*
 
Index: solib.h
===================================================================
RCS file: /work/cvs/gnu/gdb/gdb/solib.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 solib.h
--- solib.h	1999/09/09 00:38:38	1.1.1.1
+++ solib.h	2000/03/07 19:49:31
@@ -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
diff -u -p -r1.1.1.6 infrun.c
--- infrun.c	2000/03/07 18:42:13	1.1.1.6
+++ infrun.c	2000/03/07 19:53:59
@@ -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]