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]

[patch] Fix for PR gdb/9538 (loading of separate debuginfo and symlinks).


Greetings,

Attached is a proposed fix for PR gdb/9538.

Mostly it just moves code around, and adds a "try realpath(objfile->name)
if searching with objfile->name fails."

The added test fails before the patch, and succeeds after it.

Tested on Linux/x86_64.

Thanks,

--
Paul Pluzhnikov


2012-01-11  Paul Pluzhnikov  <ppluzhnikov@google.com>

	PR gdb/9538
	* symfile.c (find_separate_debug_file): New function.
	(terminate_after_last_dir_separator): Likewise.
	(find_separate_debug_file_by_debuglink): Also try realpath.


testsuite/ChangeLog:

	PR gdb/9538
	* gdb.base/sepdebug.exp: New test.



Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.325
diff -u -p -r1.325 symfile.c
--- symfile.c	12 Jan 2012 00:00:01 -0000	1.325
+++ symfile.c	12 Jan 2012 01:34:01 -0000
@@ -1441,35 +1441,15 @@ show_debug_file_directory (struct ui_fil
 #define DEBUG_SUBDIRECTORY ".debug"
 #endif
 
-char *
-find_separate_debug_file_by_debuglink (struct objfile *objfile)
-{
-  char *basename, *debugdir;
-  char *dir = NULL;
-  char *debugfile = NULL;
-  char *canon_name = NULL;
-  unsigned long crc32;
+static char *
+find_separate_debug_file (const char *dir, const char *debuglink,
+			  unsigned long crc32, struct objfile *objfile)
+{
+  char *debugdir;
+  char *debugfile;
+  char *canon_name;
   int i;
 
-  basename = get_debug_link_info (objfile, &crc32);
-
-  if (basename == NULL)
-    /* There's no separate debug info, hence there's no way we could
-       load it => no warning.  */
-    goto cleanup_return_debugfile;
-
-  dir = xstrdup (objfile->name);
-
-  /* Strip off the final filename part, leaving the directory name,
-     followed by a slash.  The directory can be relative or absolute.  */
-  for (i = strlen(dir) - 1; i >= 0; i--)
-    {
-      if (IS_DIR_SEPARATOR (dir[i]))
-	break;
-    }
-  /* If I is -1 then no directory is present there and DIR will be "".  */
-  dir[i+1] = '\0';
-
   /* Set I to max (strlen (canon_name), strlen (dir)).  */
   canon_name = lrealpath (dir);
   i = strlen (dir);
@@ -1480,12 +1460,12 @@ find_separate_debug_file_by_debuglink (s
 		       + i
 		       + strlen (DEBUG_SUBDIRECTORY)
 		       + strlen ("/")
-		       + strlen (basename)
+		       + strlen (debuglink)
 		       + 1);
 
   /* First try in the same directory as the original file.  */
   strcpy (debugfile, dir);
-  strcat (debugfile, basename);
+  strcat (debugfile, debuglink);
 
   if (separate_debug_file_exists (debugfile, crc32, objfile))
     goto cleanup_return_debugfile;
@@ -1494,7 +1474,7 @@ find_separate_debug_file_by_debuglink (s
   strcpy (debugfile, dir);
   strcat (debugfile, DEBUG_SUBDIRECTORY);
   strcat (debugfile, "/");
-  strcat (debugfile, basename);
+  strcat (debugfile, debuglink);
 
   if (separate_debug_file_exists (debugfile, crc32, objfile))
     goto cleanup_return_debugfile;
@@ -1520,7 +1500,7 @@ find_separate_debug_file_by_debuglink (s
       debugfile[debugdir_end - debugdir] = 0;
       strcat (debugfile, "/");
       strcat (debugfile, dir);
-      strcat (debugfile, basename);
+      strcat (debugfile, debuglink);
 
       if (separate_debug_file_exists (debugfile, crc32, objfile))
 	goto cleanup_return_debugfile;
@@ -1536,7 +1516,7 @@ find_separate_debug_file_by_debuglink (s
 	  debugfile[debugdir_end - debugdir] = 0;
 	  strcat (debugfile, canon_name + strlen (gdb_sysroot));
 	  strcat (debugfile, "/");
-	  strcat (debugfile, basename);
+	  strcat (debugfile, debuglink);
 
 	  if (separate_debug_file_exists (debugfile, crc32, objfile))
 	    goto cleanup_return_debugfile;
@@ -1551,8 +1531,61 @@ find_separate_debug_file_by_debuglink (s
 
 cleanup_return_debugfile:
   xfree (canon_name);
-  xfree (basename);
+  return debugfile;
+}
+
+static void
+terminate_after_last_dir_separator (char *path)
+{
+  int i;
+
+  /* Strip off the final filename part, leaving the directory name,
+     followed by a slash.  The directory can be relative or absolute.  */
+  for (i = strlen(path) - 1; i >= 0; i--)
+    {
+      if (IS_DIR_SEPARATOR (path[i]))
+	break;
+    }
+  /* If I is -1 then no directory is present there and DIR will be "".  */
+  path[i+1] = '\0';
+}
+
+char *
+find_separate_debug_file_by_debuglink (struct objfile *objfile)
+{
+  char *debuglink;
+  char *dir;
+  char *debugfile;
+  unsigned long crc32;
+
+  debuglink = get_debug_link_info (objfile, &crc32);
+
+  if (debuglink == NULL)
+    /* There's no separate debug info, hence there's no way we could
+       load it => no warning.  */
+    return NULL;
+
+  dir = xstrdup (objfile->name);
+  terminate_after_last_dir_separator (dir);
+
+  debugfile = find_separate_debug_file (dir, debuglink, crc32, objfile);
   xfree (dir);
+
+  if (debugfile != NULL)
+    goto cleanup_return_debugfile;
+
+  /* For PR gdb/9538, try again with realpath.  */
+  dir = lrealpath (objfile->name);
+  if (dir == NULL)
+    goto cleanup_return_debugfile;
+
+  terminate_after_last_dir_separator (dir);
+  debugfile = find_separate_debug_file (dir, debuglink, crc32, objfile);
+  xfree (dir);
+
+ cleanup_return_debugfile:
+  xfree (debuglink);
+
   return debugfile;
 }
 
Index: testsuite/gdb.base/sepdebug.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sepdebug.exp,v
retrieving revision 1.33
diff -u -p -r1.33 sepdebug.exp
--- testsuite/gdb.base/sepdebug.exp	4 Jan 2012 08:17:46 -0000	1.33
+++ testsuite/gdb.base/sepdebug.exp	12 Jan 2012 01:34:01 -0000
@@ -45,7 +45,7 @@ if  { [gdb_compile "${srcdir}/${subdir}/
 
 # Note: the procedure gdb_gnu_strip_debug will produce an executable called
 # ${binfile}, which is just like the executable ($binfile) but without
-# the debuginfo. Instead $binfile has a .gnudebuglink section which contains
+# the debuginfo. Instead $binfile has a .gnu_debuglink section which contains
 # the name of a debuginfo only file. This file will be stored in the
 # gdb.base/ subdirectory.
 
@@ -55,9 +55,25 @@ if [gdb_gnu_strip_debug $binfile] {
     return -1
 }
 
+#
+# PR gdb/9538.  Verify that symlinked executable still finds the separate
+# debuginfo.
+#
 gdb_exit
 gdb_start
 gdb_reinitialize_dir $srcdir/$subdir
+set subsubdir ${objdir}/${subdir}/pr9538
+exec mkdir ${subsubdir}
+exec ln -s ${binfile} ${subsubdir}
+gdb_load ${subsubdir}/${testfile}${EXEEXT}
+if { $gdb_file_cmd_debug_info != "debug" } then {
+    fail "No debug information found."
+}
+gdb_exit
+exec rm -rf ${subsubdir}
+
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
 gdb_load ${binfile}
 if { $gdb_file_cmd_debug_info != "debug" } then {
     fail "No debug information found."


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