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]

[rfc] Separate debug files and --with-sysroot


This is a patch I've had lying around for quite a while.

Background: The --with-sysroot option is designed for cross debuggers which
target a normally native system, such as remote debugging of GNU/Linux or
BSD targets.  It's especially important because shared libraries will have
"absolute" paths in the debuggee that need to be adjusted on the host.
So right now, to match the other components of the toolchain, GDB has a
--with-sysroot configure option that maps on to a default setting of the
"solib-absolute-prefix" variable.

Background 2: Separate debug files are a neat invention which allows
debugging information to be stored in a different file from the code,
so that they can be installed optionally.  GDB searches for them in a
couple of places: next to the executable, in a .debug subdirectory of the
executable's parent directory, and in 'debug-file-directory' plus the
full path to the executable.   If /bin/ls has a .gnu_debuglink section
saying that debug info is named ls.debug, GDB will look in /bin/ls.debug,
/bin/.debug/ls.debug, and $prefix/lib/debug/bin/ls.debug.

For sysrooted setups, I think the appropriate paths to search inside the
debug info directory are ones relative to the sysroot.  That lets a system
using NFS to share the root filesystem (pretty common, in my embedded Linux
experience) use the same debug info files for a cross debugger and a native
debugger.  That means a layout of something like this:

    /path/to/devkit/sys-root/lib/ld-linux.so.2
    /path/to/devkit/sys-root/bin/ls
    /path/to/devkit/sys-root/usr/lib/debug/bin/ls.debug

This is a lot more useful than having the "full" host path; then you'd have
/path/to/devkit/sys-root/usr/lib/debug/path/to/devkit/sys-root/bin/ls.debug.
Talk about a mouthful.

The attached patch does two things:
  - We relocate the default sysroot when GDB is moved, based on the runtime
    prefix.  Extend the same logic to the default debug directory, so that
    a prepared installation can be dropped in at any path - very useful
    when distributing.
  - If a system root is configured, and an object file is inside the system
    root, the system root path is removed when searching the debug file
    directory.

This seems pretty reasonable to me.  Looking at it now, I'm thinking of an
additional tweak: adding "set sysroot", and making solib-absolute-prefix
an alias to that, so that the sysroot is configurable at runtime.  That
will need a documentation update.

Any thoughts?

-- 
Daniel Jacobowitz
CodeSourcery

2006-10-17  Daniel Jacobowitz  <dan@codesourcery.com>

	* configure.ac (DEBUGDIR_RELOCATABLE): Define for debugdir inside
	exec_prefix.
	(TARGET_SYSTEM_ROOT_RELOCATABLE): Allow for exec_prefix being
	'${prefix}'.
	* configure, config.in: Regenerate.
	* defs.h (debug_file_directory): Declare.
	* main.c (captured_main): Canonicalize gdb_sysroot.  Initialize
	debug_file_directory and relocate it if DEBUGDIR_RELOCATABLE.
	* symfile.c (debug_file_directory): Make non-static.
	(find_separate_debug_file): Look for debug info for SYSROOT/PATH
	in DEBUGDIR/PATH if DEBUGDIR is inside SYSROOT.
	(_initialize_symfile): Don't initialize debug_file_directory here.

diff -rup gdb-6.5.50.orig/gdb/configure.ac gdb-6.5.50/gdb/configure.ac
--- gdb-6.5.50.orig/gdb/configure.ac	2006-08-08 13:26:23.000000000 -0700
+++ gdb-6.5.50/gdb/configure.ac	2006-10-17 16:07:31.000000000 -0700
@@ -75,6 +75,22 @@ AC_DEFINE_DIR(DEBUGDIR, debugdir,
               [Global directory for separate debug files. ])
 #AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
+if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then
+  if test "x$prefix" = xNONE; then
+    test_prefix=/usr/local
+  else
+    test_prefix=$prefix
+  fi
+else
+  test_prefix=$exec_prefix
+fi
+case ${debugdir} in
+"${test_prefix}"|"${test_prefix}/"*|\
+'${exec_prefix}'|'${exec_prefix}/'*)
+  AC_DEFINE(DEBUGDIR_RELOCATABLE, 1, [Define if the debug directory should be relocated when GDB is moved.])
+  ;;
+esac
+
 AC_CONFIG_SUBDIRS(doc testsuite)
 
 # Provide defaults for some variables set by the per-host and per-target
@@ -1064,7 +1080,7 @@ AC_ARG_WITH(sysroot,
 
  TARGET_SYSTEM_ROOT_DEFINE='-DTARGET_SYSTEM_ROOT=\"$(TARGET_SYSTEM_ROOT)\"'
 
- if test "x$exec_prefix" = xNONE; then
+ if test "x$exec_prefix" = xNONE || test "x$exec_prefix" = 'x${prefix}'; then
   if test "x$prefix" = xNONE; then
    test_prefix=/usr/local
   else
diff -rup gdb-6.5.50.orig/gdb/defs.h gdb-6.5.50/gdb/defs.h
--- gdb-6.5.50.orig/gdb/defs.h	2006-09-21 06:50:51.000000000 -0700
+++ gdb-6.5.50/gdb/defs.h	2006-10-17 15:34:03.000000000 -0700
@@ -167,6 +167,9 @@ extern int dbx_commands;
 /* System root path, used to find libraries etc.  */
 extern char *gdb_sysroot;
 
+/* Search path for separate debug files.  */
+extern char *debug_file_directory;
+
 extern int quit_flag;
 extern int immediate_quit;
 extern int sevenbit_strings;
diff -rup gdb-6.5.50.orig/gdb/main.c gdb-6.5.50/gdb/main.c
--- gdb-6.5.50.orig/gdb/main.c	2006-07-27 14:31:40.000000000 -0700
+++ gdb-6.5.50/gdb/main.c	2006-10-17 15:34:03.000000000 -0700
@@ -221,19 +221,64 @@ captured_main (void *data)
       if (res == 0)
 	{
 	  xfree (gdb_sysroot);
-	  gdb_sysroot = TARGET_SYSTEM_ROOT;
+	  gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
 	}
     }
   else
-    gdb_sysroot = TARGET_SYSTEM_ROOT;
+    gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
 #else
 #if defined (TARGET_SYSTEM_ROOT)
-  gdb_sysroot = TARGET_SYSTEM_ROOT;
+  gdb_sysroot = xstrdup (TARGET_SYSTEM_ROOT);
 #else
   gdb_sysroot = "";
 #endif
 #endif
 
+  /* Canonicalize the sysroot path.  */
+  if (*gdb_sysroot)
+    {
+      char *canon_sysroot = lrealpath (gdb_sysroot);
+      if (canon_sysroot)
+	{
+	  xfree (gdb_sysroot);
+	  gdb_sysroot = canon_sysroot;
+	}
+    }
+
+#ifdef DEBUGDIR_RELOCATABLE
+  debug_file_directory = make_relative_prefix (argv[0], BINDIR, DEBUGDIR);
+  if (debug_file_directory)
+    {
+      struct stat s;
+      int res = 0;
+
+      if (stat (debug_file_directory, &s) == 0)
+	if (S_ISDIR (s.st_mode))
+	  res = 1;
+
+      if (res == 0)
+	{
+	  xfree (debug_file_directory);
+	  debug_file_directory = xstrdup (DEBUGDIR);
+	}
+    }
+  else
+    debug_file_directory = xstrdup (DEBUGDIR);
+#else
+  debug_file_directory = xstrdup (DEBUGDIR);
+#endif
+
+  /* Canonicalize the debugfile path.  */
+  if (*debug_file_directory)
+    {
+      char *canon_debug = lrealpath (debug_file_directory);
+      if (canon_debug)
+	{
+	  xfree (debug_file_directory);
+	  debug_file_directory = canon_debug;
+	}
+    }
+
   /* There will always be an interpreter.  Either the one passed into
      this captured main, or one specified by the user at start up, or
      the console.  Initialize the interpreter to the one requested by 
diff -rup gdb-6.5.50.orig/gdb/symfile.c gdb-6.5.50/gdb/symfile.c
--- gdb-6.5.50.orig/gdb/symfile.c	2006-09-21 07:00:53.000000000 -0700
+++ gdb-6.5.50/gdb/symfile.c	2006-10-17 15:34:22.000000000 -0700
@@ -1156,7 +1156,7 @@ separate_debug_file_exists (const char *
   return crc == file_crc;
 }
 
-static char *debug_file_directory = NULL;
+char *debug_file_directory = NULL;
 static void
 show_debug_file_directory (struct ui_file *file, int from_tty,
 			   struct cmd_list_element *c, const char *value)
@@ -1178,6 +1178,7 @@ find_separate_debug_file (struct objfile
   char *dir;
   char *debugfile;
   char *name_copy;
+  char *canon_name;
   bfd_size_type debuglink_size;
   unsigned long crc32;
   int i;
@@ -1245,6 +1246,30 @@ find_separate_debug_file (struct objfile
       return xstrdup (debugfile);
     }
 
+  /* If the file is in the sysroot, try using its base path in the
+     global debugfile directory.  */
+  canon_name = lrealpath (dir);
+  if (canon_name
+      && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
+      && IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
+    {
+      strcpy (debugfile, debug_file_directory);
+      strcat (debugfile, canon_name + strlen (gdb_sysroot));
+      strcat (debugfile, "/");
+      strcat (debugfile, basename);
+
+      if (separate_debug_file_exists (debugfile, crc32))
+	{
+	  xfree (canon_name);
+	  xfree (basename);
+	  xfree (dir);
+	  return xstrdup (debugfile);
+	}
+    }
+  
+  if (canon_name)
+    xfree (canon_name);
+
   xfree (basename);
   xfree (dir);
   return NULL;
@@ -3857,7 +3882,6 @@ Usage: set extension-language .foo bar")
   add_info ("extensions", info_ext_lang_command,
 	    _("All filename extensions associated with a source language."));
 
-  debug_file_directory = xstrdup (DEBUGDIR);
   add_setshow_optional_filename_cmd ("debug-file-directory", class_support,
 				     &debug_file_directory, _("\
 Set the directory where separate debug symbols are searched for."), _("\

-- 
Joseph S. Myers
joseph@codesourcery.com


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