- Support multiple directories for `set debug-file-directory' (BZ 528668).

This commit is contained in:
Jan Kratochvil 2009-10-22 23:52:25 +00:00
parent e4ac510550
commit d4a047fbf7
5 changed files with 674 additions and 183 deletions

View File

@ -1,7 +1,7 @@
Index: gdb-6.8.91.20090925/gdb/corelow.c
Index: gdb-7.0/gdb/corelow.c
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/corelow.c 2009-07-31 17:25:21.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/corelow.c 2009-09-25 09:39:09.000000000 +0200
--- gdb-7.0.orig/gdb/corelow.c 2009-07-31 17:25:21.000000000 +0200
+++ gdb-7.0/gdb/corelow.c 2009-10-23 00:17:29.000000000 +0200
@@ -45,6 +45,10 @@
#include "exceptions.h"
#include "solib.h"
@ -91,11 +91,11 @@ Index: gdb-6.8.91.20090925/gdb/corelow.c
+ NULL, NULL, NULL,
+ &setlist, &showlist);
}
Index: gdb-6.8.91.20090925/gdb/doc/gdb.texinfo
Index: gdb-7.0/gdb/doc/gdb.texinfo
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/doc/gdb.texinfo 2009-09-25 09:29:58.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/doc/gdb.texinfo 2009-09-25 09:29:58.000000000 +0200
@@ -13895,6 +13895,27 @@ information files.
--- gdb-7.0.orig/gdb/doc/gdb.texinfo 2009-10-23 00:12:39.000000000 +0200
+++ gdb-7.0/gdb/doc/gdb.texinfo 2009-10-23 00:17:29.000000000 +0200
@@ -13896,6 +13896,27 @@ information files.
@end table
@ -123,10 +123,10 @@ Index: gdb-6.8.91.20090925/gdb/doc/gdb.texinfo
@cindex @code{.gnu_debuglink} sections
@cindex debug link sections
A debug link is a special section of the executable file named
Index: gdb-6.8.91.20090925/gdb/solib-svr4.c
Index: gdb-7.0/gdb/solib-svr4.c
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/solib-svr4.c 2009-09-25 09:29:57.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/solib-svr4.c 2009-09-25 09:43:14.000000000 +0200
--- gdb-7.0.orig/gdb/solib-svr4.c 2009-10-23 00:12:38.000000000 +0200
+++ gdb-7.0/gdb/solib-svr4.c 2009-10-23 00:17:29.000000000 +0200
@@ -1101,9 +1101,49 @@ svr4_current_sos (void)
safe_strerror (errcode));
else
@ -180,10 +180,10 @@ Index: gdb-6.8.91.20090925/gdb/solib-svr4.c
}
xfree (buffer);
Index: gdb-6.8.91.20090925/gdb/symfile.c
Index: gdb-7.0/gdb/symfile.c
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/symfile.c 2009-09-25 09:29:57.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/symfile.c 2009-09-25 09:29:58.000000000 +0200
--- gdb-7.0.orig/gdb/symfile.c 2009-10-23 00:12:38.000000000 +0200
+++ gdb-7.0/gdb/symfile.c 2009-10-23 00:43:28.000000000 +0200
@@ -56,6 +56,7 @@
#include "elf-bfd.h"
#include "solib.h"
@ -618,7 +618,7 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
if (found == NULL)
warning (_("File \"%s\" has no build-id, file skipped"), filename);
@@ -1234,8 +1626,9 @@ build_id_verify (const char *filename, s
@@ -1234,14 +1626,16 @@ build_id_verify (const char *filename, s
return retval;
}
@ -628,48 +628,77 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
+build_id_to_filename (struct build_id *build_id, char **link_return,
+ int add_debug_suffix)
{
char *link, *s, *retval = NULL;
gdb_byte *data = build_id->data;
@@ -1243,7 +1636,9 @@ build_id_to_debug_filename (struct build
char *link, *debugdir, *retval = NULL;
+ char *link_all = NULL;
/* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
- + 2 * size + (sizeof ".debug" - 1) + 1);
+ + 2 * size
+ + (add_debug_suffix ? sizeof ".debug" - 1 : 0)
+ + 1);
s = link + sprintf (link, "%s/.build-id/", debug_file_directory);
if (size > 0)
{
@@ -1254,12 +1649,14 @@ build_id_to_debug_filename (struct build
*s++ = '/';
while (size-- > 0)
s += sprintf (s, "%02x", (unsigned) *data++);
- strcpy (s, ".debug");
+ if (add_debug_suffix)
+ strcpy (s, ".debug");
+ else
+ *s = 0;
- link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
- + 2 * build_id->size + (sizeof ".debug" - 1) + 1);
+ link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+ + 2 * build_id->size + (sizeof ".debug" - 1) + 1);
/* lrealpath() is expensive even for the usually non-existent files. */
if (access (link, F_OK) == 0)
retval = lrealpath (link);
- xfree (link);
/* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
cause "/.build-id/..." lookups. */
@@ -1272,7 +1666,10 @@ build_id_to_debug_filename (struct build
*s++ = '/';
while (size-- > 0)
s += sprintf (s, "%02x", (unsigned) *data++);
- strcpy (s, ".debug");
+ if (add_debug_suffix)
+ strcpy (s, ".debug");
+ else
+ *s = 0;
if (retval != NULL && !build_id_verify (retval, build_id))
{
@@ -1267,9 +1664,150 @@ build_id_to_debug_filename (struct build
retval = NULL;
/* lrealpath() is expensive even for the usually non-existent files. */
if (access (link, F_OK) == 0)
@@ -1285,15 +1682,185 @@ build_id_to_debug_filename (struct build
}
if (retval != NULL)
- break;
+ {
+ /* LINK_ALL is not used below in this non-NULL RETVAL case. */
+ break;
+ }
+
+ if (link_all == NULL)
+ link_all = xstrdup (link);
+ else
+ {
+ size_t len_orig = strlen (link_all);
+
+ link_all = xrealloc (link_all, len_orig + 1 + strlen (link) + 1);
+
+ /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with
+ its possible use as an argument for installation command. */
+ link_all[len_orig] = ' ';
+
+ strcpy (&link_all[len_orig + 1], link);
+ }
debugdir = debugdir_end;
}
while (*debugdir != 0);
+ if (link_return != NULL)
+ *link_return = link;
+ else
+ xfree (link);
+ {
+ if (retval != NULL)
+ {
+ *link_return = link;
+ link = NULL;
+ }
+ else
+ {
+ *link_return = link_all;
+ link_all = NULL;
+ }
+ }
+ xfree (link);
+ xfree (link_all);
+
+ return retval;
+}
+
return retval;
}
+/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages
+ Try to install the hash file ...
+ avoidance. */
@ -692,9 +721,9 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
+
+ retval = obstack_alloc (&missing_filepair_obstack, size);
+ memset (retval, 0, size);
+ return retval;
+}
+
return retval;
}
+static hashval_t
+missing_filepair_hash_func (const struct missing_filepair *elem)
+{
@ -809,20 +838,7 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
static char *
get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
{
@@ -1352,32 +1890,36 @@ static char *
find_separate_debug_file (struct objfile *objfile)
{
asection *sect;
- char *basename;
- char *dir;
- char *debugfile;
+ char *basename = NULL;
+ char *dir = NULL;
+ char *debugfile = NULL;
char *name_copy;
- char *canon_name;
+ char *canon_name = NULL;
bfd_size_type debuglink_size;
@@ -1384,13 +1951,14 @@ find_separate_debug_file (struct objfile
unsigned long crc32;
int i;
struct build_id *build_id;
@ -839,123 +855,34 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
xfree (build_id);
/* Prevent looping on a stripped .debug file. */
if (build_id_name != NULL && strcmp (build_id_name, objfile->name) == 0)
{
- warning (_("\"%s\": separate debug info file has no debug info"),
+ warning (_("\"%s\": The separate debug info file has no debug info"),
build_id_name);
@@ -1400,7 +1968,10 @@ find_separate_debug_file (struct objfile
xfree (build_id_name);
}
else if (build_id_name != NULL)
- return build_id_name;
+ {
+ {
+ xfree (build_id_filename);
+ return build_id_name;
+ }
}
basename = get_debug_link_info (objfile, &crc32);
@@ -1385,7 +1927,7 @@ find_separate_debug_file (struct objfile
if (basename == NULL)
/* There's no separate debug info, hence there's no way we could
load it => no warning. */
- return NULL;
+ goto cleanup_return_debugfile;
dir = xstrdup (objfile->name);
@@ -1407,24 +1949,19 @@ find_separate_debug_file (struct objfile
if (canon_name && strlen (canon_name) > i)
i = strlen (canon_name);
- debugfile = alloca (strlen (debug_file_directory) + 1
- + i
- + strlen (DEBUG_SUBDIRECTORY)
- + strlen ("/")
- + strlen (basename)
- + 1);
+ debugfile = xmalloc (strlen (debug_file_directory) + 1
+ + i
+ + strlen (DEBUG_SUBDIRECTORY)
+ + strlen ("/")
+ + strlen (basename)
+ + 1);
/* First try in the same directory as the original file. */
strcpy (debugfile, dir);
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
strcpy (debugfile, dir);
@@ -1433,12 +1970,7 @@ find_separate_debug_file (struct objfile
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* Then try in the global debugfile directory. */
strcpy (debugfile, debug_file_directory);
@@ -1447,12 +1979,7 @@ find_separate_debug_file (struct objfile
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* If the file is in the sysroot, try using its base path in the
global debugfile directory. */
@@ -1466,20 +1993,18 @@ find_separate_debug_file (struct objfile
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (canon_name);
- xfree (basename);
- xfree (dir);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
}
@@ -1501,8 +2072,10 @@ find_separate_debug_file (struct objfile
- if (canon_name)
- xfree (canon_name);
+ debugfile = NULL;
xfree (debugfile);
debugfile = NULL;
+ debug_print_missing (objfile->name, build_id_filename);
+cleanup_return_debugfile:
cleanup_return_debugfile:
+ xfree (build_id_filename);
+ xfree (canon_name);
xfree (canon_name);
xfree (basename);
xfree (dir);
- return NULL;
+ return debugfile;
}
@@ -4229,4 +4754,16 @@ the global debug-file directory prepende
@@ -4256,4 +4829,16 @@ each global debug-file-directory compone
NULL,
show_debug_file_directory,
&setlist, &showlist);
+
+
+ add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose,
+ _("\
+ Set debugging level of the build-id locator."), _("\
@ -965,13 +892,13 @@ Index: gdb-6.8.91.20090925/gdb/symfile.c
+ NULL,
+ show_build_id_verbose,
+ &setlist, &showlist);
+
+
+ observer_attach_executable_changed (debug_print_executable_changed);
}
Index: gdb-6.8.91.20090925/gdb/symfile.h
Index: gdb-7.0/gdb/symfile.h
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/symfile.h 2009-09-25 09:29:57.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/symfile.h 2009-09-25 09:29:58.000000000 +0200
--- gdb-7.0.orig/gdb/symfile.h 2009-10-23 00:12:38.000000000 +0200
+++ gdb-7.0/gdb/symfile.h 2009-10-23 00:17:29.000000000 +0200
@@ -381,6 +381,13 @@ extern int symfile_map_offsets_to_segmen
struct symfile_segment_data *get_symfile_segment_data (bfd *abfd);
void free_symfile_segment_data (struct symfile_segment_data *data);
@ -986,10 +913,10 @@ Index: gdb-6.8.91.20090925/gdb/symfile.h
/* From dwarf2read.c */
extern int dwarf2_has_info (struct objfile *);
Index: gdb-6.8.91.20090925/gdb/testsuite/lib/gdb.exp
Index: gdb-7.0/gdb/testsuite/lib/gdb.exp
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/testsuite/lib/gdb.exp 2009-09-25 09:29:57.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/testsuite/lib/gdb.exp 2009-09-25 09:29:58.000000000 +0200
--- gdb-7.0.orig/gdb/testsuite/lib/gdb.exp 2009-10-23 00:12:38.000000000 +0200
+++ gdb-7.0/gdb/testsuite/lib/gdb.exp 2009-10-23 00:17:29.000000000 +0200
@@ -1248,6 +1248,16 @@ proc default_gdb_start { } {
warning "Couldn't set the width to 0."
}
@ -1007,10 +934,10 @@ Index: gdb-6.8.91.20090925/gdb/testsuite/lib/gdb.exp
return 0;
}
Index: gdb-6.8.91.20090925/gdb/testsuite/lib/mi-support.exp
Index: gdb-7.0/gdb/testsuite/lib/mi-support.exp
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/testsuite/lib/mi-support.exp 2009-09-15 20:51:26.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/testsuite/lib/mi-support.exp 2009-09-25 09:29:58.000000000 +0200
--- gdb-7.0.orig/gdb/testsuite/lib/mi-support.exp 2009-09-15 20:51:26.000000000 +0200
+++ gdb-7.0/gdb/testsuite/lib/mi-support.exp 2009-10-23 00:17:29.000000000 +0200
@@ -221,6 +221,16 @@ proc default_mi_gdb_start { args } {
}
}
@ -1028,10 +955,10 @@ Index: gdb-6.8.91.20090925/gdb/testsuite/lib/mi-support.exp
detect_async
Index: gdb-6.8.91.20090925/gdb/objfiles.h
Index: gdb-7.0/gdb/objfiles.h
===================================================================
--- gdb-6.8.91.20090925.orig/gdb/objfiles.h 2009-09-25 09:29:57.000000000 +0200
+++ gdb-6.8.91.20090925/gdb/objfiles.h 2009-09-25 09:38:27.000000000 +0200
--- gdb-7.0.orig/gdb/objfiles.h 2009-10-23 00:12:38.000000000 +0200
+++ gdb-7.0/gdb/objfiles.h 2009-10-23 00:17:29.000000000 +0200
@@ -428,6 +428,10 @@ struct objfile
#define OBJF_MAIN (1 << 7)

View File

@ -0,0 +1,137 @@
http://sourceware.org/ml/gdb-patches/2009-10/msg00509.html
Subject: [patch 2/3] find_separate_debug_file cleanup
Hi,
current code was:
* difficult to maintain as a new variable required xfree on many places
* was causing memory corruptions due to silently misapplied 3rd party patches
as the close code fragments unfortunately match patch context
Thanks,
Jan
gdb/
2009-10-21 Jan Kratochvil <jan.kratochvil@redhat.com>
* symfile.c (find_separate_debug_file): Initialize dir, debugfile and
canon_name to NULL. Change alloca to xmalloc, newly call xfree for it.
New label cleanup_return_debugfile, jump to it from the failure paths.
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1333,11 +1333,10 @@ static char *
find_separate_debug_file (struct objfile *objfile)
{
asection *sect;
- char *basename;
- char *dir;
- char *debugfile;
- char *name_copy;
- char *canon_name;
+ char *basename, *name_copy;
+ char *dir = NULL;
+ char *debugfile = NULL;
+ char *canon_name = NULL;
bfd_size_type debuglink_size;
unsigned long crc32;
int i;
@@ -1366,7 +1365,7 @@ find_separate_debug_file (struct objfile *objfile)
if (basename == NULL)
/* There's no separate debug info, hence there's no way we could
load it => no warning. */
- return NULL;
+ goto cleanup_return_debugfile;
dir = xstrdup (objfile->name);
@@ -1388,24 +1387,19 @@ find_separate_debug_file (struct objfile *objfile)
if (canon_name && strlen (canon_name) > i)
i = strlen (canon_name);
- debugfile = alloca (strlen (debug_file_directory) + 1
- + i
- + strlen (DEBUG_SUBDIRECTORY)
- + strlen ("/")
- + strlen (basename)
- + 1);
+ debugfile = xmalloc (strlen (debug_file_directory) + 1
+ + i
+ + strlen (DEBUG_SUBDIRECTORY)
+ + strlen ("/")
+ + strlen (basename)
+ + 1);
/* First try in the same directory as the original file. */
strcpy (debugfile, dir);
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
strcpy (debugfile, dir);
@@ -1414,12 +1408,7 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* Then try in the global debugfile directory. */
strcpy (debugfile, debug_file_directory);
@@ -1428,12 +1417,7 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (basename);
- xfree (dir);
- xfree (canon_name);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
/* If the file is in the sysroot, try using its base path in the
global debugfile directory. */
@@ -1447,20 +1431,17 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- {
- xfree (canon_name);
- xfree (basename);
- xfree (dir);
- return xstrdup (debugfile);
- }
+ goto cleanup_return_debugfile;
}
- if (canon_name)
- xfree (canon_name);
+ xfree (debugfile);
+ debugfile = NULL;
+cleanup_return_debugfile:
+ xfree (canon_name);
xfree (basename);
xfree (dir);
- return NULL;
+ return debugfile;
}

View File

@ -0,0 +1,271 @@
http://sourceware.org/ml/gdb-patches/2009-10/msg00508.html
Subject: [patch 3/3] debug-file-directory with multiple components
Hi,
for various reasons `debug-file-directory' would be sometimes useful to have
multiple components such as `solib-search-path' has.
I found it useful myself during various separate debuginfo tests/scripts.
It was requested for the ABRT bugreporting project at the preceding mail of:
https://fedorahosted.org/pipermail/crash-catcher/2009-October/000054.html
It should be a backward compatible extension as DIRNAME_SEPARATOR should never
be a valid part of a single DEBUG_FILE_DIRECTORY component.
Thanks,
Jan
gdb/doc/
2009-10-22 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (set debug-file-directory, show debug-file-directory)
(Auto-loading): Use plural and note one can use multiple components now.
gdb/
2009-10-22 Jan Kratochvil <jan.kratochvil@redhat.com>
* symfile.c (build_id_to_debug_filename): New variable debugdir. Move
variables size, s and data into a new inner block. Change xmalloc for
alloca, use direct BUILDID->SIZE there now. Loop for the
DEBUG_FILE_DIRECTORY components.
(find_separate_debug_file): New variable debugdir and debugdir_end.
Loop for the DEBUG_FILE_DIRECTORY components.
(_initialize_symfile): For "debug-file-directory" use plural and note
one can use multiple components now.
gdb/testsuite/
2009-10-22 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/sepdebug.exp: New test_different_dir call for multiple-dirs.
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -14066,13 +14066,14 @@ name @value{GDBN} is currently using.
@table @code
@kindex set debug-file-directory
-@item set debug-file-directory @var{directory}
-Set the directory which @value{GDBN} searches for separate debugging
-information files to @var{directory}.
+@item set debug-file-directory @var{directories}
+Set the directories which @value{GDBN} searches for separate debugging
+information files to @var{directory}. Multiple directory components can be set
+concatenating them by a directory separator.
@kindex show debug-file-directory
@item show debug-file-directory
-Show the directory @value{GDBN} searches for separate debugging
+Show the directories @value{GDBN} searches for separate debugging
information files.
@end table
@@ -19336,8 +19337,8 @@ readable, @value{GDBN} will evaluate it as a Python script.
If this file does not exist, and if the parameter
@code{debug-file-directory} is set (@pxref{Separate Debug Files}),
-then @value{GDBN} will use the file named
-@file{@var{debug-file-directory}/@var{real-name}}, where
+then @value{GDBN} will use for its each separated directory component
+@code{component} the file named @file{@code{component}/@var{real-name}}, where
@var{real-name} is the object file's real name, as described above.
Finally, if this file does not exist, then @value{GDBN} will look for
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1218,35 +1218,59 @@ build_id_verify (const char *filename, struct build_id *check)
static char *
build_id_to_debug_filename (struct build_id *build_id)
{
- char *link, *s, *retval = NULL;
- gdb_byte *data = build_id->data;
- size_t size = build_id->size;
+ char *link, *debugdir, *retval = NULL;
/* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
- link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
- + 2 * size + (sizeof ".debug" - 1) + 1);
- s = link + sprintf (link, "%s/.build-id/", debug_file_directory);
- if (size > 0)
- {
- size--;
- s += sprintf (s, "%02x", (unsigned) *data++);
- }
- if (size > 0)
- *s++ = '/';
- while (size-- > 0)
- s += sprintf (s, "%02x", (unsigned) *data++);
- strcpy (s, ".debug");
-
- /* lrealpath() is expensive even for the usually non-existent files. */
- if (access (link, F_OK) == 0)
- retval = lrealpath (link);
- xfree (link);
-
- if (retval != NULL && !build_id_verify (retval, build_id))
+ link = alloca (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1
+ + 2 * build_id->size + (sizeof ".debug" - 1) + 1);
+
+ /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+ cause "/.build-id/..." lookups. */
+
+ debugdir = debug_file_directory;
+ do
{
- xfree (retval);
- retval = NULL;
+ char *s, *debugdir_end;
+ gdb_byte *data = build_id->data;
+ size_t size = build_id->size;
+
+ while (*debugdir == DIRNAME_SEPARATOR)
+ debugdir++;
+
+ debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
+ if (debugdir_end == NULL)
+ debugdir_end = &debugdir[strlen (debugdir)];
+
+ memcpy (link, debugdir, debugdir_end - debugdir);
+ s = &link[debugdir_end - debugdir];
+ s += sprintf (s, "/.build-id/");
+ if (size > 0)
+ {
+ size--;
+ s += sprintf (s, "%02x", (unsigned) *data++);
+ }
+ if (size > 0)
+ *s++ = '/';
+ while (size-- > 0)
+ s += sprintf (s, "%02x", (unsigned) *data++);
+ strcpy (s, ".debug");
+
+ /* lrealpath() is expensive even for the usually non-existent files. */
+ if (access (link, F_OK) == 0)
+ retval = lrealpath (link);
+
+ if (retval != NULL && !build_id_verify (retval, build_id))
+ {
+ xfree (retval);
+ retval = NULL;
+ }
+
+ if (retval != NULL)
+ break;
+
+ debugdir = debugdir_end;
}
+ while (*debugdir != 0);
return retval;
}
@@ -1333,7 +1357,7 @@ static char *
find_separate_debug_file (struct objfile *objfile)
{
asection *sect;
- char *basename, *name_copy;
+ char *basename, *name_copy, *debugdir;
char *dir = NULL;
char *debugfile = NULL;
char *canon_name = NULL;
@@ -1410,29 +1434,51 @@ find_separate_debug_file (struct objfile *objfile)
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
goto cleanup_return_debugfile;
- /* Then try in the global debugfile directory. */
- strcpy (debugfile, debug_file_directory);
- strcat (debugfile, "/");
- strcat (debugfile, dir);
- strcat (debugfile, basename);
-
- if (separate_debug_file_exists (debugfile, crc32, objfile->name))
- goto cleanup_return_debugfile;
+ /* Then try in the global debugfile directories.
+
+ Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+ cause "/..." lookups. */
- /* If the file is in the sysroot, try using its base path in the
- global debugfile directory. */
- if (canon_name
- && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
- && IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
+ debugdir = debug_file_directory;
+ do
{
- strcpy (debugfile, debug_file_directory);
- strcat (debugfile, canon_name + strlen (gdb_sysroot));
+ char *debugdir_end;
+
+ while (*debugdir == DIRNAME_SEPARATOR)
+ debugdir++;
+
+ debugdir_end = strchr (debugdir, DIRNAME_SEPARATOR);
+ if (debugdir_end == NULL)
+ debugdir_end = &debugdir[strlen (debugdir)];
+
+ memcpy (debugfile, debugdir, debugdir_end - debugdir);
+ debugfile[debugdir_end - debugdir] = 0;
strcat (debugfile, "/");
+ strcat (debugfile, dir);
strcat (debugfile, basename);
if (separate_debug_file_exists (debugfile, crc32, objfile->name))
goto cleanup_return_debugfile;
+
+ /* If the file is in the sysroot, try using its base path in the
+ global debugfile directory. */
+ if (canon_name
+ && strncmp (canon_name, gdb_sysroot, strlen (gdb_sysroot)) == 0
+ && IS_DIR_SEPARATOR (canon_name[strlen (gdb_sysroot)]))
+ {
+ memcpy (debugfile, debugdir, debugdir_end - debugdir);
+ debugfile[debugdir_end - debugdir] = 0;
+ strcat (debugfile, canon_name + strlen (gdb_sysroot));
+ strcat (debugfile, "/");
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32, objfile->name))
+ goto cleanup_return_debugfile;
+ }
+
+ debugdir = debugdir_end;
}
+ while (*debugdir != 0);
xfree (debugfile);
debugfile = NULL;
@@ -4173,12 +4219,12 @@ Usage: set extension-language .foo bar"),
add_setshow_optional_filename_cmd ("debug-file-directory", class_support,
&debug_file_directory, _("\
-Set the directory where separate debug symbols are searched for."), _("\
-Show the directory where separate debug symbols are searched for."), _("\
+Set the directories where separate debug symbols are searched for."), _("\
+Show the directories where separate debug symbols are searched for."), _("\
Separate debug symbols are first searched for in the same\n\
directory as the binary, then in the `" DEBUG_SUBDIRECTORY "' subdirectory,\n\
and lastly at the path of the directory of the binary with\n\
-the global debug-file directory prepended."),
+each global debug-file-directory component prepended."),
NULL,
show_debug_file_directory,
&setlist, &showlist);
--- a/gdb/testsuite/gdb.base/sepdebug.exp
+++ b/gdb/testsuite/gdb.base/sepdebug.exp
@@ -995,6 +995,12 @@ if ![string compare $build_id_debug_filename ""] then {
test_different_dir build-id "${objdir}/${subdir}" $xfail
+ # Test also multiple directories can be specified. Without the build-id
+ # reference GDB would find the separate debug info just at the same
+ # location as the executable file.
+
+ test_different_dir multiple-dirs "/doesnotexist:${objdir}/${subdir}" $xfail
+
# Spare debug files may confuse testsuite runs in the future.
remote_exec build "rm -f ${objdir}/${subdir}/${build_id_debug_filename}"
}

View File

@ -0,0 +1,151 @@
http://sourceware.org/ml/gdb-patches/2009-10/msg00507.html
Subject: [patch 1/3] print the .debug file name having CRC mismatch
Hi,
this patch is left as is from Andrew Cagney.
Thanks,
Jan
gdb/
2005-04-02 Andrew Cagney <cagney@gnu.org>
* symfile.c (separate_debug_file_exists): When the CRCs mismatch
print a warning.
(find_separate_debug_file): Pass in the objfile's name.
gdb/testsuite/
2009-10-21 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.base/sepdebug.exp (CRC mismatch is reported): New test.
* gdb.base/sepdebug2.c: New file.
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1283,7 +1283,8 @@ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
}
static int
-separate_debug_file_exists (const char *name, unsigned long crc)
+separate_debug_file_exists (const char *name, unsigned long crc,
+ const char *parent_name)
{
unsigned long file_crc = 0;
bfd *abfd;
@@ -1303,7 +1304,15 @@ separate_debug_file_exists (const char *name, unsigned long crc)
bfd_close (abfd);
- return crc == file_crc;
+ if (crc != file_crc)
+ {
+ warning (_("the debug information found in \"%s\""
+ " does not match \"%s\" (CRC mismatch).\n"),
+ name, parent_name);
+ return 0;
+ }
+
+ return 1;
}
char *debug_file_directory = NULL;
@@ -1355,6 +1364,8 @@ find_separate_debug_file (struct objfile *objfile)
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. */
return NULL;
dir = xstrdup (objfile->name);
@@ -1388,7 +1399,7 @@ find_separate_debug_file (struct objfile *objfile)
strcpy (debugfile, dir);
strcat (debugfile, basename);
- if (separate_debug_file_exists (debugfile, crc32))
+ if (separate_debug_file_exists (debugfile, crc32, objfile->name))
{
xfree (basename);
xfree (dir);
@@ -1402,7 +1413,7 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, "/");
strcat (debugfile, basename);
- if (separate_debug_file_exists (debugfile, crc32))
+ if (separate_debug_file_exists (debugfile, crc32, objfile->name))
{
xfree (basename);
xfree (dir);
@@ -1416,7 +1427,7 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, dir);
strcat (debugfile, basename);
- if (separate_debug_file_exists (debugfile, crc32))
+ if (separate_debug_file_exists (debugfile, crc32, objfile->name))
{
xfree (basename);
xfree (dir);
@@ -1435,7 +1446,7 @@ find_separate_debug_file (struct objfile *objfile)
strcat (debugfile, "/");
strcat (debugfile, basename);
- if (separate_debug_file_exists (debugfile, crc32))
+ if (separate_debug_file_exists (debugfile, crc32, objfile->name))
{
xfree (canon_name);
xfree (basename);
--- a/gdb/testsuite/gdb.base/sepdebug.exp
+++ b/gdb/testsuite/gdb.base/sepdebug.exp
@@ -952,6 +952,23 @@ set debugfile "${objdir}/${subdir}/${testfile}.debug"
test_different_dir debuglink "${objdir}/${subdir}" 0
+# Test CRC mismatch is reported.
+
+if {[build_executable sepdebug.exp sepdebug2 sepdebug2.c debug] != -1
+ && ![gdb_gnu_strip_debug ${objdir}/${subdir}/sepdebug2]} {
+
+ remote_exec build "cp ${debugfile} ${objdir}/${subdir}/.debug/sepdebug2.debug"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+
+ set escapedobjdirsubdir [string_to_regexp ${objdir}/${subdir}]
+
+ gdb_test "file ${objdir}/${subdir}/sepdebug2" "warning: the debug information found in \"${escapedobjdirsubdir}/\\.debug/sepdebug2\\.debug\" does not match \"${escapedobjdirsubdir}/sepdebug2\" \\(CRC mismatch\\)\\..*\\(no debugging symbols found\\).*" "CRC mismatch is reported"
+}
+
+
# NT_GNU_BUILD_ID / .note.gnu.build-id test:
set build_id_debug_filename [build_id_debug_filename_get $binfile]
--- /dev/null
+++ b/gdb/testsuite/gdb.base/sepdebug2.c
@@ -0,0 +1,22 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2009 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+int
+main (void)
+{
+ return 0;
+}

View File

@ -14,7 +14,7 @@ Version: 7.0
# The release always contains a leading reserved number, start it at 1.
# `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing.
Release: 2%{?_with_upstream:.upstream}%{?dist}
Release: 3%{?_with_upstream:.upstream}%{?dist}
License: GPLv3+
Group: Development/Debuggers
@ -125,10 +125,6 @@ Patch145: gdb-6.3-threaded-watchpoints2-20050225.patch
# Fix printing of inherited members
Patch148: gdb-6.3-inheritance-20050324.patch
# Print a warning when the separate debug info's CRC doesn't match.
Patch150: gdb-6.3-test-sepcrc-20050402.patch
Patch151: gdb-6.3-sepcrc-20050402.patch
# Do not issue warning message about first page of storage for ia64 gcore
Patch153: gdb-6.3-ia64-gcore-page0-20050421.patch
@ -370,6 +366,11 @@ Patch381: gdb-simultaneous-step-resume-breakpoint-test.patch
# Fix GNU/Linux core open: Can't read pathname for load map: Input/output error.
Patch382: gdb-core-open-vdso-warning.patch
# Support multiple directories for `set debug-file-directory' (BZ 528668).
Patch383: gdb-bz528668-symfile-sepcrc.patch
Patch384: gdb-bz528668-symfile-cleanup.patch
Patch385: gdb-bz528668-symfile-multi.patch
BuildRequires: ncurses-devel texinfo gettext flex bison expat-devel
Requires: readline
BuildRequires: readline-devel
@ -463,6 +464,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
#patch232 -p1
%patch349 -p1
%patch383 -p1
%patch384 -p1
%patch385 -p1
%patch1 -p1
%patch3 -p1
@ -483,8 +487,6 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
%patch142 -p1
%patch145 -p1
%patch148 -p1
%patch150 -p1
%patch151 -p1
%patch153 -p1
%patch157 -p1
%patch158 -p1
@ -854,6 +856,9 @@ fi
%endif
%changelog
* Thu Oct 22 2009 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.0-3
- Support multiple directories for `set debug-file-directory' (BZ 528668).
* Mon Oct 19 2009 Jan Kratochvil <jan.kratochvil@redhat.com> - 7.0-2
- Sync the .spec with RHEL/CentOS without EPEL, do not BuildRequires: fpc there.