[rfa] Partial fix for debugging static threaded apps

Daniel Jacobowitz drow@false.org
Wed Dec 8 17:48:00 GMT 2004


This patch finally connects linux-thread-db.c to the new inferior_created
observer.  The thread_db_new_objfile hook is broken out into a common
function; it is called when new shared libraries are loaded, and when
a new inferior is created or attached to.  It's fairly straightforward.

What isn't straightforward are the other issues with staticthreads.exp.
Both of these were observed on my desktop system, a Debian GNU/Linux
unstable, i686-linux system running NPTL and a 2.6 kernel.

(A) This patch isn't strictly necessary, because there is always a shared
library - even for static applications.  That's because my kernel supports
the vsyscall DSO, and GDB now handles it.  The patch is still necessary for
non-vsyscall setups.

(B) This patch isn't sufficient, because GDB is dynamically linked to
libthread_db, and loads it from /lib/tls/i686/cmov/libthread_db.so.1. That's
NPTL.  staticthreads is statically linked and gets LinuxThreads instead
of NPTL.  I have a follow-up patch which allows GDB to load both copies of
libthread_db and use the right one.  That fixes staticthreads.exp for me.
I'll clean it up for submission after this patch is settled.

Is this patch OK?

-- 
Daniel Jacobowitz

2004-12-08  Daniel Jacobowitz  <dan@debian.org>

	* Makefile.in (linux-thread-db.o): Add $(observer_h).
	* linux-thread-db.c: Include "observer.h".
	(check_for_thread_db): New function, broken out from
	thread_db_new_objfile.  Update comments.  Delete redundant
	using_thread_db check.
	(thread_db_new_objfile): Call check_for_thread_db.
	(check_for_thread_db_observer): New function.
	(_initialize_thread_db): Register an inferior_created
	observer.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.676
diff -u -p -r1.676 Makefile.in
--- Makefile.in	7 Dec 2004 22:17:59 -0000	1.676
+++ Makefile.in	8 Dec 2004 16:27:11 -0000
@@ -2625,7 +2625,7 @@ thread.o: thread.c $(defs_h) $(symtab_h)
 linux-thread-db.o: linux-thread-db.c $(defs_h) $(gdb_assert_h) \
 	$(gdb_proc_service_h) $(gdb_thread_db_h) $(bfd_h) $(gdbthread_h) \
 	$(inferior_h) $(symfile_h) $(objfiles_h) $(target_h) $(regcache_h) \
-	$(solib_svr4_h)
+	$(solib_svr4_h) $(observer_h)
 top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \
 	$(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \
 	$(inferior_h) $(target_h) $(breakpoint_h) $(gdbtypes_h) \
Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.2
diff -u -p -r1.2 linux-thread-db.c
--- linux-thread-db.c	8 Dec 2004 15:10:30 -0000	1.2
+++ linux-thread-db.c	8 Dec 2004 16:27:11 -0000
@@ -34,6 +34,7 @@
 #include "target.h"
 #include "regcache.h"
 #include "solib-svr4.h"
+#include "observer.h"
 
 #ifdef HAVE_GNU_LIBC_VERSION_H
 #include <gnu/libc-version.h>
@@ -618,8 +619,12 @@ check_thread_signals (void)
 #endif
 }
 
+/* Check whether thread_db is usable.  This function is called when
+   an inferior is created (or otherwise acquired, e.g. attached to)
+   and when new shared libraries are loaded into a running process.  */
+
 static void
-thread_db_new_objfile (struct objfile *objfile)
+check_for_thread_db (void)
 {
   td_err_e err;
 
@@ -648,29 +653,16 @@ thread_db_new_objfile (struct objfile *o
   }
 
   /* Don't attempt to use thread_db on targets which can not run
-     (core files).  */
-  if (objfile == NULL || !target_has_execution)
-    {
-      /* All symbols have been discarded.  If the thread_db target is
-         active, deactivate it now.  */
-      if (using_thread_db)
-	{
-	  gdb_assert (proc_handle.pid == 0);
-	  unpush_target (&thread_db_ops);
-	  using_thread_db = 0;
-	}
-
-      goto quit;
-    }
+     (executables not running yet, core files) for now.  */
+  if (!target_has_execution)
+    return;
 
   if (using_thread_db)
     /* Nothing to do.  The thread library was already detected and the
        target vector was already activated.  */
-    goto quit;
+    return;
 
-  /* Initialize the structure that identifies the child process.  Note
-     that at this point there is no guarantee that we actually have a
-     child process.  */
+  /* Initialize the structure that identifies the child process.  */
   proc_handle.pid = GET_PID (inferior_ptid);
 
   /* Now attempt to open a connection to the thread library.  */
@@ -697,12 +689,24 @@ thread_db_new_objfile (struct objfile *o
 	       thread_db_err_str (err));
       break;
     }
+}
+
+static void
+thread_db_new_objfile (struct objfile *objfile)
+{
+  if (objfile != NULL)
+    check_for_thread_db ();
 
-quit:
   if (target_new_objfile_chain)
     target_new_objfile_chain (objfile);
 }
 
+static void
+check_for_thread_db_observer (struct target_ops *target, int from_tty)
+{
+  check_for_thread_db ();
+}
+
 /* Attach to a new thread.  This function is called when we receive a
    TD_CREATE event or when we iterate over all threads and find one
    that wasn't already in our list.  */
@@ -1357,5 +1361,8 @@ _initialize_thread_db (void)
       /* Add ourselves to objfile event chain.  */
       target_new_objfile_chain = deprecated_target_new_objfile_hook;
       deprecated_target_new_objfile_hook = thread_db_new_objfile;
+
+      /* Register ourselves for the new inferior observer.  */
+      observer_attach_inferior_created (check_for_thread_db_observer);
     }
 }



More information about the Gdb-patches mailing list