This is the mail archive of the gdb-patches@sourceware.org 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]
Other format: [Raw text]

[RFA 2/2] $pdir/../foo: Add support in libthread-db-search-path


Hi.
In a 64-cross-32 debugging situation, $pdir in libthread-db-search-path
isn't usable, what you really want is $pdir/../lib64.
[setting aside lib vs lib32 vs lib64, blech]

This set of two patches provides support for this.

This second patch contains the core functionality.

Ok to check in?

Regression tested on amd64-linux.

2012-07-18  Doug Evans  <dje@google.com>

	* linux-thread-db.c: #include "gdb_vecs.h".
	(try_thread_db_load_from_pdir_1): New arg "subdir".  All callers
	updated.
	(try_thread_db_load_from_pdir): New arg "subdir".  All callers updated.
	(thread_db_load_search): Use a vector to iterate over path elements.
	Handle text appearing after "$pdir".

	gdbserver/
	* Makefile.in (SFILES): Add gdb_vecs.c.
	(OBS): Add gdb_vecs.o.
	(gdb_vecs_h, host_defs_h): New variables.
	(thread-db.o): Add $(gdb_vecs_h) dependency.
	(gdb_vecs.o): New rule.
	* thread-db.c: #include "gdb_vecs.h".
	(thread_db_load_search): Use a vector to iterate over path elements.
	Handle text appearing after "$pdir".

Index: linux-thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/linux-thread-db.c,v
retrieving revision 1.104
diff -u -p -r1.104 linux-thread-db.c
--- linux-thread-db.c	7 Jul 2012 12:11:31 -0000	1.104
+++ linux-thread-db.c	19 Jul 2012 01:34:25 -0000
@@ -23,7 +23,7 @@
 #include <dlfcn.h>
 #include "gdb_proc_service.h"
 #include "gdb_thread_db.h"
-
+#include "gdb_vecs.h"
 #include "bfd.h"
 #include "command.h"
 #include "exceptions.h"
@@ -898,11 +898,12 @@ try_thread_db_load (const char *library)
 }
 
 /* Subroutine of try_thread_db_load_from_pdir to simplify it.
-   Try loading libthread_db from the same directory as OBJ.
+   Try loading libthread_db in directory(OBJ)/SUBDIR.
+   SUBDIR may be NULL.  It may also be something like "../lib64".
    The result is true for success.  */
 
 static int
-try_thread_db_load_from_pdir_1 (struct objfile *obj)
+try_thread_db_load_from_pdir_1 (struct objfile *obj, const char *subdir)
 {
   struct cleanup *cleanup;
   char *path, *cp;
@@ -915,14 +916,21 @@ try_thread_db_load_from_pdir_1 (struct o
       return 0;
     }
 
-  path = xmalloc (strlen (obj->name) + 1 + strlen (LIBTHREAD_DB_SO) + 1);
+  path = xmalloc (strlen (obj->name) + (subdir ? strlen (subdir) + 1 : 0)
+		  + 1 + strlen (LIBTHREAD_DB_SO) + 1);
   cleanup = make_cleanup (xfree, path);
 
   strcpy (path, obj->name);
   cp = strrchr (path, '/');
   /* This should at minimum hit the first character.  */
   gdb_assert (cp != NULL);
-  strcpy (cp + 1, LIBTHREAD_DB_SO);
+  cp[1] = '\0';
+  if (subdir != NULL)
+    {
+      strcat (cp, subdir);
+      strcat (cp, "/");
+    }
+  strcat (cp, LIBTHREAD_DB_SO);
 
   if (!file_is_auto_load_safe (path, _("auto-load: Loading libthread-db "
 				       "library \"%s\" from $pdir.\n"),
@@ -936,11 +944,12 @@ try_thread_db_load_from_pdir_1 (struct o
 }
 
 /* Handle $pdir in libthread-db-search-path.
-   Look for libthread_db in the directory of libpthread.
+   Look for libthread_db in directory(libpthread)/SUBDIR.
+   SUBDIR may be NULL.  It may also be something like "../lib64".
    The result is true for success.  */
 
 static int
-try_thread_db_load_from_pdir (void)
+try_thread_db_load_from_pdir (const char *subdir)
 {
   struct objfile *obj;
 
@@ -950,14 +959,15 @@ try_thread_db_load_from_pdir (void)
   ALL_OBJFILES (obj)
     if (libpthread_name_p (obj->name))
       {
-	if (try_thread_db_load_from_pdir_1 (obj))
+	if (try_thread_db_load_from_pdir_1 (obj, subdir))
 	  return 1;
 
 	/* We may have found the separate-debug-info version of
 	   libpthread, and it may live in a directory without a matching
 	   libthread_db.  */
 	if (obj->separate_debug_objfile_backlink != NULL)
-	  return try_thread_db_load_from_pdir_1 (obj->separate_debug_objfile_backlink);
+	  return try_thread_db_load_from_pdir_1 (obj->separate_debug_objfile_backlink,
+						 subdir);
 
 	return 0;
       }
@@ -1015,37 +1025,41 @@ try_thread_db_load_from_dir (const char 
 static int
 thread_db_load_search (void)
 {
-  const char *search_path = libthread_db_search_path;
-  int rc = 0;
+  VEC (char_ptr) *dir_vec;
+  struct cleanup *cleanups;
+  char *this_dir;
+  int i, rc = 0;
 
-  while (*search_path)
+  dir_vec = dirnames_to_char_ptr_vec (libthread_db_search_path);
+  cleanups = make_cleanup_free_char_ptr_vec (dir_vec);
+
+  for (i = 0; VEC_iterate (char_ptr, dir_vec, i, this_dir); ++i)
     {
-      const char *end = strchr (search_path, ':');
-      const char *this_dir = search_path;
+      const int pdir_len = sizeof ("$pdir") - 1;
       size_t this_dir_len;
 
-      if (end)
-	{
-	  this_dir_len = end - search_path;
-	  search_path += this_dir_len + 1;
-	}
-      else
-	{
-	  this_dir_len = strlen (this_dir);
-	  search_path += this_dir_len;
-	}
+      this_dir_len = strlen (this_dir);
 
-      if (this_dir_len == sizeof ("$pdir") - 1
-	  && strncmp (this_dir, "$pdir", this_dir_len) == 0)
+      if (strncmp (this_dir, "$pdir", pdir_len) == 0
+	  && (this_dir[pdir_len] == '\0'
+	      || this_dir[pdir_len] == '/'))
 	{
-	  if (try_thread_db_load_from_pdir ())
+	  char *subdir = NULL;
+	  struct cleanup *free_subdir_cleanup = NULL;
+
+	  if (this_dir[pdir_len] == '/')
 	    {
-	      rc = 1;
-	      break;
+	      subdir = xmalloc (strlen (this_dir));
+	      free_subdir_cleanup = make_cleanup (xfree, subdir);
+	      strcpy (subdir, this_dir + pdir_len + 1);
 	    }
+	  rc = try_thread_db_load_from_pdir (subdir);
+	  if (free_subdir_cleanup != NULL)
+	    do_cleanups (free_subdir_cleanup);
+	  if (rc)
+	    break;
 	}
-      else if (this_dir_len == sizeof ("$sdir") - 1
-	       && strncmp (this_dir, "$sdir", this_dir_len) == 0)
+      else if (strcmp (this_dir, "$sdir") == 0)
 	{
 	  if (try_thread_db_load_from_sdir ())
 	    {
@@ -1063,6 +1077,7 @@ thread_db_load_search (void)
 	}
     }
 
+  do_cleanups (cleanups);
   if (libthread_db_debug)
     printf_unfiltered (_("thread_db_load_search returning %d\n"), rc);
   return rc;
Index: gdbserver/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/Makefile.in,v
retrieving revision 1.135
diff -u -p -r1.135 Makefile.in
--- gdbserver/Makefile.in	2 Jul 2012 15:29:38 -0000	1.135
+++ gdbserver/Makefile.in	19 Jul 2012 01:34:25 -0000
@@ -140,7 +140,7 @@ SFILES=	$(srcdir)/gdbreplay.c $(srcdir)/
 	$(srcdir)/win32-arm-low.c $(srcdir)/win32-i386-low.c \
 	$(srcdir)/win32-low.c $(srcdir)/wincecompat.c \
 	$(srcdir)/hostio.c $(srcdir)/hostio-errno.c \
-	$(srcdir)/common/vec.c \
+	$(srcdir)/common/vec.c $(srcdir)/common/gdb_vecs.c \
 	$(srcdir)/common/common-utils.c $(srcdir)/common/xml-utils.c \
 	$(srcdir)/common/linux-osdata.c $(srcdir)/common/ptid.c \
 	$(srcdir)/common/buffer.c
@@ -153,7 +153,7 @@ SOURCES = $(SFILES)
 TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
 
 OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
-	utils.o version.o vec.o \
+	utils.o version.o vec.o gdb_vecs.o \
 	mem-break.o hostio.o event-loop.o tracepoint.o \
 	xml-utils.o common-utils.o ptid.o buffer.o format.o \
 	dll.o \
@@ -414,6 +414,8 @@ ax_h = $(srcdir)/ax.h
 agent_h = $(srcdir)/../common/agent.h
 linux_osdata_h = $(srcdir)/../common/linux-osdata.h
 vec_h = $(srcdir)/../common/vec.h
+gdb_vecs_h = $(srcdir)/../common/gdb_vecs.h
+host_defs_h = $(srcdir)/../common/host-defs.h
 # Since everything must include server.h, we make that depend on
 # generated files.
 server_h = $(srcdir)/server.h $(regcache_h) $(srcdir)/target.h \
@@ -485,7 +487,7 @@ remote-utils.o: remote-utils.c terminal.
 server.o: server.c $(server_h) $(agent_h) $(gdbthread_h)
 target.o: target.c $(server_h) 
 thread-db.o: thread-db.c $(server_h) $(linux_low_h) $(gdb_proc_service_h) \
-	$(gdb_thread_db_h)
+	$(gdb_thread_db_h) $(gdb_vecs_h)
 tracepoint.o: tracepoint.c $(server_h) $(ax_h) $(agent_h) $(gdbthread_h)
 utils.o: utils.c $(server_h)
 gdbreplay.o: gdbreplay.c config.h
@@ -506,6 +508,9 @@ common-utils.o: ../common/common-utils.c
 vec.o: ../common/vec.c $(vec_h)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
 
+gdb_vecs.o: ../common/gdb_vecs.c $(vec_h) $(gdb_vecs_h) $(host_defs_h)
+	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
+
 xml-utils.o: ../common/xml-utils.c $(server_h)
 	$(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
 
Index: gdbserver/thread-db.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbserver/thread-db.c,v
retrieving revision 1.43
diff -u -p -r1.43 thread-db.c
--- gdbserver/thread-db.c	4 Jan 2012 08:17:24 -0000	1.43
+++ gdbserver/thread-db.c	19 Jul 2012 01:34:25 -0000
@@ -28,6 +28,7 @@ static int thread_db_use_events;
 
 #include "gdb_proc_service.h"
 #include "gdb_thread_db.h"
+#include "gdb_vecs.h"
 
 #ifndef USE_LIBTHREAD_DB_DIRECTLY
 #include <dlfcn.h>
@@ -741,39 +742,31 @@ try_thread_db_load_from_dir (const char 
 static int
 thread_db_load_search (void)
 {
-  const char *search_path;
-  int rc = 0;
+  VEC (char_ptr) *dir_vec;
+  char *this_dir;
+  int i, rc = 0;
 
   if (libthread_db_search_path == NULL)
     libthread_db_search_path = xstrdup (LIBTHREAD_DB_SEARCH_PATH);
 
-  search_path = libthread_db_search_path;
-  while (*search_path)
+  dir_vec = dirnames_to_char_ptr_vec (libthread_db_search_path);
+
+  for (i = 0; VEC_iterate (char_ptr, dir_vec, i, this_dir); ++i)
     {
-      const char *end = strchr (search_path, ':');
-      const char *this_dir = search_path;
+      const int pdir_len = sizeof ("$pdir") - 1;
       size_t this_dir_len;
 
-      if (end)
-	{
-	  this_dir_len = end - search_path;
-	  search_path += this_dir_len + 1;
-	}
-      else
-	{
-	  this_dir_len = strlen (this_dir);
-	  search_path += this_dir_len;
-	}
+      this_dir_len = strlen (this_dir);
 
-      if (this_dir_len == sizeof ("$pdir") - 1
-	  && strncmp (this_dir, "$pdir", this_dir_len) == 0)
+      if (strncmp (this_dir, "$pdir", pdir_len) == 0
+	  && (this_dir[pdir_len] == '\0'
+	      || this_dir[pdir_len] == '/'))
 	{
 	  /* We don't maintain a list of loaded libraries so we don't know
 	     where libpthread lives.  We *could* fetch the info, but we don't
 	     do that yet.  Ignore it.  */
 	}
-      else if (this_dir_len == sizeof ("$sdir") - 1
-	       && strncmp (this_dir, "$sdir", this_dir_len) == 0)
+      else if (strcmp (this_dir, "$sdir") == 0)
 	{
 	  if (try_thread_db_load_from_sdir ())
 	    {
@@ -791,6 +784,7 @@ thread_db_load_search (void)
 	}
     }
 
+  free_char_ptr_vec (dir_vec);
   if (debug_threads)
     fprintf (stderr, "thread_db_load_search returning %d\n", rc);
   return rc;


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