* [patch] build-id .debug files load (like .gnu_debuglink)
@ 2007-08-24 18:05 Jan Kratochvil
2007-08-24 18:20 ` Daniel Jacobowitz
2007-08-25 22:48 ` Roland McGrath
0 siblings, 2 replies; 25+ messages in thread
From: Jan Kratochvil @ 2007-08-24 18:05 UTC (permalink / raw)
To: gdb-patches; +Cc: Roland McGrath
[-- Attachment #1: Type: text/plain, Size: 1186 bytes --]
Hi,
Patch improves performance of the separate debug info files verification as it
does not need to read and checksum the whole .debug file, it only reads its id.
This part may be questionable:
- debugfile = find_separate_debug_file (objfile);
+ /* If the file has its own symbol tables it has no separate debug info. */
+ if (objfile->psymtabs == NULL)
+ debugfile = find_separate_debug_file (objfile);
So far .gnu_debuglink existed only in the main file (not the .debug file) and
it existed only if the debug info was stripped to a separate file from it.
debug-id exists always and even both in the main file and the .debug file,
therefore the former code above would deadlock in a loop. Not sure if
`PSYMTABS == NULL' is the right condition. According to my experiments on
GNU/Linux it should be correct.
--- background:
There is now a new build-id feature since binutils-2.17.50.0.18 with section
`.note.gnu.build-id' used for finding the matching binaries for a core file.
http://fedoraproject.org/wiki/RolandMcGrath/BuildID
Patch uses the recently approved BFD `.note.gnu.build-id' parsing:
http://sourceware.org/ml/binutils/2007-08/msg00296.html
Regards,
Jan
[-- Attachment #2: gdb-buildid-verify0.patch --]
[-- Type: text/plain, Size: 15954 bytes --]
2007-08-24 Jan Kratochvil <jan.kratochvil@redhat.com>
* Makefile.in (symfile.o): Update dependencies.
* symfile.c (symbol_file_add_with_addrs_or_offsets): Initialize the
DEBUGFILE variable. FIND_SEPARATE_DEBUG_FILE called only if !PSYMTABS.
(struct build_id): New structure.
(build_id_bfd_shdr_get, build_id_verify, build_id_to_filename): New.
(find_separate_debug_file): New variable BUILD_ID.
Call BUILD_ID_BFD_SHDR_GET with BUILD_ID_TO_FILENAME as the first try.
2007-08-24 Jan Kratochvil <jan.kratochvil@redhat.com>
* lib/gdb.exp (build_id_debug_filename_get): New function.
* gdb.base/sepdebug.exp: Reflect the changes in the heading comment.
Remove the generate DEBUG file for the future testcase runs.
New testcase for the NT_GNU_BUILD_ID retrieval.
Move the final testing step to ...
(test_different_dir): ... a new function.
New parameter XFAIL to XFAIL all the tests performed.
New parameter TEST_DIFFERENT_DIR parametrizing the directory.
New parameter TYPE to PF_PREFIX all the tests performed.
--- gdb/Makefile.in 23 Aug 2007 20:33:48 -0000 1.929
+++ gdb/Makefile.in 24 Aug 2007 17:48:06 -0000
@@ -2731,7 +2731,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink
$(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \
$(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \
$(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \
- $(parser_defs_h) $(varobj_h)
+ $(parser_defs_h) $(varobj_h) $(elf_bfd_h)
symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \
$(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \
$(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h)
--- gdb/symfile.c 23 Aug 2007 18:08:39 -0000 1.190
+++ gdb/symfile.c 24 Aug 2007 17:48:07 -0000
@@ -51,6 +51,7 @@
#include "exec.h"
#include "parser-defs.h"
#include "varobj.h"
+#include "elf-bfd.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -1017,7 +1018,7 @@ symbol_file_add_with_addrs_or_offsets (b
{
struct objfile *objfile;
struct partial_symtab *psymtab;
- char *debugfile;
+ char *debugfile = NULL;
struct section_addr_info *orig_addrs = NULL;
struct cleanup *my_cleanups;
const char *name = bfd_get_filename (abfd);
@@ -1081,7 +1082,9 @@ symbol_file_add_with_addrs_or_offsets (b
}
}
- debugfile = find_separate_debug_file (objfile);
+ /* If the file has its own symbol tables it has no separate debug info. */
+ if (objfile->psymtabs == NULL)
+ debugfile = find_separate_debug_file (objfile);
if (debugfile)
{
if (addrs != NULL)
@@ -1223,6 +1226,103 @@ symbol_file_clear (int from_tty)
printf_unfiltered (_("No symbol file now.\n"));
}
+struct build_id
+ {
+ size_t size;
+ gdb_byte data[1];
+ };
+
+/* Locate NT_GNU_BUILD_ID and return its content.
+ Separate debuginfo files have corrupted PHDR but SHDR is correct there. */
+
+static struct build_id *
+build_id_bfd_shdr_get (bfd *abfd)
+{
+ struct build_id *retval;
+
+ if (!bfd_check_format (abfd, bfd_object)
+ || bfd_get_flavour (abfd) != bfd_target_elf_flavour
+ || elf_tdata (abfd)->build_id == NULL)
+ return NULL;
+
+ retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size);
+ retval->size = elf_tdata (abfd)->build_id_size;
+ memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size);
+
+ return retval;
+}
+
+/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */
+
+static int
+build_id_verify (const char *filename, struct build_id *check)
+{
+ bfd *abfd;
+ struct build_id *found = NULL;
+ int retval = 0;
+
+ /* We expect to be silent on the non-existing files. */
+ abfd = bfd_openr (filename, gnutarget);
+ if (abfd == NULL)
+ return 0;
+
+ found = build_id_bfd_shdr_get (abfd);
+
+ if (found == NULL)
+ warning (_("File \"%s\" has no build-id, file skipped"), filename);
+ else if (found->size != check->size
+ || memcmp (found->data, check->data, found->size) != 0)
+ warning (_("File \"%s\" has a different build-id, file skipped"), filename);
+ else
+ retval = 1;
+
+ if (!bfd_close (abfd))
+ warning (_("cannot close \"%s\": %s"), filename,
+ bfd_errmsg (bfd_get_error ()));
+ return retval;
+}
+
+static char *
+build_id_to_filename (struct build_id *build_id, int add_debug_suffix)
+{
+ char *link, *s, *retval = NULL;
+ gdb_byte *data = build_id->data;
+ size_t size = build_id->size;
+
+ /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */
+ link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 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)
+ {
+ size--;
+ s += sprintf (s, "%02x", (unsigned) *data++);
+ }
+ if (size > 0)
+ *s++ = '/';
+ while (size-- > 0)
+ s += sprintf (s, "%02x", (unsigned) *data++);
+ if (add_debug_suffix)
+ strcpy (s, ".debug");
+ else
+ *s = 0;
+
+ /* 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))
+ {
+ xfree (retval);
+ retval = NULL;
+ }
+
+ return retval;
+}
+
static char *
get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
{
@@ -1300,6 +1400,18 @@ find_separate_debug_file (struct objfile
bfd_size_type debuglink_size;
unsigned long crc32;
int i;
+ struct build_id *build_id;
+
+ build_id = build_id_bfd_shdr_get (objfile->obfd);
+ if (build_id != NULL)
+ {
+ char *build_id_name;
+
+ build_id_name = build_id_to_filename (build_id, 1);
+ free (build_id);
+ if (build_id_name != NULL)
+ return build_id_name;
+ }
basename = get_debug_link_info (objfile, &crc32);
--- gdb/testsuite/gdb.base/sepdebug.exp 23 Aug 2007 18:14:17 -0000 1.8
+++ gdb/testsuite/gdb.base/sepdebug.exp 24 Aug 2007 17:48:08 -0000
@@ -19,11 +19,14 @@
# Based on break.exp, written by Rob Savoye. (rob@cygnus.com)
# Modified to test gdb's handling of separate debug info files.
+# Modified to test gdb's handling of a debug-id retrieval.
# This file has two parts. The first is testing that gdb behaves
# normally after reading in an executable and its corresponding
# separate debug file. The second moves the .debug file to a different
# location and tests the "set debug-file-directory" command.
+# The third is for testing build-id retrievel by finding the separate
+# ".debug-id/ab/cdef.debug" file.
if $tracelevel then {
@@ -828,93 +831,152 @@ test_next_with_recursion
#********
-# now move the .debug file to a different location so that we can test
-# the "set debug-file-directory" command.
-
-remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
-gdb_exit
-gdb_start
-gdb_reinitialize_dir $srcdir/$subdir
-gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location"
-gdb_load ${binfile}
+proc test_different_dir {type test_different_dir xfail} {
+ global srcdir subdir objdir binfile srcfile timeout gdb_prompt
+ global pf_prefix
+ global bp_location6 decimal hex
+
+ set pf_prefix "$type:"
+
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_test "set debug-file-directory ${test_different_dir}" ".*" "set separate debug location"
+ gdb_load ${binfile}
-if [target_info exists gdb_stub] {
- gdb_step_for_stub;
-}
+ if [target_info exists gdb_stub] {
+ gdb_step_for_stub;
+ }
-#
-# test break at function
-#
-gdb_test "break main" \
- "Breakpoint.*at.* file .*$srcfile, line.*" \
- "breakpoint function, optimized file"
+ #
+ # test break at function
+ #
+ if {$xfail} {
+ setup_xfail "*-*-*"
+ }
+ gdb_test "break main" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint function, optimized file"
-#
-# test break at function
-#
-gdb_test "break marker4" \
- "Breakpoint.*at.* file .*$srcfile, line.*" \
- "breakpoint small function, optimized file"
+ #
+ # test break at function
+ #
+ if {$xfail} {
+ setup_xfail "*-*-*"
+ }
+ gdb_test "break marker4" \
+ "Breakpoint.*at.* file .*$srcfile, line.*" \
+ "breakpoint small function, optimized file"
-#
-# run until the breakpoint at main is hit. For non-stubs-using targets.
-#
-gdb_run_cmd
-gdb_expect {
- -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" {
- pass "run until function breakpoint, optimized file"
+ #
+ # run until the breakpoint at main is hit. For non-stubs-using targets.
+ #
+ gdb_run_cmd
+ if {$xfail} {
+ setup_xfail "*-*-*"
}
- -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" {
- pass "run until function breakpoint, optimized file (code motion)"
+ gdb_expect {
+ -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" {
+ pass "run until function breakpoint, optimized file"
+ }
+ -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" {
+ pass "run until function breakpoint, optimized file (code motion)"
+ }
+ -re "$gdb_prompt $" {
+ fail "run until function breakpoint, optimized file"
+ }
+ timeout {
+ fail "run until function breakpoint, optimized file (timeout)"
+ }
}
- -re "$gdb_prompt $" {
- fail "run until function breakpoint, optimized file"
+
+ #
+ # run until the breakpoint at a small function
+ #
+
+ #
+ # Add a second pass pattern. The behavior differs here between stabs
+ # and dwarf for one-line functions. Stabs preserves two line symbols
+ # (one before the prologue and one after) with the same line number,
+ # but dwarf regards these as duplicates and discards one of them.
+ # Therefore the address after the prologue (where the breakpoint is)
+ # has no exactly matching line symbol, and GDB reports the breakpoint
+ # as if it were in the middle of a line rather than at the beginning.
+
+ set bp_location13 [gdb_get_line_number "set breakpoint 13 here"]
+ set bp_location14 [gdb_get_line_number "set breakpoint 14 here"]
+ send_gdb "continue\n"
+ if {$xfail} {
+ setup_xfail "*-*-*"
}
- timeout {
- fail "run until function breakpoint, optimized file (timeout)"
+ gdb_expect {
+ -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
+ pass "run until breakpoint set at small function, optimized file"
+ }
+ -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
+ pass "run until breakpoint set at small function, optimized file"
+ }
+ -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
+ # marker4() is defined at line 46 when compiled with -DPROTOTYPES
+ pass "run until breakpoint set at small function, optimized file (line bp_location14)"
+ }
+ -re ".*$gdb_prompt " {
+ fail "run until breakpoint set at small function, optimized file"
+ }
+ timeout {
+ fail "run until breakpoint set at small function, optimized file (timeout)"
+ }
+ }
+
+
+ # Reset the default arguments for VxWorks
+ if [istarget "*-*-vxworks*"] {
+ set timeout 10
+ verbose "Timeout is now $timeout seconds" 2
+ send_gdb "set args main\n"
+ gdb_expect -re ".*$gdb_prompt $" {}
}
+
+ unset pf_prefix
+# proc test_different_dir
}
-#
-# run until the breakpoint at a small function
-#
-#
-# Add a second pass pattern. The behavior differs here between stabs
-# and dwarf for one-line functions. Stabs preserves two line symbols
-# (one before the prologue and one after) with the same line number,
-# but dwarf regards these as duplicates and discards one of them.
-# Therefore the address after the prologue (where the breakpoint is)
-# has no exactly matching line symbol, and GDB reports the breakpoint
-# as if it were in the middle of a line rather than at the beginning.
+# now move the .debug file to a different location so that we can test
+# the "set debug-file-directory" command.
+
+remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}"
+set debugfile "${objdir}/${subdir}/${testfile}.debug"
-set bp_location13 [gdb_get_line_number "set breakpoint 13 here"]
-set bp_location14 [gdb_get_line_number "set breakpoint 14 here"]
-send_gdb "continue\n"
-gdb_expect {
- -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
- pass "run until breakpoint set at small function, optimized file"
- }
- -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" {
- pass "run until breakpoint set at small function, optimized file"
- }
- -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" {
- # marker4() is defined at line 46 when compiled with -DPROTOTYPES
- pass "run until breakpoint set at small function, optimized file (line bp_location14)"
- }
- -re ".*$gdb_prompt " {
- fail "run until breakpoint set at small function, optimized file"
- }
- timeout {
- fail "run until breakpoint set at small function, optimized file (timeout)"
+test_different_dir debuglink "${objdir}/${subdir}" 0
+
+
+# NT_GNU_BUILD_ID / .note.gnu.build-id test:
+
+set build_id_debug_filename [build_id_debug_filename_get $binfile]
+if {$build_id_debug_filename eq ""} {
+ unsupported "build-id is not supported by the compiler"
+
+ # Spare debug files may confuse testsuite runs in the future.
+ remote_exec build "rm -f $debugfile"
+} else {
+ set build_id_debugself_filename [build_id_debug_filename_get $debugfile]
+ set test "build-id support by binutils"
+ set xfail 0
+ if {$build_id_debugself_filename eq ""} {
+ unsupported $test
+ set xfail 1
+ } elseif {$build_id_debugself_filename ne $build_id_debug_filename} {
+ fail $test
+ } else {
+ pass $test
}
-}
+ file mkdir [file dirname ${objdir}/${subdir}/${build_id_debug_filename}]
+ remote_exec build "mv $debugfile ${objdir}/${subdir}/${build_id_debug_filename}"
+
+ test_different_dir build-id "${objdir}/${subdir}" $xfail
-# Reset the default arguments for VxWorks
-if [istarget "*-*-vxworks*"] {
- set timeout 10
- verbose "Timeout is now $timeout seconds" 2
- send_gdb "set args main\n"
- gdb_expect -re ".*$gdb_prompt $" {}
+ # Spare debug files may confuse testsuite runs in the future.
+ remote_exec build "rm -f ${objdir}/${subdir}/${build_id_debug_filename}"
}
--- gdb/testsuite/lib/gdb.exp 23 Aug 2007 20:10:04 -0000 1.86
+++ gdb/testsuite/lib/gdb.exp 24 Aug 2007 17:48:08 -0000
@@ -2482,6 +2482,27 @@ proc separate_debug_filename { exec } {
return $debug_file
}
+# Return the build-id hex string (usually 160 bits as 40 hex characters)
+# converted to the form: .build-id/ab/cdef1234...89.debug
+# Return "" if no build-id found.
+proc build_id_debug_filename_get { exec } {
+ set tmp "${exec}-tmp"
+ exec objcopy -j .note.gnu.build-id -O binary $exec $tmp
+ set fi [open $tmp]
+ # Skip the NOTE header.
+ read $fi 16
+ set data [read $fi]
+ close $fi
+ file delete $tmp
+ if {$data eq ""} {
+ return ""
+ }
+ # Convert it to hex.
+ binary scan $data H* data
+ set data [regsub {^..} $data {\0/}]
+ return ".build-id/${data}.debug";
+}
+
# Create stripped files for DEST, replacing it. If ARGS is passed, it is a
# list of optional flags. The only currently supported flag is no-main,
# which removes the symbol entry for main from the separate debug file.
^ permalink raw reply [flat|nested] 25+ messages in thread* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-24 18:05 [patch] build-id .debug files load (like .gnu_debuglink) Jan Kratochvil @ 2007-08-24 18:20 ` Daniel Jacobowitz 2007-08-25 22:49 ` Jan Kratochvil 2007-08-25 22:48 ` Roland McGrath 1 sibling, 1 reply; 25+ messages in thread From: Daniel Jacobowitz @ 2007-08-24 18:20 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Roland McGrath On Fri, Aug 24, 2007 at 08:04:50PM +0200, Jan Kratochvil wrote: > Hi, > > Patch improves performance of the separate debug info files verification as it > does not need to read and checksum the whole .debug file, it only reads its id. > > This part may be questionable: > - debugfile = find_separate_debug_file (objfile); > + /* If the file has its own symbol tables it has no separate debug info. */ > + if (objfile->psymtabs == NULL) > + debugfile = find_separate_debug_file (objfile); > > So far .gnu_debuglink existed only in the main file (not the .debug file) and > it existed only if the debug info was stripped to a separate file from it. > debug-id exists always and even both in the main file and the .debug file, > therefore the former code above would deadlock in a loop. Not sure if > `PSYMTABS == NULL' is the right condition. According to my experiments on > GNU/Linux it should be correct. In some cases a library will be left with .symtab but not .debug_info; sometimes elfutils does this, also sometimes it is done deliberately for ld.so / libpthread.so so that the separate debug file is not necessary for minimal debugging to work. We should either pass a flag down so that we know we're already looking at the separate debug file (more efficient, saves us the second search, more work to implement) or else have find_separate_debug_file fail if it finds objfile again. > +/* Locate NT_GNU_BUILD_ID and return its content. > + Separate debuginfo files have corrupted PHDR but SHDR is correct there. */ > + > +static struct build_id * > +build_id_bfd_shdr_get (bfd *abfd) > +{ > + struct build_id *retval; > + > + if (!bfd_check_format (abfd, bfd_object) > + || bfd_get_flavour (abfd) != bfd_target_elf_flavour > + || elf_tdata (abfd)->build_id == NULL) > + return NULL; > + > + retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size); > + retval->size = elf_tdata (abfd)->build_id_size; > + memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size); > + > + return retval; > +} This function isn't doing anything with program headers or section headers now, maybe it should be renamed (and the comment doesn't need to talk about corrupted phdrs in that case). I believe the manual needs an update to mention the new search path. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-24 18:20 ` Daniel Jacobowitz @ 2007-08-25 22:49 ` Jan Kratochvil 2007-08-25 23:58 ` Daniel Jacobowitz 0 siblings, 1 reply; 25+ messages in thread From: Jan Kratochvil @ 2007-08-25 22:49 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Roland McGrath [-- Attachment #1: Type: text/plain, Size: 3119 bytes --] On Fri, 24 Aug 2007 20:20:28 +0200, Daniel Jacobowitz wrote: > On Fri, Aug 24, 2007 at 08:04:50PM +0200, Jan Kratochvil wrote: ... > > This part may be questionable: > > - debugfile = find_separate_debug_file (objfile); > > + /* If the file has its own symbol tables it has no separate debug info. */ > > + if (objfile->psymtabs == NULL) > > + debugfile = find_separate_debug_file (objfile); ... > > Not sure if `PSYMTABS == NULL' is the right condition. According to my > > experiments on GNU/Linux it should be correct. > > In some cases a library will be left with .symtab but not .debug_info; > sometimes elfutils does this, also sometimes it is done deliberately > for ld.so / libpthread.so so that the separate debug file is not > necessary for minimal debugging to work. You are right about the content of `/lib64/ld-linux-x86-64.so.2'. Still in such case both `.dynsym' and `.symtab' gets read into MSYMBOLS but PSYMTABS and SYMTABS are left forever NULL for the main executable (as there is no .debug_info). While I would still expect the former patch was right I changed it according to your advice. It is definitely the safe way but with a tiny performance hit: The reason of my check was that build-id (contrary to the debug-link) is always present there, even for locally built unsplit files. With the patch attached below GDB will try to open a separate debug file in /usr/lib/debug/.debug-id/ even for the unsplit files. This step did not happen with my former patch. > We should either pass a flag down so that we know we're already > looking at the separate debug file (more efficient, saves us the > second search, more work to implement) Chose this way as the intention of the whole patch is performance. (Aware OBJF_DEBUG_FILE is not an OBJFILE flag - just an additional SYMBOL_FILE_ADD_WITH_ADDRS_OR_OFFSETS parameter - but it may get one day useful for later retrieval from OBJFILE.) > > +/* Locate NT_GNU_BUILD_ID and return its content. > > + Separate debuginfo files have corrupted PHDR but SHDR is correct there. */ > > + > > +static struct build_id * > > +build_id_bfd_shdr_get (bfd *abfd) > > +{ > > + struct build_id *retval; > > + > > + if (!bfd_check_format (abfd, bfd_object) > > + || bfd_get_flavour (abfd) != bfd_target_elf_flavour > > + || elf_tdata (abfd)->build_id == NULL) > > + return NULL; > > + > > + retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size); > > + retval->size = elf_tdata (abfd)->build_id_size; > > + memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size); > > + > > + return retval; > > +} > > This function isn't doing anything with program headers or section > headers now, maybe it should be renamed (and the comment doesn't need > to talk about corrupted phdrs in that case). Not agreed as the PHDR<->SHDR difference is important (there are issues about it for readelf/eu-readelf - whether PHDR or SHDR should be chosen there). But changed according to your advice. > I believe the manual needs an update to mention the new search path. I see now, sorry, implemented. Thanks, Jan [-- Attachment #2: gdb-buildid-verify1.patch --] [-- Type: text/plain, Size: 23673 bytes --] 2007-08-25 Jan Kratochvil <jan.kratochvil@redhat.com> * Makefile.in (symfile.o): Update dependencies. * objfiles.h (OBJF_DEBUG_FILE): New definition. * symfile.c (symbol_file_add_with_addrs_or_offsets): Initialize the DEBUGFILE variable. FIND_SEPARATE_DEBUG_FILE protected against loop by setting OBJF_DEBUG_FILE for the first call. (struct build_id): New structure. (build_id_bfd_get, build_id_verify, build_id_to_debug_filename): New. (find_separate_debug_file): New variable BUILD_ID. Call BUILD_ID_BFD_GET with BUILD_ID_TO_DEBUG_FILENAME as the first try. 2007-08-25 Jan Kratochvil <jan.kratochvil@redhat.com> * lib/gdb.exp (build_id_debug_filename_get): New function. * gdb.base/sepdebug.exp: Reflect the changes in the heading comment. Remove the generate DEBUG file for the future testcase runs. New testcase for the NT_GNU_BUILD_ID retrieval. Move the final testing step to ... (test_different_dir): ... a new function. New parameter XFAIL to XFAIL all the tests performed. New parameter TEST_DIFFERENT_DIR parametrizing the directory. New parameter TYPE to PF_PREFIX all the tests performed. 2007-08-25 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Separate Debug Files): Included a BUILD ID description. Enlisted BUILD ID to the debug file searching example. Included a BUILD ID `.note.gnu.build-id' section description. Updated/added the debug files splitting instructions for OBJCOPY. --- gdb/Makefile.in 23 Aug 2007 20:33:48 -0000 1.929 +++ gdb/Makefile.in 25 Aug 2007 22:43:21 -0000 @@ -2731,7 +2731,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink $(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \ $(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \ $(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \ - $(parser_defs_h) $(varobj_h) + $(parser_defs_h) $(varobj_h) $(elf_bfd_h) symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \ $(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \ $(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h) --- gdb/objfiles.h 23 Aug 2007 18:08:36 -0000 1.46 +++ gdb/objfiles.h 25 Aug 2007 22:43:21 -0000 @@ -448,6 +448,11 @@ struct objfile #define OBJF_USERLOADED (1 << 5) /* User loaded */ +/* We should not try to find by build-id the separate debug info file for the + same separate debug info file itself. */ + +#define OBJF_DEBUG_FILE (1 << 6) /* Separate debug file */ + /* The object file that the main symbol table was loaded from (e.g. the argument to the "symbol-file" or "file" command). */ --- gdb/symfile.c 23 Aug 2007 18:08:39 -0000 1.190 +++ gdb/symfile.c 25 Aug 2007 22:43:21 -0000 @@ -51,6 +51,7 @@ #include "exec.h" #include "parser-defs.h" #include "varobj.h" +#include "elf-bfd.h" #include <sys/types.h> #include <fcntl.h> @@ -1017,7 +1018,7 @@ symbol_file_add_with_addrs_or_offsets (b { struct objfile *objfile; struct partial_symtab *psymtab; - char *debugfile; + char *debugfile = NULL; struct section_addr_info *orig_addrs = NULL; struct cleanup *my_cleanups; const char *name = bfd_get_filename (abfd); @@ -1081,18 +1082,21 @@ symbol_file_add_with_addrs_or_offsets (b } } - debugfile = find_separate_debug_file (objfile); + if (!(flags & OBJF_DEBUG_FILE)) + debugfile = find_separate_debug_file (objfile); if (debugfile) { if (addrs != NULL) { objfile->separate_debug_objfile - = symbol_file_add (debugfile, from_tty, orig_addrs, 0, flags); + = symbol_file_add (debugfile, from_tty, orig_addrs, 0, + flags | OBJF_DEBUG_FILE); } else { objfile->separate_debug_objfile - = symbol_file_add (debugfile, from_tty, NULL, 0, flags); + = symbol_file_add (debugfile, from_tty, NULL, 0, + flags | OBJF_DEBUG_FILE); } objfile->separate_debug_objfile->separate_debug_objfile_backlink = objfile; @@ -1223,6 +1227,97 @@ symbol_file_clear (int from_tty) printf_unfiltered (_("No symbol file now.\n")); } +struct build_id + { + size_t size; + gdb_byte data[1]; + }; + +/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ + +static struct build_id * +build_id_bfd_get (bfd *abfd) +{ + struct build_id *retval; + + if (!bfd_check_format (abfd, bfd_object) + || bfd_get_flavour (abfd) != bfd_target_elf_flavour + || elf_tdata (abfd)->build_id == NULL) + return NULL; + + retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size); + retval->size = elf_tdata (abfd)->build_id_size; + memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size); + + return retval; +} + +/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */ + +static int +build_id_verify (const char *filename, struct build_id *check) +{ + bfd *abfd; + struct build_id *found = NULL; + int retval = 0; + + /* We expect to be silent on the non-existing files. */ + abfd = bfd_openr (filename, gnutarget); + if (abfd == NULL) + return 0; + + found = build_id_bfd_get (abfd); + + if (found == NULL) + warning (_("File \"%s\" has no build-id, file skipped"), filename); + else if (found->size != check->size + || memcmp (found->data, check->data, found->size) != 0) + warning (_("File \"%s\" has a different build-id, file skipped"), filename); + else + retval = 1; + + if (!bfd_close (abfd)) + warning (_("cannot close \"%s\": %s"), filename, + bfd_errmsg (bfd_get_error ())); + return retval; +} + +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; + + /* 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)) + { + xfree (retval); + retval = NULL; + } + + return retval; +} + static char * get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) { @@ -1300,6 +1395,18 @@ find_separate_debug_file (struct objfile bfd_size_type debuglink_size; unsigned long crc32; int i; + struct build_id *build_id; + + build_id = build_id_bfd_get (objfile->obfd); + if (build_id != NULL) + { + char *build_id_name; + + build_id_name = build_id_to_debug_filename (build_id); + free (build_id); + if (build_id_name != NULL) + return build_id_name; + } basename = get_debug_link_info (objfile, &crc32); --- gdb/doc/gdb.texinfo 21 Aug 2007 15:09:59 -0000 1.423 +++ gdb/doc/gdb.texinfo 25 Aug 2007 22:43:31 -0000 @@ -11902,18 +11902,32 @@ than the executable code itself --- some information for their executables in separate files, which users can install only when they need to debug a problem. -If an executable's debugging information has been extracted to a -separate file, the executable should contain a @dfn{debug link} giving -the name of the debugging information file (with no directory -components), and a checksum of its contents. (The exact form of a -debug link is described below.) If the full name of the directory -containing the executable is @var{execdir}, and the executable has a -debug link that specifies the name @var{debugfile}, then @value{GDBN} -will automatically search for the debugging information file in three -places: +There are two identificators how the separate debug file may be found: @itemize @bullet @item +@dfn{debug link} is present only in the executable if its debug information has +been split out. It is not present in the separate debug file. It provides the +separate debug file filename, usually as @file{executable.debug}. +@item +@dfn{build id} is present in all the files (if the operating system supports +it). The executable file and its separate debug file have the same unique +@dfn{build id} content. +@end itemize + +If the full name of the directory containing the executable is @var{execdir}, +the executable has a debug link that specifies the name @var{debugfile}, +@var{bu} is the first byte (two hexadecimal characters) of the build id +content, @var{ild-id} are the remaining bytes / hexadecimal characters and +@var{globaldebugdir} is the global debug file directory then @value{GDBN} will +automatically search for the debugging information file in four places: + +@itemize @bullet +@item +a specific file in the subdirectory of the global debug file directory +according to the @dfn{build id} content (if present), the file tried is +@file{@var{globaldebugdir}/.debug-id/@var{bu}/@var{ild-id}.debug}. +@item the directory containing the executable file (that is, it will look for a file named @file{@var{execdir}/@var{debugfile}}, @item @@ -11928,15 +11942,17 @@ executable's full path, and the name fro @end itemize @noindent @value{GDBN} checks under each of these names for a debugging -information file whose checksum matches that given in the link, and -reads the debugging information from the first one it finds. - -So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, -which has a link containing the name @file{ls.debug}, and the global -debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look -for debug information in @file{/usr/bin/ls.debug}, -@file{/usr/bin/.debug/ls.debug}, and -@file{/usr/lib/debug/usr/bin/ls.debug}. +information file with build id content matching the build id content of the +executable file - or - whose checksum matches the one given in the link in the +debug link case. In each case @value{GDBN} reads the debugging information +from the first debug file it finds. + +So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, which has +a @dfn{debug link} containing the name @file{ls.debug}, its @dfn{build id} +value in hexadecimal is @code{abcdef} and the global debug directory is +@file{/usr/lib/debug}, then @value{GDBN} will look for debug information in +@file{/usr/lib/debug/.build-id/ab/cdef.debug}, @file{/usr/bin/ls.debug}, +@file{/usr/bin/.debug/ls.debug}, and @file{/usr/lib/debug/usr/bin/ls.debug}. You can set the global debugging info directory's name, and view the name @value{GDBN} is currently using. @@ -11978,6 +11994,16 @@ Any executable file format can carry a d contain a section named @code{.gnu_debuglink} with the contents described above. +@cindex @code{.note.gnu.build-id} sections +@cindex build id +Build id is a special section of the executable file named +@code{.note.gnu.build-id}. The section contains unique identification hash +derived from the built files - it remains the same across multiple builds of +the same build tree. The default algorithm SHA1 produces 160 bits (40 +hexadecimal characters) of the content. The same section and value is present +in the original built binary with symbols, in its stripped variant and in the +separate debug information file. + The debugging information file itself should be an ordinary executable, containing a full set of linker symbols, sections, and debugging information. The sections of the debugging information file @@ -11985,18 +12011,21 @@ should have the same names, addresses an but they need not contain any data --- much like a @code{.bss} section in an ordinary executable. -As of December 2002, there is no standard GNU utility to produce -separated executable / debugging information file pairs. Ulrich -Drepper's @file{elfutils} package, starting with version 0.53, -contains a version of the @code{strip} command such that the command -@kbd{strip foo -f foo.debug} removes the debugging information from -the executable file @file{foo}, places it in the file -@file{foo.debug}, and leaves behind a debug link in @file{foo}. - -Since there are many different ways to compute CRC's (different -polynomials, reversals, byte ordering, etc.), the simplest way to -describe the CRC used in @code{.gnu_debuglink} sections is to give the -complete code for a function that computes it: +@sc{gnu} binary utilities contain the @samp{objcopy} utility able to produce +the separated executable / debugging information file pairs by commands +@kbd{objcopy --only-keep-debug foo foo.debug; strip -g foo; objcopy +--add-gnu-debuglink="foo.debug" "foo"}. These commands remove the debugging +information from the executable file @file{foo}, place it in the file +@file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich +Drepper's @file{elfutils} package, starting with version 0.53, contains +a version of the @code{strip} command such that the command @kbd{strip foo -f +foo.debug} has the same functionality as the three commands above. + +Since there are many different ways to compute CRC's for the debug link +(different polynomials, reversals, byte ordering, etc.). This computation does +not apply to the build id section. The simplest way to describe the CRC used +in @code{.gnu_debuglink} sections is to give the complete code for a function +that computes it: @kindex gnu_debuglink_crc32 @smallexample --- gdb/testsuite/gdb.base/sepdebug.exp 23 Aug 2007 18:14:17 -0000 1.8 +++ gdb/testsuite/gdb.base/sepdebug.exp 25 Aug 2007 22:43:31 -0000 @@ -19,11 +19,14 @@ # Based on break.exp, written by Rob Savoye. (rob@cygnus.com) # Modified to test gdb's handling of separate debug info files. +# Modified to test gdb's handling of a debug-id retrieval. # This file has two parts. The first is testing that gdb behaves # normally after reading in an executable and its corresponding # separate debug file. The second moves the .debug file to a different # location and tests the "set debug-file-directory" command. +# The third is for testing build-id retrievel by finding the separate +# ".debug-id/ab/cdef.debug" file. if $tracelevel then { @@ -828,93 +831,152 @@ test_next_with_recursion #******** -# now move the .debug file to a different location so that we can test -# the "set debug-file-directory" command. - -remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}" -gdb_exit -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location" -gdb_load ${binfile} +proc test_different_dir {type test_different_dir xfail} { + global srcdir subdir objdir binfile srcfile timeout gdb_prompt + global pf_prefix + global bp_location6 decimal hex + + set pf_prefix "$type:" + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_test "set debug-file-directory ${test_different_dir}" ".*" "set separate debug location" + gdb_load ${binfile} -if [target_info exists gdb_stub] { - gdb_step_for_stub; -} + if [target_info exists gdb_stub] { + gdb_step_for_stub; + } -# -# test break at function -# -gdb_test "break main" \ - "Breakpoint.*at.* file .*$srcfile, line.*" \ - "breakpoint function, optimized file" + # + # test break at function + # + if {$xfail} { + setup_xfail "*-*-*" + } + gdb_test "break main" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function, optimized file" -# -# test break at function -# -gdb_test "break marker4" \ - "Breakpoint.*at.* file .*$srcfile, line.*" \ - "breakpoint small function, optimized file" + # + # test break at function + # + if {$xfail} { + setup_xfail "*-*-*" + } + gdb_test "break marker4" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint small function, optimized file" -# -# run until the breakpoint at main is hit. For non-stubs-using targets. -# -gdb_run_cmd -gdb_expect { - -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" { - pass "run until function breakpoint, optimized file" + # + # run until the breakpoint at main is hit. For non-stubs-using targets. + # + gdb_run_cmd + if {$xfail} { + setup_xfail "*-*-*" } - -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" { - pass "run until function breakpoint, optimized file (code motion)" + gdb_expect { + -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" { + pass "run until function breakpoint, optimized file" + } + -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" { + pass "run until function breakpoint, optimized file (code motion)" + } + -re "$gdb_prompt $" { + fail "run until function breakpoint, optimized file" + } + timeout { + fail "run until function breakpoint, optimized file (timeout)" + } } - -re "$gdb_prompt $" { - fail "run until function breakpoint, optimized file" + + # + # run until the breakpoint at a small function + # + + # + # Add a second pass pattern. The behavior differs here between stabs + # and dwarf for one-line functions. Stabs preserves two line symbols + # (one before the prologue and one after) with the same line number, + # but dwarf regards these as duplicates and discards one of them. + # Therefore the address after the prologue (where the breakpoint is) + # has no exactly matching line symbol, and GDB reports the breakpoint + # as if it were in the middle of a line rather than at the beginning. + + set bp_location13 [gdb_get_line_number "set breakpoint 13 here"] + set bp_location14 [gdb_get_line_number "set breakpoint 14 here"] + send_gdb "continue\n" + if {$xfail} { + setup_xfail "*-*-*" } - timeout { - fail "run until function breakpoint, optimized file (timeout)" + gdb_expect { + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" { + # marker4() is defined at line 46 when compiled with -DPROTOTYPES + pass "run until breakpoint set at small function, optimized file (line bp_location14)" + } + -re ".*$gdb_prompt " { + fail "run until breakpoint set at small function, optimized file" + } + timeout { + fail "run until breakpoint set at small function, optimized file (timeout)" + } + } + + + # Reset the default arguments for VxWorks + if [istarget "*-*-vxworks*"] { + set timeout 10 + verbose "Timeout is now $timeout seconds" 2 + send_gdb "set args main\n" + gdb_expect -re ".*$gdb_prompt $" {} } + + unset pf_prefix +# proc test_different_dir } -# -# run until the breakpoint at a small function -# -# -# Add a second pass pattern. The behavior differs here between stabs -# and dwarf for one-line functions. Stabs preserves two line symbols -# (one before the prologue and one after) with the same line number, -# but dwarf regards these as duplicates and discards one of them. -# Therefore the address after the prologue (where the breakpoint is) -# has no exactly matching line symbol, and GDB reports the breakpoint -# as if it were in the middle of a line rather than at the beginning. +# now move the .debug file to a different location so that we can test +# the "set debug-file-directory" command. + +remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}" +set debugfile "${objdir}/${subdir}/${testfile}.debug" -set bp_location13 [gdb_get_line_number "set breakpoint 13 here"] -set bp_location14 [gdb_get_line_number "set breakpoint 14 here"] -send_gdb "continue\n" -gdb_expect { - -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { - pass "run until breakpoint set at small function, optimized file" - } - -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { - pass "run until breakpoint set at small function, optimized file" - } - -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" { - # marker4() is defined at line 46 when compiled with -DPROTOTYPES - pass "run until breakpoint set at small function, optimized file (line bp_location14)" - } - -re ".*$gdb_prompt " { - fail "run until breakpoint set at small function, optimized file" - } - timeout { - fail "run until breakpoint set at small function, optimized file (timeout)" +test_different_dir debuglink "${objdir}/${subdir}" 0 + + +# NT_GNU_BUILD_ID / .note.gnu.build-id test: + +set build_id_debug_filename [build_id_debug_filename_get $binfile] +if {$build_id_debug_filename eq ""} { + unsupported "build-id is not supported by the compiler" + + # Spare debug files may confuse testsuite runs in the future. + remote_exec build "rm -f $debugfile" +} else { + set build_id_debugself_filename [build_id_debug_filename_get $debugfile] + set test "build-id support by binutils" + set xfail 0 + if {$build_id_debugself_filename eq ""} { + unsupported $test + set xfail 1 + } elseif {$build_id_debugself_filename ne $build_id_debug_filename} { + fail $test + } else { + pass $test } -} + file mkdir [file dirname ${objdir}/${subdir}/${build_id_debug_filename}] + remote_exec build "mv $debugfile ${objdir}/${subdir}/${build_id_debug_filename}" + + test_different_dir build-id "${objdir}/${subdir}" $xfail -# Reset the default arguments for VxWorks -if [istarget "*-*-vxworks*"] { - set timeout 10 - verbose "Timeout is now $timeout seconds" 2 - send_gdb "set args main\n" - gdb_expect -re ".*$gdb_prompt $" {} + # Spare debug files may confuse testsuite runs in the future. + remote_exec build "rm -f ${objdir}/${subdir}/${build_id_debug_filename}" } --- gdb/testsuite/lib/gdb.exp 23 Aug 2007 20:10:04 -0000 1.86 +++ gdb/testsuite/lib/gdb.exp 25 Aug 2007 22:43:32 -0000 @@ -2482,6 +2482,27 @@ proc separate_debug_filename { exec } { return $debug_file } +# Return the build-id hex string (usually 160 bits as 40 hex characters) +# converted to the form: .build-id/ab/cdef1234...89.debug +# Return "" if no build-id found. +proc build_id_debug_filename_get { exec } { + set tmp "${exec}-tmp" + exec objcopy -j .note.gnu.build-id -O binary $exec $tmp + set fi [open $tmp] + # Skip the NOTE header. + read $fi 16 + set data [read $fi] + close $fi + file delete $tmp + if {$data eq ""} { + return "" + } + # Convert it to hex. + binary scan $data H* data + set data [regsub {^..} $data {\0/}] + return ".build-id/${data}.debug"; +} + # Create stripped files for DEST, replacing it. If ARGS is passed, it is a # list of optional flags. The only currently supported flag is no-main, # which removes the symbol entry for main from the separate debug file. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-25 22:49 ` Jan Kratochvil @ 2007-08-25 23:58 ` Daniel Jacobowitz 2007-08-26 9:41 ` Jan Kratochvil 0 siblings, 1 reply; 25+ messages in thread From: Daniel Jacobowitz @ 2007-08-25 23:58 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, Roland McGrath On Sun, Aug 26, 2007 at 12:49:14AM +0200, Jan Kratochvil wrote: > You are right about the content of `/lib64/ld-linux-x86-64.so.2'. > Still in such case both `.dynsym' and `.symtab' gets read into MSYMBOLS but > PSYMTABS and SYMTABS are left forever NULL for the main executable (as there is > no .debug_info). > > While I would still expect the former patch was right I changed it according to > your advice. It is definitely the safe way but with a tiny performance hit: > > The reason of my check was that build-id (contrary to the debug-link) is always > present there, even for locally built unsplit files. With the patch attached > below GDB will try to open a separate debug file in /usr/lib/debug/.debug-id/ > even for the unsplit files. This step did not happen with my former patch. Right. There's two other ways we could check, which Roland suggested: presence of .gnu_debuglink and presence of .debug_info. I misread your original patch. If there's no .debug_info then there won't be any psymtabs. So that's probably the best check, and I apologize for the bad advice. I don't want to check for .gnu_debuglink; in the future maybe files which use build ID won't have a .gnu_debuglink section any more. -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-25 23:58 ` Daniel Jacobowitz @ 2007-08-26 9:41 ` Jan Kratochvil 2007-08-31 9:38 ` Eli Zaretskii 0 siblings, 1 reply; 25+ messages in thread From: Jan Kratochvil @ 2007-08-26 9:41 UTC (permalink / raw) To: Daniel Jacobowitz; +Cc: gdb-patches, Roland McGrath [-- Attachment #1: Type: text/plain, Size: 527 bytes --] On Sun, 26 Aug 2007 01:58:05 +0200, Daniel Jacobowitz wrote: ... > I misread your original patch. If there's no .debug_info then there > won't be any psymtabs. So that's probably the best check, and I > apologize for the bad advice. I don't want to check for > .gnu_debuglink; in the future maybe files which use build ID won't > have a .gnu_debuglink section any more. Put there back the original check with a comment now. Added additional loop-deadlock prevention for stripped .debug files. Thanks for the review, Jan [-- Attachment #2: gdb-buildid-verify2.patch --] [-- Type: text/plain, Size: 23036 bytes --] 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> * Makefile.in (symfile.o): Update dependencies. * symfile.c (symbol_file_add_with_addrs_or_offsets): Initialize the DEBUGFILE variable. FIND_SEPARATE_DEBUG_FILE called only if !PSYMTABS. (struct build_id): New structure. (build_id_bfd_get, build_id_verify, build_id_to_debug_filename): New. (find_separate_debug_file): New variable BUILD_ID. Call BUILD_ID_BFD_GET with BUILD_ID_TO_DEBUG_FILENAME as the first try. 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> * lib/gdb.exp (build_id_debug_filename_get): New function. * gdb.base/sepdebug.exp: Reflect the changes in the heading comment. Remove the generate DEBUG file for the future testcase runs. New testcase for the NT_GNU_BUILD_ID retrieval. Move the final testing step to ... (test_different_dir): ... a new function. New parameter XFAIL to XFAIL all the tests performed. New parameter TEST_DIFFERENT_DIR parametrizing the directory. New parameter TYPE to PF_PREFIX all the tests performed. 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Separate Debug Files): Included a BUILD ID description. Enlisted BUILD ID to the debug file searching example. Included a BUILD ID `.note.gnu.build-id' section description. Updated/added the debug files splitting instructions for OBJCOPY. --- gdb/Makefile.in 23 Aug 2007 20:33:48 -0000 1.929 +++ gdb/Makefile.in 26 Aug 2007 09:33:21 -0000 @@ -2731,7 +2731,7 @@ symfile.o: symfile.c $(defs_h) $(bfdlink $(gdb_stabs_h) $(gdb_obstack_h) $(completer_h) $(bcache_h) \ $(hashtab_h) $(readline_h) $(gdb_assert_h) $(block_h) \ $(gdb_string_h) $(gdb_stat_h) $(observer_h) $(exec_h) \ - $(parser_defs_h) $(varobj_h) + $(parser_defs_h) $(varobj_h) $(elf_bfd_h) symfile-mem.o: symfile-mem.c $(defs_h) $(symtab_h) $(gdbcore_h) \ $(objfiles_h) $(exceptions_h) $(gdbcmd_h) $(target_h) $(value_h) \ $(symfile_h) $(observer_h) $(auxv_h) $(elf_common_h) --- gdb/symfile.c 23 Aug 2007 18:08:39 -0000 1.190 +++ gdb/symfile.c 26 Aug 2007 09:33:23 -0000 @@ -51,6 +51,7 @@ #include "exec.h" #include "parser-defs.h" #include "varobj.h" +#include "elf-bfd.h" #include <sys/types.h> #include <fcntl.h> @@ -1017,7 +1018,7 @@ symbol_file_add_with_addrs_or_offsets (b { struct objfile *objfile; struct partial_symtab *psymtab; - char *debugfile; + char *debugfile = NULL; struct section_addr_info *orig_addrs = NULL; struct cleanup *my_cleanups; const char *name = bfd_get_filename (abfd); @@ -1081,7 +1082,11 @@ symbol_file_add_with_addrs_or_offsets (b } } - debugfile = find_separate_debug_file (objfile); + /* If the file has its own symbol tables it has no separate debug info. + `.dynsym'/`.symtab' go to MSYMBOLS, `.debug_info' goes to SYMTABS/PSYMTABS. + `.gnu_debuglink' may no longer be present with `.note.gnu.build-id'. */ + if (objfile->psymtabs == NULL) + debugfile = find_separate_debug_file (objfile); if (debugfile) { if (addrs != NULL) @@ -1223,6 +1228,97 @@ symbol_file_clear (int from_tty) printf_unfiltered (_("No symbol file now.\n")); } +struct build_id + { + size_t size; + gdb_byte data[1]; + }; + +/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ + +static struct build_id * +build_id_bfd_get (bfd *abfd) +{ + struct build_id *retval; + + if (!bfd_check_format (abfd, bfd_object) + || bfd_get_flavour (abfd) != bfd_target_elf_flavour + || elf_tdata (abfd)->build_id == NULL) + return NULL; + + retval = xmalloc (sizeof *retval - 1 + elf_tdata (abfd)->build_id_size); + retval->size = elf_tdata (abfd)->build_id_size; + memcpy (retval->data, elf_tdata (abfd)->build_id, retval->size); + + return retval; +} + +/* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */ + +static int +build_id_verify (const char *filename, struct build_id *check) +{ + bfd *abfd; + struct build_id *found = NULL; + int retval = 0; + + /* We expect to be silent on the non-existing files. */ + abfd = bfd_openr (filename, gnutarget); + if (abfd == NULL) + return 0; + + found = build_id_bfd_get (abfd); + + if (found == NULL) + warning (_("File \"%s\" has no build-id, file skipped"), filename); + else if (found->size != check->size + || memcmp (found->data, check->data, found->size) != 0) + warning (_("File \"%s\" has a different build-id, file skipped"), filename); + else + retval = 1; + + if (!bfd_close (abfd)) + warning (_("cannot close \"%s\": %s"), filename, + bfd_errmsg (bfd_get_error ())); + return retval; +} + +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; + + /* 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)) + { + xfree (retval); + retval = NULL; + } + + return retval; +} + static char * get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) { @@ -1300,6 +1396,25 @@ find_separate_debug_file (struct objfile bfd_size_type debuglink_size; unsigned long crc32; int i; + struct build_id *build_id; + + build_id = build_id_bfd_get (objfile->obfd); + if (build_id != NULL) + { + char *build_id_name; + + build_id_name = build_id_to_debug_filename (build_id); + free (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"), + build_id_name); + xfree (build_id_name); + } + else if (build_id_name != NULL) + return build_id_name; + } basename = get_debug_link_info (objfile, &crc32); --- gdb/doc/gdb.texinfo 21 Aug 2007 15:09:59 -0000 1.423 +++ gdb/doc/gdb.texinfo 26 Aug 2007 09:33:32 -0000 @@ -11902,18 +11902,32 @@ than the executable code itself --- some information for their executables in separate files, which users can install only when they need to debug a problem. -If an executable's debugging information has been extracted to a -separate file, the executable should contain a @dfn{debug link} giving -the name of the debugging information file (with no directory -components), and a checksum of its contents. (The exact form of a -debug link is described below.) If the full name of the directory -containing the executable is @var{execdir}, and the executable has a -debug link that specifies the name @var{debugfile}, then @value{GDBN} -will automatically search for the debugging information file in three -places: +There are two identificators how the separate debug file may be found: @itemize @bullet @item +@dfn{debug link} is present only in the executable if its debug information has +been split out. It is not present in the separate debug file. It provides the +separate debug file filename, usually as @file{executable.debug}. +@item +@dfn{build id} is present in all the files (if the operating system supports +it). The executable file and its separate debug file have the same unique +@dfn{build id} content. +@end itemize + +If the full name of the directory containing the executable is @var{execdir}, +the executable has a debug link that specifies the name @var{debugfile}, +@var{bu} is the first byte (two hexadecimal characters) of the build id +content, @var{ild-id} are the remaining bytes / hexadecimal characters and +@var{globaldebugdir} is the global debug file directory then @value{GDBN} will +automatically search for the debugging information file in four places: + +@itemize @bullet +@item +a specific file in the subdirectory of the global debug file directory +according to the @dfn{build id} content (if present), the file tried is +@file{@var{globaldebugdir}/.debug-id/@var{bu}/@var{ild-id}.debug}. +@item the directory containing the executable file (that is, it will look for a file named @file{@var{execdir}/@var{debugfile}}, @item @@ -11928,15 +11942,17 @@ executable's full path, and the name fro @end itemize @noindent @value{GDBN} checks under each of these names for a debugging -information file whose checksum matches that given in the link, and -reads the debugging information from the first one it finds. - -So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, -which has a link containing the name @file{ls.debug}, and the global -debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look -for debug information in @file{/usr/bin/ls.debug}, -@file{/usr/bin/.debug/ls.debug}, and -@file{/usr/lib/debug/usr/bin/ls.debug}. +information file with build id content matching the build id content of the +executable file - or - whose checksum matches the one given in the link in the +debug link case. In each case @value{GDBN} reads the debugging information +from the first debug file it finds. + +So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, which has +a @dfn{debug link} containing the name @file{ls.debug}, its @dfn{build id} +value in hexadecimal is @code{abcdef} and the global debug directory is +@file{/usr/lib/debug}, then @value{GDBN} will look for debug information in +@file{/usr/lib/debug/.build-id/ab/cdef.debug}, @file{/usr/bin/ls.debug}, +@file{/usr/bin/.debug/ls.debug}, and @file{/usr/lib/debug/usr/bin/ls.debug}. You can set the global debugging info directory's name, and view the name @value{GDBN} is currently using. @@ -11978,6 +11994,16 @@ Any executable file format can carry a d contain a section named @code{.gnu_debuglink} with the contents described above. +@cindex @code{.note.gnu.build-id} sections +@cindex build id +Build id is a special section of the executable file named +@code{.note.gnu.build-id}. The section contains unique identification hash +derived from the built files - it remains the same across multiple builds of +the same build tree. The default algorithm SHA1 produces 160 bits (40 +hexadecimal characters) of the content. The same section and value is present +in the original built binary with symbols, in its stripped variant and in the +separate debug information file. + The debugging information file itself should be an ordinary executable, containing a full set of linker symbols, sections, and debugging information. The sections of the debugging information file @@ -11985,18 +12011,21 @@ should have the same names, addresses an but they need not contain any data --- much like a @code{.bss} section in an ordinary executable. -As of December 2002, there is no standard GNU utility to produce -separated executable / debugging information file pairs. Ulrich -Drepper's @file{elfutils} package, starting with version 0.53, -contains a version of the @code{strip} command such that the command -@kbd{strip foo -f foo.debug} removes the debugging information from -the executable file @file{foo}, places it in the file -@file{foo.debug}, and leaves behind a debug link in @file{foo}. - -Since there are many different ways to compute CRC's (different -polynomials, reversals, byte ordering, etc.), the simplest way to -describe the CRC used in @code{.gnu_debuglink} sections is to give the -complete code for a function that computes it: +@sc{gnu} binary utilities contain the @samp{objcopy} utility able to produce +the separated executable / debugging information file pairs by commands +@kbd{objcopy --only-keep-debug foo foo.debug; strip -g foo; objcopy +--add-gnu-debuglink="foo.debug" "foo"}. These commands remove the debugging +information from the executable file @file{foo}, place it in the file +@file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich +Drepper's @file{elfutils} package, starting with version 0.53, contains +a version of the @code{strip} command such that the command @kbd{strip foo -f +foo.debug} has the same functionality as the three commands above. + +Since there are many different ways to compute CRC's for the debug link +(different polynomials, reversals, byte ordering, etc.). This computation does +not apply to the build id section. The simplest way to describe the CRC used +in @code{.gnu_debuglink} sections is to give the complete code for a function +that computes it: @kindex gnu_debuglink_crc32 @smallexample --- gdb/testsuite/gdb.base/sepdebug.exp 23 Aug 2007 18:14:17 -0000 1.8 +++ gdb/testsuite/gdb.base/sepdebug.exp 26 Aug 2007 09:33:32 -0000 @@ -19,11 +19,14 @@ # Based on break.exp, written by Rob Savoye. (rob@cygnus.com) # Modified to test gdb's handling of separate debug info files. +# Modified to test gdb's handling of a debug-id retrieval. # This file has two parts. The first is testing that gdb behaves # normally after reading in an executable and its corresponding # separate debug file. The second moves the .debug file to a different # location and tests the "set debug-file-directory" command. +# The third is for testing build-id retrievel by finding the separate +# ".debug-id/ab/cdef.debug" file. if $tracelevel then { @@ -828,93 +831,152 @@ test_next_with_recursion #******** -# now move the .debug file to a different location so that we can test -# the "set debug-file-directory" command. - -remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}" -gdb_exit -gdb_start -gdb_reinitialize_dir $srcdir/$subdir -gdb_test "set debug-file-directory ${objdir}/${subdir}" ".*" "set separate debug location" -gdb_load ${binfile} +proc test_different_dir {type test_different_dir xfail} { + global srcdir subdir objdir binfile srcfile timeout gdb_prompt + global pf_prefix + global bp_location6 decimal hex + + set pf_prefix "$type:" + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_test "set debug-file-directory ${test_different_dir}" ".*" "set separate debug location" + gdb_load ${binfile} -if [target_info exists gdb_stub] { - gdb_step_for_stub; -} + if [target_info exists gdb_stub] { + gdb_step_for_stub; + } -# -# test break at function -# -gdb_test "break main" \ - "Breakpoint.*at.* file .*$srcfile, line.*" \ - "breakpoint function, optimized file" + # + # test break at function + # + if {$xfail} { + setup_xfail "*-*-*" + } + gdb_test "break main" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function, optimized file" -# -# test break at function -# -gdb_test "break marker4" \ - "Breakpoint.*at.* file .*$srcfile, line.*" \ - "breakpoint small function, optimized file" + # + # test break at function + # + if {$xfail} { + setup_xfail "*-*-*" + } + gdb_test "break marker4" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint small function, optimized file" -# -# run until the breakpoint at main is hit. For non-stubs-using targets. -# -gdb_run_cmd -gdb_expect { - -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" { - pass "run until function breakpoint, optimized file" + # + # run until the breakpoint at main is hit. For non-stubs-using targets. + # + gdb_run_cmd + if {$xfail} { + setup_xfail "*-*-*" } - -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" { - pass "run until function breakpoint, optimized file (code motion)" + gdb_expect { + -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $" { + pass "run until function breakpoint, optimized file" + } + -re "Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $" { + pass "run until function breakpoint, optimized file (code motion)" + } + -re "$gdb_prompt $" { + fail "run until function breakpoint, optimized file" + } + timeout { + fail "run until function breakpoint, optimized file (timeout)" + } } - -re "$gdb_prompt $" { - fail "run until function breakpoint, optimized file" + + # + # run until the breakpoint at a small function + # + + # + # Add a second pass pattern. The behavior differs here between stabs + # and dwarf for one-line functions. Stabs preserves two line symbols + # (one before the prologue and one after) with the same line number, + # but dwarf regards these as duplicates and discards one of them. + # Therefore the address after the prologue (where the breakpoint is) + # has no exactly matching line symbol, and GDB reports the breakpoint + # as if it were in the middle of a line rather than at the beginning. + + set bp_location13 [gdb_get_line_number "set breakpoint 13 here"] + set bp_location14 [gdb_get_line_number "set breakpoint 14 here"] + send_gdb "continue\n" + if {$xfail} { + setup_xfail "*-*-*" } - timeout { - fail "run until function breakpoint, optimized file (timeout)" + gdb_expect { + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" { + # marker4() is defined at line 46 when compiled with -DPROTOTYPES + pass "run until breakpoint set at small function, optimized file (line bp_location14)" + } + -re ".*$gdb_prompt " { + fail "run until breakpoint set at small function, optimized file" + } + timeout { + fail "run until breakpoint set at small function, optimized file (timeout)" + } + } + + + # Reset the default arguments for VxWorks + if [istarget "*-*-vxworks*"] { + set timeout 10 + verbose "Timeout is now $timeout seconds" 2 + send_gdb "set args main\n" + gdb_expect -re ".*$gdb_prompt $" {} } + + unset pf_prefix +# proc test_different_dir } -# -# run until the breakpoint at a small function -# -# -# Add a second pass pattern. The behavior differs here between stabs -# and dwarf for one-line functions. Stabs preserves two line symbols -# (one before the prologue and one after) with the same line number, -# but dwarf regards these as duplicates and discards one of them. -# Therefore the address after the prologue (where the breakpoint is) -# has no exactly matching line symbol, and GDB reports the breakpoint -# as if it were in the middle of a line rather than at the beginning. +# now move the .debug file to a different location so that we can test +# the "set debug-file-directory" command. + +remote_exec build "mv ${objdir}/${subdir}/.debug/${testfile}.debug ${objdir}/${subdir}" +set debugfile "${objdir}/${subdir}/${testfile}.debug" -set bp_location13 [gdb_get_line_number "set breakpoint 13 here"] -set bp_location14 [gdb_get_line_number "set breakpoint 14 here"] -send_gdb "continue\n" -gdb_expect { - -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { - pass "run until breakpoint set at small function, optimized file" - } - -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { - pass "run until breakpoint set at small function, optimized file" - } - -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" { - # marker4() is defined at line 46 when compiled with -DPROTOTYPES - pass "run until breakpoint set at small function, optimized file (line bp_location14)" - } - -re ".*$gdb_prompt " { - fail "run until breakpoint set at small function, optimized file" - } - timeout { - fail "run until breakpoint set at small function, optimized file (timeout)" +test_different_dir debuglink "${objdir}/${subdir}" 0 + + +# NT_GNU_BUILD_ID / .note.gnu.build-id test: + +set build_id_debug_filename [build_id_debug_filename_get $binfile] +if {$build_id_debug_filename eq ""} { + unsupported "build-id is not supported by the compiler" + + # Spare debug files may confuse testsuite runs in the future. + remote_exec build "rm -f $debugfile" +} else { + set build_id_debugself_filename [build_id_debug_filename_get $debugfile] + set test "build-id support by binutils" + set xfail 0 + if {$build_id_debugself_filename eq ""} { + unsupported $test + set xfail 1 + } elseif {$build_id_debugself_filename ne $build_id_debug_filename} { + fail $test + } else { + pass $test } -} + file mkdir [file dirname ${objdir}/${subdir}/${build_id_debug_filename}] + remote_exec build "mv $debugfile ${objdir}/${subdir}/${build_id_debug_filename}" + + test_different_dir build-id "${objdir}/${subdir}" $xfail -# Reset the default arguments for VxWorks -if [istarget "*-*-vxworks*"] { - set timeout 10 - verbose "Timeout is now $timeout seconds" 2 - send_gdb "set args main\n" - gdb_expect -re ".*$gdb_prompt $" {} + # Spare debug files may confuse testsuite runs in the future. + remote_exec build "rm -f ${objdir}/${subdir}/${build_id_debug_filename}" } --- gdb/testsuite/lib/gdb.exp 23 Aug 2007 20:10:04 -0000 1.86 +++ gdb/testsuite/lib/gdb.exp 26 Aug 2007 09:33:34 -0000 @@ -2482,6 +2482,27 @@ proc separate_debug_filename { exec } { return $debug_file } +# Return the build-id hex string (usually 160 bits as 40 hex characters) +# converted to the form: .build-id/ab/cdef1234...89.debug +# Return "" if no build-id found. +proc build_id_debug_filename_get { exec } { + set tmp "${exec}-tmp" + exec objcopy -j .note.gnu.build-id -O binary $exec $tmp + set fi [open $tmp] + # Skip the NOTE header. + read $fi 16 + set data [read $fi] + close $fi + file delete $tmp + if {$data eq ""} { + return "" + } + # Convert it to hex. + binary scan $data H* data + set data [regsub {^..} $data {\0/}] + return ".build-id/${data}.debug"; +} + # Create stripped files for DEST, replacing it. If ARGS is passed, it is a # list of optional flags. The only currently supported flag is no-main, # which removes the symbol entry for main from the separate debug file. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-26 9:41 ` Jan Kratochvil @ 2007-08-31 9:38 ` Eli Zaretskii 2007-08-31 20:51 ` [patch approval?] " Jan Kratochvil [not found] ` <20070901081934.GA31205@host0.dyn.jankratochvil.net> 0 siblings, 2 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-08-31 9:38 UTC (permalink / raw) To: Jan Kratochvil; +Cc: drow, gdb-patches, roland > Date: Sun, 26 Aug 2007 11:40:53 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: gdb-patches@sourceware.org, Roland McGrath <roland@redhat.com> > > 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> > > * gdb.texinfo (Separate Debug Files): Included a BUILD ID description. > Enlisted BUILD ID to the debug file searching example. > Included a BUILD ID `.note.gnu.build-id' section description. > Updated/added the debug files splitting instructions for OBJCOPY. Thanks. The patch for the manual needs some work on the wording. Please commit it (assuming that the code patch is approved), and I will then improve it and post the changes here so you will see what I've done. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approval?] build-id .debug files load (like .gnu_debuglink) 2007-08-31 9:38 ` Eli Zaretskii @ 2007-08-31 20:51 ` Jan Kratochvil 2007-08-31 21:12 ` Daniel Jacobowitz 2007-09-01 8:01 ` Eli Zaretskii [not found] ` <20070901081934.GA31205@host0.dyn.jankratochvil.net> 1 sibling, 2 replies; 25+ messages in thread From: Jan Kratochvil @ 2007-08-31 20:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: drow, gdb-patches, roland On Fri, 31 Aug 2007 11:38:37 +0200, Eli Zaretskii wrote: > (assuming that the code patch is approved), AFAIK I did not get a final approval. http://sources.redhat.com/ml/gdb-patches/2007-08/msg00478.html > > Date: Sun, 26 Aug 2007 11:40:53 +0200 > > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > Cc: gdb-patches@sourceware.org, Roland McGrath <roland@redhat.com> > > > > 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> > > > > * gdb.texinfo (Separate Debug Files): Included a BUILD ID description. > > Enlisted BUILD ID to the debug file searching example. > > Included a BUILD ID `.note.gnu.build-id' section description. > > Updated/added the debug files splitting instructions for OBJCOPY. > > Thanks. The patch for the manual needs some work on the wording. > Please commit it Thanks, going to at least make notes on your fixes. Regards, Jan ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approval?] build-id .debug files load (like .gnu_debuglink) 2007-08-31 20:51 ` [patch approval?] " Jan Kratochvil @ 2007-08-31 21:12 ` Daniel Jacobowitz 2007-09-01 8:01 ` Eli Zaretskii 1 sibling, 0 replies; 25+ messages in thread From: Daniel Jacobowitz @ 2007-08-31 21:12 UTC (permalink / raw) To: Jan Kratochvil; +Cc: Eli Zaretskii, gdb-patches, roland On Fri, Aug 31, 2007 at 10:50:36PM +0200, Jan Kratochvil wrote: > On Fri, 31 Aug 2007 11:38:37 +0200, Eli Zaretskii wrote: > > (assuming that the code patch is approved), > > AFAIK I did not get a final approval. > http://sources.redhat.com/ml/gdb-patches/2007-08/msg00478.html I just looked over your final patch; the code part is OK. Thanks for your patience. I didn't look too closely at the test - if it fails, we'll fix it :-) -- Daniel Jacobowitz CodeSourcery ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approval?] build-id .debug files load (like .gnu_debuglink) 2007-08-31 20:51 ` [patch approval?] " Jan Kratochvil 2007-08-31 21:12 ` Daniel Jacobowitz @ 2007-09-01 8:01 ` Eli Zaretskii 1 sibling, 0 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-09-01 8:01 UTC (permalink / raw) To: Jan Kratochvil; +Cc: drow, gdb-patches, roland > Date: Fri, 31 Aug 2007 22:50:36 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: drow@false.org, gdb-patches@sourceware.org, roland@redhat.com > > > Thanks. The patch for the manual needs some work on the wording. > > Please commit it > > Thanks, going to at least make notes on your fixes. I will gladly answer any of the questions you might have after looking at my fixes, when they are committed. ^ permalink raw reply [flat|nested] 25+ messages in thread
[parent not found: <20070901081934.GA31205@host0.dyn.jankratochvil.net>]
* Re: [patch] build-id .debug files load (like .gnu_debuglink) [not found] ` <20070901081934.GA31205@host0.dyn.jankratochvil.net> @ 2007-09-01 10:31 ` Eli Zaretskii 2007-09-01 11:35 ` Jan Kratochvil 0 siblings, 1 reply; 25+ messages in thread From: Eli Zaretskii @ 2007-09-01 10:31 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, roland > Date: Sat, 1 Sep 2007 10:19:34 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Fri, 31 Aug 2007 11:38:37 +0200, Eli Zaretskii wrote: > > > Date: Sun, 26 Aug 2007 11:40:53 +0200 > > > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > > Cc: gdb-patches@sourceware.org, Roland McGrath <roland@redhat.com> > > > > > > 2007-08-26 Jan Kratochvil <jan.kratochvil@redhat.com> > > > > > > * gdb.texinfo (Separate Debug Files): Included a BUILD ID description. > > > Enlisted BUILD ID to the debug file searching example. > > > Included a BUILD ID `.note.gnu.build-id' section description. > > > Updated/added the debug files splitting instructions for OBJCOPY. > > > > Thanks. The patch for the manual needs some work on the wording. > > Please commit it (assuming that the code patch is approved), and I > > will then improve it and post the changes here so you will see what > > I've done. > > Just a notification the patch has been committed. Thanks. I attach below the changes I committed to the manual, to fix the description of how GDB looks for debug info files when debug ID is supported. Because the rewording is so extensive, I also attach below the entire section in its new form, to facilitate reading. I ended up to be a bit confused about several issues related to debug ID; if you (or someone else, maybe Roland) can shed some light on them, I might be able to improve the section in a couple of additional areas where for now I left things a bit vague or even inaccurate: . The Fedora site that describes the build ID features seems to say that there are TWO files (actually symlinks) in the global debug directory for each executable: ab/cdef1234 and ab/cdef1234.debug. By contrast, you only talk about a single file. What is the truth, and if the second file exists, how, if at all, does it affect GDB? . The Fedora site says that the build ID symlinks are created only in the global debug directory. However, your patch seems to say that GDB looks for these symlinks in all the other possible locations as well: @value{GDBN} checks under each of these names for a debugging +information file with build id content matching the build id content of the +executable file - or - whose checksum matches the one given in the link in the +debug link case. Which one is true? . The objcopy commands shown in your patch seem to be relevant only to the ``debug link'' method (at least that's what I understand from the last objcopy command). If so, I think we should say what are the corresponding commands for the ``debug ID'' method. Likewise, if there are (or going to be) features in elfutils that support ``debug ID'', I think we should mention them, as we do for ``debug links'' now. . I'm confused by your mentioning of ``all files'' in this passage: +@dfn{build id} is present in all the files [...] as opposed to ``only the executable'' in the debug link case: +@dfn{debug link} is present only in the executable [...] I don't understand this distinction. As far as I could glean from the build ID description on the Fedora site, the difference is that the build ID is present both in the executable and in the debug info file, whereas the debug link is present only in the executable. Thus we have two files (maybe 3, if core dumps are counted), vs one, not ``only one'' vs ``all''. Did I miss something? Finally, here are the patch followed by the full section. Please feel free to ask about any of the changes I made. Btw, I think this change warrants an entry in NEWS. Thanks again for working on this. ---------------- The patch ------------------------- Index: gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.425 diff -u -r1.425 gdb.texinfo --- gdb.texinfo 1 Sep 2007 08:17:13 -0000 1.425 +++ gdb.texinfo 1 Sep 2007 09:57:16 -0000 @@ -11893,66 +11893,79 @@ @cindex @file{.debug} subdirectories @cindex debugging information directory, global @cindex global debugging information directory +@cindex build ID, and separate debugging files +@cindex @file{.build-id} directory @value{GDBN} allows you to put a program's debugging information in a file separate from the executable itself, in a way that allows @value{GDBN} to find and load the debugging information automatically. -Since debugging information can be very large --- sometimes larger -than the executable code itself --- some systems distribute debugging +Since debugging information can be very large---sometimes larger +than the executable code itself---some systems distribute debugging information for their executables in separate files, which users can install only when they need to debug a problem. -There are two identificators how the separate debug file may be found: +@value{GDBN} supports two ways of specifying the separate debug info +file: @itemize @bullet @item -@dfn{debug link} is present only in the executable if its debug information has -been split out. It is not present in the separate debug file. It provides the -separate debug file filename, usually as @file{executable.debug}. -@item -@dfn{build id} is present in all the files (if the operating system supports -it). The executable file and its separate debug file have the same unique -@dfn{build id} content. +The executable contains a @dfn{debug link} that specifies the name of +the separate debug info file. The separate debug file's name is +usually @file{@var{executable}.debug}, where @var{executable} is the +name of the corresponding executable file without leading directories +(e.g., @file{ls.debug} for @file{/usr/bin/ls}). In addition, the +debug link specifies a CRC32 checksum for the debug file, which +@value{GDBN} uses to validate that the executable and the debug file +came from the same build. + +@item +The executable contains a @dfn{build ID}, a unique signature that is +also present in the corresponding debug info file. (This is supported +only on some operating systems, notably on @sc{gnu}/Linux. For more +details about this feature, see +@uref{http://fedoraproject.org/wiki/Releases/FeatureBuildId, the +Fedora Project's description of the buid ID feature}.) The debug info +file's name is not specified explicitly by the debug ID, but can be +computed from the build ID, see below. @end itemize -If the full name of the directory containing the executable is @var{execdir}, -the executable has a debug link that specifies the name @var{debugfile}, -@var{bu} is the first byte (two hexadecimal characters) of the build id -content, @var{ild-id} are the remaining bytes / hexadecimal characters and -@var{globaldebugdir} is the global debug file directory then @value{GDBN} will -automatically search for the debugging information file in four places: +Depending on the way the debug info file is specified, @value{GDBN} +uses two different methods of looking for the debug file: @itemize @bullet @item -a specific file in the subdirectory of the global debug file directory -according to the @dfn{build id} content (if present), the file tried is -@file{@var{globaldebugdir}/.debug-id/@var{bu}/@var{ild-id}.debug}. -@item -the directory containing the executable file (that is, it will look -for a file named @file{@var{execdir}/@var{debugfile}}, -@item -a subdirectory of that directory named @file{.debug} (that is, the -file @file{@var{execdir}/.debug/@var{debugfile}}, and -@item -a subdirectory of the global debug file directory that includes the -executable's full path, and the name from the link (that is, the file -@file{@var{globaldebugdir}/@var{execdir}/@var{debugfile}}, where -@var{globaldebugdir} is the global debug file directory, and -@var{execdir} has been turned into a relative path). +For the ``debug link'' method, @value{GDBN} looks up the named file in +the directory of the executable file, then in a subdirectory of that +directory named @file{.debug}, and finally under the global debug +directory, in a subdirectory whose name is identical to the leading +directories of the executable's absolute file name. + +@item +For the ``debug ID'' method, @value{GDBN} looks in the +@file{.build-id} subdirectory of the global debug directory for a file +named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the +first 2 hex characters of the debug ID signature, and @var{nnnnnnnn} +are the rest of the signature. (Real signatures are 32 or more +characters, not 10.) +@end itemize + +So, for example, suppose you ask @value{GDBN} to debug +@file{/usr/bin/ls}, which has a @dfn{debug link} that specifies the +file @file{ls.debug}, and a @dfn{build id} whose value in hex is +@code{abcdef1234}. If the global debug directory is +@file{/usr/lib/debug}, then @value{GDBN} will look for the following +debug information files, in the indicated order: + +@itemize @minus +@item +@file{/usr/lib/debug/.build-id/ab/cdef1234.debug} +@item +@file{/usr/bin/ls.debug} +@item +@file{/usr/bin/.debug/ls.debug} +@item +@file{/usr/lib/debug/usr/bin/ls.debug}. @end itemize -@noindent -@value{GDBN} checks under each of these names for a debugging -information file with build id content matching the build id content of the -executable file - or - whose checksum matches the one given in the link in the -debug link case. In each case @value{GDBN} reads the debugging information -from the first debug file it finds. - -So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls}, which has -a @dfn{debug link} containing the name @file{ls.debug}, its @dfn{build id} -value in hexadecimal is @code{abcdef} and the global debug directory is -@file{/usr/lib/debug}, then @value{GDBN} will look for debug information in -@file{/usr/lib/debug/.build-id/ab/cdef.debug}, @file{/usr/bin/ls.debug}, -@file{/usr/bin/.debug/ls.debug}, and @file{/usr/lib/debug/usr/bin/ls.debug}. You can set the global debugging info directory's name, and view the name @value{GDBN} is currently using. @@ -11972,7 +11985,7 @@ @end table @cindex @code{.gnu_debuglink} sections -@cindex debug links +@cindex debug link sections A debug link is a special section of the executable file named @code{.gnu_debuglink}. The section must contain: @@ -11995,37 +12008,46 @@ described above. @cindex @code{.note.gnu.build-id} sections -@cindex build id -Build id is a special section of the executable file named -@code{.note.gnu.build-id}. The section contains unique identification hash -derived from the built files - it remains the same across multiple builds of -the same build tree. The default algorithm SHA1 produces 160 bits (40 -hexadecimal characters) of the content. The same section and value is present -in the original built binary with symbols, in its stripped variant and in the -separate debug information file. +@cindex build ID sections +A build ID is a special section of the executable file named +@code{.note.gnu.build-id}. This section contains unique +identification for the built files---it remains the same across +multiple builds of the same build tree. The default algorithm SHA1 +produces 160 bits (40 hexadecimal characters) of the content. The +same section with an identical value is present in the original built +binary with symbols, in its stripped variant, and in the separate +debugging information file. The debugging information file itself should be an ordinary executable, containing a full set of linker symbols, sections, and debugging information. The sections of the debugging information file -should have the same names, addresses and sizes as the original file, -but they need not contain any data --- much like a @code{.bss} section +should have the same names, addresses, and sizes as the original file, +but they need not contain any data---much like a @code{.bss} section in an ordinary executable. -@sc{gnu} binary utilities contain the @samp{objcopy} utility able to produce -the separated executable / debugging information file pairs by commands -@kbd{objcopy --only-keep-debug foo foo.debug; strip -g foo; objcopy ---add-gnu-debuglink="foo.debug" "foo"}. These commands remove the debugging +@sc{gnu} binary utilities (Binutils) package includes the +@samp{objcopy} utility that can produce +the separated executable / debugging information file pairs using the +following commands: + +@example +@kbd{objcopy --only-keep-debug foo foo.debug} +@kbd{strip -g foo} +@kbd{objcopy --add-gnu-debuglink="foo.debug" "foo"} +@end example + +@noindent +These commands remove the debugging information from the executable file @file{foo}, place it in the file @file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich Drepper's @file{elfutils} package, starting with version 0.53, contains a version of the @code{strip} command such that the command @kbd{strip foo -f foo.debug} has the same functionality as the three commands above. -Since there are many different ways to compute CRC's for the debug link -(different polynomials, reversals, byte ordering, etc.). This computation does -not apply to the build id section. The simplest way to describe the CRC used -in @code{.gnu_debuglink} sections is to give the complete code for a function -that computes it: +Since there are many different ways to compute CRC's for the debug +link (different polynomials, reversals, byte ordering, etc.), the +simplest way to describe the CRC used in @code{.gnu_debuglink} +sections is to give the complete code for a function that computes it: @kindex gnu_debuglink_crc32 @smallexample @@ -12097,6 +12119,9 @@ @} @end smallexample +@noindent +This computation does not apply to the ``build ID'' method. + @node Symbol Errors @section Errors Reading Symbol Files ----------------- The full text of the section ------------------ @node Separate Debug Files @section Debugging Information in Separate Files @cindex separate debugging information files @cindex debugging information in separate files @cindex @file{.debug} subdirectories @cindex debugging information directory, global @cindex global debugging information directory @cindex build ID, and separate debugging files @cindex @file{.build-id} directory @value{GDBN} allows you to put a program's debugging information in a file separate from the executable itself, in a way that allows @value{GDBN} to find and load the debugging information automatically. Since debugging information can be very large---sometimes larger than the executable code itself---some systems distribute debugging information for their executables in separate files, which users can install only when they need to debug a problem. @value{GDBN} supports two ways of specifying the separate debug info file: @itemize @bullet @item The executable contains a @dfn{debug link} that specifies the name of the separate debug info file. The separate debug file's name is usually @file{@var{executable}.debug}, where @var{executable} is the name of the corresponding executable file without leading directories (e.g., @file{ls.debug} for @file{/usr/bin/ls}). In addition, the debug link specifies a CRC32 checksum for the debug file, which @value{GDBN} uses to validate that the executable and the debug file came from the same build. @item The executable contains a @dfn{build ID}, a unique signature that is also present in the corresponding debug info file. (This is supported only on some operating systems, notably on @sc{gnu}/Linux. For more details about this feature, see @uref{http://fedoraproject.org/wiki/Releases/FeatureBuildId, the Fedora Project's description of the buid ID feature}.) The debug info file's name is not specified explicitly by the debug ID, but can be computed from the build ID, see below. @end itemize Depending on the way the debug info file is specified, @value{GDBN} uses two different methods of looking for the debug file: @itemize @bullet @item For the ``debug link'' method, @value{GDBN} looks up the named file in the directory of the executable file, then in a subdirectory of that directory named @file{.debug}, and finally under the global debug directory, in a subdirectory whose name is identical to the leading directories of the executable's absolute file name. @item For the ``debug ID'' method, @value{GDBN} looks in the @file{.build-id} subdirectory of the global debug directory for a file named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the first 2 hex characters of the debug ID signature, and @var{nnnnnnnn} are the rest of the signature. (Real signatures are 32 or more characters, not 10.) @end itemize So, for example, suppose you ask @value{GDBN} to debug @file{/usr/bin/ls}, which has a @dfn{debug link} that specifies the file @file{ls.debug}, and a @dfn{build id} whose value in hex is @code{abcdef1234}. If the global debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look for the following debug information files, in the indicated order: @itemize @minus @item @file{/usr/lib/debug/.build-id/ab/cdef1234.debug} @item @file{/usr/bin/ls.debug} @item @file{/usr/bin/.debug/ls.debug} @item @file{/usr/lib/debug/usr/bin/ls.debug}. @end itemize You can set the global debugging info directory's name, and view the 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}. @kindex show debug-file-directory @item show debug-file-directory Show the directory @value{GDBN} searches for separate debugging information files. @end table @cindex @code{.gnu_debuglink} sections @cindex debug link sections A debug link is a special section of the executable file named @code{.gnu_debuglink}. The section must contain: @itemize @item A filename, with any leading directory components removed, followed by a zero byte, @item zero to three bytes of padding, as needed to reach the next four-byte boundary within the section, and @item a four-byte CRC checksum, stored in the same endianness used for the executable file itself. The checksum is computed on the debugging information file's full contents by the function given below, passing zero as the @var{crc} argument. @end itemize Any executable file format can carry a debug link, as long as it can contain a section named @code{.gnu_debuglink} with the contents described above. @cindex @code{.note.gnu.build-id} sections @cindex build ID sections A build ID is a special section of the executable file named @code{.note.gnu.build-id}. This section contains unique identification for the built files---it remains the same across multiple builds of the same build tree. The default algorithm SHA1 produces 160 bits (40 hexadecimal characters) of the content. The same section with an identical value is present in the original built binary with symbols, in its stripped variant, and in the separate debugging information file. The debugging information file itself should be an ordinary executable, containing a full set of linker symbols, sections, and debugging information. The sections of the debugging information file should have the same names, addresses, and sizes as the original file, but they need not contain any data---much like a @code{.bss} section in an ordinary executable. @sc{gnu} binary utilities (Binutils) package includes the @samp{objcopy} utility that can produce the separated executable / debugging information file pairs using the following commands: @example @kbd{objcopy --only-keep-debug foo foo.debug} @kbd{strip -g foo} @kbd{objcopy --add-gnu-debuglink="foo.debug" "foo"} @end example @noindent These commands remove the debugging information from the executable file @file{foo}, place it in the file @file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich Drepper's @file{elfutils} package, starting with version 0.53, contains a version of the @code{strip} command such that the command @kbd{strip foo -f foo.debug} has the same functionality as the three commands above. Since there are many different ways to compute CRC's for the debug link (different polynomials, reversals, byte ordering, etc.), the simplest way to describe the CRC used in @code{.gnu_debuglink} sections is to give the complete code for a function that computes it: @kindex gnu_debuglink_crc32 @smallexample unsigned long gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len) @{ static const unsigned long crc32_table[256] = @{ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d @}; unsigned char *end; crc = ~crc & 0xffffffff; for (end = buf + len; buf < end; ++buf) crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); return ~crc & 0xffffffff; @} @end smallexample @noindent This computation does not apply to the ``build ID'' method. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 10:31 ` [patch] " Eli Zaretskii @ 2007-09-01 11:35 ` Jan Kratochvil 2007-09-01 12:15 ` Eli Zaretskii 0 siblings, 1 reply; 25+ messages in thread From: Jan Kratochvil @ 2007-09-01 11:35 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches, roland [-- Attachment #1: Type: text/plain, Size: 3505 bytes --] Hi, On Sat, 01 Sep 2007 12:31:07 +0200, Eli Zaretskii wrote: ... > I attach below the changes I committed to the manual, thanks, sure more readable. ... > . The Fedora site that describes the build ID features seems to say > that there are TWO files (actually symlinks) in the global debug > directory for each executable: ab/cdef1234 and ab/cdef1234.debug. > By contrast, you only talk about a single file. The file ab/cdef1234 points to the main executable (or shared library), it is not used by this patch so far. Going to submit now the second part of the patch which automatically finds the matching executable / shared libraries according to the build-id signatures left stored in a core file. There should be probably a new section in the documentation for it afterwards. > . The Fedora site says that the build ID symlinks are created only > in the global debug directory. However, your patch seems to say > that GDB looks for these symlinks in all the other possible > locations as well: > > @value{GDBN} checks under each of these names for a debugging > +information file with build id content matching the build id content of the > +executable file - or - whose checksum matches the one given in the link in the > +debug link case. > > Which one is true? Wrong/ambiguous is my wording. Your current sectence `GDB will look for the following debug information files, in the indicated order' is definitely right so I expect your current documentation version can be kept this way. > . The objcopy commands shown in your patch seem to be relevant only > to the ``debug link'' method (at least that's what I understand > from the last objcopy command). If so, I think we should say what > are the corresponding commands for the ``debug ID'' method. > Likewise, if there are (or going to be) features in elfutils that > support ``debug ID'', I think we should mention them, as we do for > ``debug links'' now. ``debug ID'' gets included by `ld --build-id', therefore by `gcc -Wl,--build-id', it is still not default in FSF GCC. There are no specific splitting commands required (such as `objcopy --add-gnu-debuglink' for the former "debug link". Older binutils strip ``debug ID'' during the file split, binutils since binutils-2.17.50.0.18 became compatible. Included a new doc paragraph. > . I'm confused by your mentioning of ``all files'' in this passage: > > +@dfn{build id} is present in all the files [...] > > as opposed to ``only the executable'' in the debug link case: > > +@dfn{debug link} is present only in the executable [...] > > I don't understand this distinction. As far as I could glean from > the build ID description on the Fedora site, the difference is > that the build ID is present both in the executable and in the > debug info file, whereas the debug link is present only in the > executable. Thus we have two files (maybe 3, if core dumps are > counted), vs one, not ``only one'' vs ``all''. Did I miss > something? You are right and your wording in the doc is also OK: The executable contains a "build ID", a unique signature that is also present in the corresponding debug info file. ... > Btw, I think this change warrants an entry in NEWS. I delayed it after the second part (locating the files from the core file signatures) but still the entry can be updated later. NEWS/doc patch included below. Thanks, Jan [-- Attachment #2: gdb-build-id-news-and-build.patch --] [-- Type: text/plain, Size: 1799 bytes --] 2007-09-01 Jan Kratochvil <jan.kratochvil@redhat.com> * NEWS: Mention the build-id .debug files verification. 2007-09-01 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Separate Debug Files): Cosmetic quoting removal. New binaries build instructions for the ``build ID'' inclusion. --- gdb/NEWS 28 Aug 2007 19:57:11 -0000 1.236 +++ gdb/NEWS 1 Sep 2007 11:29:43 -0000 @@ -61,6 +61,9 @@ Windows and SymbianOS). * The GDB remote stub, gdbserver, now supports dynamic link libraries (DLLs) on Windows and Windows CE targets. +* GDB now supports a faster verification a .debug file matches its binary +according to its build-id signature, if the signature present. + * New commands set remoteflow --- gdb/doc/gdb.texinfo 1 Sep 2007 10:28:25 -0000 1.426 +++ gdb/doc/gdb.texinfo 1 Sep 2007 11:29:53 -0000 @@ -12033,7 +12033,7 @@ following commands: @smallexample @kbd{objcopy --only-keep-debug foo foo.debug} @kbd{strip -g foo} -@kbd{objcopy --add-gnu-debuglink="foo.debug" "foo"} +@kbd{objcopy --add-gnu-debuglink=foo.debug foo} @end smallexample @noindent @@ -12044,6 +12044,11 @@ Drepper's @file{elfutils} package, start a version of the @code{strip} command such that the command @kbd{strip foo -f foo.debug} has the same functionality as the three commands above. +``Debug ID'' gets embedded into the main executable using @code{ld --build-id} +or the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. ``Debug ID'' +support plus compatibility fixes for debug files separation are present in +@sc{gnu} binary utilities (Binutils) since version 2.17.50.0.18. + Since there are many different ways to compute CRC's for the debug link (different polynomials, reversals, byte ordering, etc.), the simplest way to describe the CRC used in @code{.gnu_debuglink} ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 11:35 ` Jan Kratochvil @ 2007-09-01 12:15 ` Eli Zaretskii 2007-09-01 13:12 ` Jan Kratochvil 2007-09-04 2:21 ` Roland McGrath 0 siblings, 2 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-09-01 12:15 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, roland > Date: Sat, 1 Sep 2007 13:35:30 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: gdb-patches@sourceware.org, roland@redhat.com > > > . The objcopy commands shown in your patch seem to be relevant only > > to the ``debug link'' method (at least that's what I understand > > from the last objcopy command). If so, I think we should say what > > are the corresponding commands for the ``debug ID'' method. > > Likewise, if there are (or going to be) features in elfutils that > > support ``debug ID'', I think we should mention them, as we do for > > ``debug links'' now. > > ``debug ID'' gets included by `ld --build-id', therefore by `gcc > -Wl,--build-id', it is still not default in FSF GCC. There are no specific > splitting commands required (such as `objcopy --add-gnu-debuglink' for the > former "debug link". But the first command, the one to create the separate debug info file, is still needed, right? In any case, we should tell that these commands (or at least the last one) is only needed for the debug-link method. > --- gdb/NEWS 28 Aug 2007 19:57:11 -0000 1.236 > +++ gdb/NEWS 1 Sep 2007 11:29:43 -0000 > @@ -61,6 +61,9 @@ Windows and SymbianOS). > * The GDB remote stub, gdbserver, now supports dynamic link libraries > (DLLs) on Windows and Windows CE targets. > > +* GDB now supports a faster verification a .debug file matches its binary ^^^ "that" is missing here. > +according to its build-id signature, if the signature present. ^^^ "if the signature is present", the "is" part is missing. > +``Debug ID'' gets embedded into the main executable using @code{ld --build-id} > +or the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. ``Debug ID'' > +support plus compatibility fixes for debug files separation are present in > +@sc{gnu} binary utilities (Binutils) since version 2.17.50.0.18. This is fine, but there's no need to quote ``debug ID'' every time you use it. I quoted it only when I used it as a name of a method of embedding information about the debug file; in other cases I used it without quotes. Otherwise, these two patches are okay with me. Thanks. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 12:15 ` Eli Zaretskii @ 2007-09-01 13:12 ` Jan Kratochvil 2007-09-01 13:25 ` Mark Kettenis 2007-09-01 14:16 ` [patch] " Eli Zaretskii 2007-09-04 2:21 ` Roland McGrath 1 sibling, 2 replies; 25+ messages in thread From: Jan Kratochvil @ 2007-09-01 13:12 UTC (permalink / raw) To: Eli Zaretskii; +Cc: gdb-patches, roland [-- Attachment #1: Type: text/plain, Size: 353 bytes --] On Sat, 01 Sep 2007 14:15:07 +0200, Eli Zaretskii wrote: ... > But the first command, the one to create the separate debug info file, > is still needed, right? > > In any case, we should tell that these commands (or at least the last > one) is only needed for the debug-link method. Enhanced the section I hope according to your advice. Thanks, Jan [-- Attachment #2: gdb-build-id-news-and-build2.patch --] [-- Type: text/plain, Size: 3636 bytes --] 2007-09-01 Jan Kratochvil <jan.kratochvil@redhat.com> * NEWS: Mention the build-id .debug files verification. 2007-09-01 Jan Kratochvil <jan.kratochvil@redhat.com> * gdb.texinfo (Separate Debug Files): Cosmetic quoting removal. Fixed the ``build ID'' name. New binaries build instructions for the build ID inclusion. Explain how the commands are specific to the build ID vs. debug link. --- gdb/NEWS 28 Aug 2007 19:57:11 -0000 1.236 +++ gdb/NEWS 1 Sep 2007 13:06:23 -0000 @@ -61,6 +61,9 @@ Windows and SymbianOS). * The GDB remote stub, gdbserver, now supports dynamic link libraries (DLLs) on Windows and Windows CE targets. +* GDB now supports a faster verification that a .debug file matches its binary +according to its build-id signature, if the signature is present. + * New commands set remoteflow --- gdb/doc/gdb.texinfo 1 Sep 2007 10:28:25 -0000 1.426 +++ gdb/doc/gdb.texinfo 1 Sep 2007 13:06:32 -0000 @@ -11925,7 +11925,7 @@ only on some operating systems, notably details about this feature, see @uref{http://fedoraproject.org/wiki/Releases/FeatureBuildId, the Fedora Project's description of the buid ID feature}.) The debug info -file's name is not specified explicitly by the debug ID, but can be +file's name is not specified explicitly by the build ID, but can be computed from the build ID, see below. @end itemize @@ -11941,10 +11941,10 @@ directory, in a subdirectory whose name directories of the executable's absolute file name. @item -For the ``debug ID'' method, @value{GDBN} looks in the +For the ``build ID'' method, @value{GDBN} looks in the @file{.build-id} subdirectory of the global debug directory for a file named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the -first 2 hex characters of the debug ID signature, and @var{nnnnnnnn} +first 2 hex characters of the build ID signature, and @var{nnnnnnnn} are the rest of the signature. (Real signatures are 32 or more characters, not 10.) @end itemize @@ -12033,16 +12033,36 @@ following commands: @smallexample @kbd{objcopy --only-keep-debug foo foo.debug} @kbd{strip -g foo} -@kbd{objcopy --add-gnu-debuglink="foo.debug" "foo"} @end smallexample @noindent These commands remove the debugging -information from the executable file @file{foo}, place it in the file -@file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich -Drepper's @file{elfutils} package, starting with version 0.53, contains +information from the executable file @file{foo} and place it in the file +@file{foo.debug}. You can use the first, second or both methods to link the +two files: + +@itemize @bullet +@item +The debug link method needs the following additional command to also leave +behind a debug link in @file{foo}: + +@smallexample +@kbd{objcopy --add-gnu-debuglink=foo.debug foo} +@end smallexample + +Ulrich Drepper's @file{elfutils} package, starting with version 0.53, contains a version of the @code{strip} command such that the command @kbd{strip foo -f -foo.debug} has the same functionality as the three commands above. +foo.debug} has the same functionality as the two separating commands and the +one linking command above. + +@item +Build ID gets embedded into the main executable using @code{ld --build-id} or +the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. Build ID support plus +compatibility fixes for debug files separation are present in @sc{gnu} binary +utilities (Binutils) since version 2.17.50.0.18. +@end itemize + +@noindent Since there are many different ways to compute CRC's for the debug link (different polynomials, reversals, byte ordering, etc.), the ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 13:12 ` Jan Kratochvil @ 2007-09-01 13:25 ` Mark Kettenis 2007-09-01 14:22 ` Eli Zaretskii 2007-09-02 13:57 ` [patch approved?] [doc] " Jan Kratochvil 2007-09-01 14:16 ` [patch] " Eli Zaretskii 1 sibling, 2 replies; 25+ messages in thread From: Mark Kettenis @ 2007-09-01 13:25 UTC (permalink / raw) To: jan.kratochvil; +Cc: eliz, gdb-patches, roland > Date: Sat, 1 Sep 2007 15:12:12 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > +@item > +Build ID gets embedded into the main executable using @code{ld --build-id} or > +the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. Build ID support plus > +compatibility fixes for debug files separation are present in @sc{gnu} binary > +utilities (Binutils) since version 2.17.50.0.18. > +@end itemize I think we should stick with references to official GNU releases in our documentation. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 13:25 ` Mark Kettenis @ 2007-09-01 14:22 ` Eli Zaretskii 2007-09-02 13:57 ` [patch approved?] [doc] " Jan Kratochvil 1 sibling, 0 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-09-01 14:22 UTC (permalink / raw) To: Mark Kettenis; +Cc: gdb-patches, roland > Date: Sat, 1 Sep 2007 15:25:14 +0200 (CEST) > From: Mark Kettenis <mark.kettenis@xs4all.nl> > CC: eliz@gnu.org, gdb-patches@sourceware.org, roland@redhat.com > > I think we should stick with references to official GNU releases in > our documentation. I'd support that if most installations had official versions. But that doesn't seem to be the case in the recent years: almost every GNU/Linux box I get my hands on have "2.aa.bb YYYYMMDD" version on it. Here's a typical example (from none other than a gnu.org machine, btw): eliz@fencepost:~$ ld --version GNU ld version 2.16.91 20060118 Debian GNU/Linux Given that this seems to be the rule rather than exception, I see no sense in insisting that unofficial versions do not exist, or aren't used widely enough to be mentioned in the docs. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approved?] [doc] build-id .debug files load (like .gnu_debuglink) 2007-09-01 13:25 ` Mark Kettenis 2007-09-01 14:22 ` Eli Zaretskii @ 2007-09-02 13:57 ` Jan Kratochvil 2007-09-02 17:49 ` Mark Kettenis 2007-09-02 19:38 ` Eli Zaretskii 1 sibling, 2 replies; 25+ messages in thread From: Jan Kratochvil @ 2007-09-02 13:57 UTC (permalink / raw) To: Eli Zaretskii, Mark Kettenis; +Cc: gdb-patches [-- Attachment #1: Type: text/plain, Size: 550 bytes --] Hi, I expect the patch is OK this way. Thanks, Jan On Sat, 01 Sep 2007 16:16:21 +0200, Eli Zaretskii wrote: ... > I'd suggest to rewrite this as follows: > > +foo.debug} has the same functionality as the two @code{objcopy} commands > +and the @code{ln -s} command above, together. Used this version. On Sat, 01 Sep 2007 15:25:14 +0200, Mark Kettenis wrote: ... > > +utilities (Binutils) since version 2.17.50.0.18. > > +@end itemize > > I think we should stick with references to official GNU releases in > our documentation. Used 2.18. [-- Attachment #2: gdb-build-id-news-and-build3.patch --] [-- Type: text/plain, Size: 3678 bytes --] 2007-09-02 Jan Kratochvil <jan.kratochvil@redhat.com> * NEWS: Mention the build-id .debug files verification. 2007-09-02 Jan Kratochvil <jan.kratochvil@redhat.com> Eli Zaretskii <eliz@gnu.org> * gdb.texinfo (Separate Debug Files): Cosmetic quoting removal. Fixed the ``build ID'' name. New binaries build instructions for the build ID inclusion. Explain how the commands are specific to the build ID vs. debug link. --- gdb/NEWS 28 Aug 2007 19:57:11 -0000 1.236 +++ gdb/NEWS 2 Sep 2007 13:48:35 -0000 @@ -61,6 +61,9 @@ Windows and SymbianOS). * The GDB remote stub, gdbserver, now supports dynamic link libraries (DLLs) on Windows and Windows CE targets. +* GDB now supports a faster verification that a .debug file matches its binary +according to its build-id signature, if the signature is present. + * New commands set remoteflow --- gdb/doc/gdb.texinfo 1 Sep 2007 10:28:25 -0000 1.426 +++ gdb/doc/gdb.texinfo 2 Sep 2007 13:48:45 -0000 @@ -11925,7 +11925,7 @@ only on some operating systems, notably details about this feature, see @uref{http://fedoraproject.org/wiki/Releases/FeatureBuildId, the Fedora Project's description of the buid ID feature}.) The debug info -file's name is not specified explicitly by the debug ID, but can be +file's name is not specified explicitly by the build ID, but can be computed from the build ID, see below. @end itemize @@ -11941,10 +11941,10 @@ directory, in a subdirectory whose name directories of the executable's absolute file name. @item -For the ``debug ID'' method, @value{GDBN} looks in the +For the ``build ID'' method, @value{GDBN} looks in the @file{.build-id} subdirectory of the global debug directory for a file named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the -first 2 hex characters of the debug ID signature, and @var{nnnnnnnn} +first 2 hex characters of the build ID signature, and @var{nnnnnnnn} are the rest of the signature. (Real signatures are 32 or more characters, not 10.) @end itemize @@ -12033,16 +12033,36 @@ following commands: @smallexample @kbd{objcopy --only-keep-debug foo foo.debug} @kbd{strip -g foo} -@kbd{objcopy --add-gnu-debuglink="foo.debug" "foo"} @end smallexample @noindent These commands remove the debugging -information from the executable file @file{foo}, place it in the file -@file{foo.debug}, and leave behind a debug link in @file{foo}. Ulrich -Drepper's @file{elfutils} package, starting with version 0.53, contains +information from the executable file @file{foo} and place it in the file +@file{foo.debug}. You can use the first, second or both methods to link the +two files: + +@itemize @bullet +@item +The debug link method needs the following additional command to also leave +behind a debug link in @file{foo}: + +@smallexample +@kbd{objcopy --add-gnu-debuglink=foo.debug foo} +@end smallexample + +Ulrich Drepper's @file{elfutils} package, starting with version 0.53, contains a version of the @code{strip} command such that the command @kbd{strip foo -f -foo.debug} has the same functionality as the three commands above. +foo.debug} has the same functionality as the two @code{objcopy} commands and +the @code{ln -s} command above, together. + +@item +Build ID gets embedded into the main executable using @code{ld --build-id} or +the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. Build ID support plus +compatibility fixes for debug files separation are present in @sc{gnu} binary +utilities (Binutils) since version 2.18. +@end itemize + +@noindent Since there are many different ways to compute CRC's for the debug link (different polynomials, reversals, byte ordering, etc.), the ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approved?] [doc] build-id .debug files load (like .gnu_debuglink) 2007-09-02 13:57 ` [patch approved?] [doc] " Jan Kratochvil @ 2007-09-02 17:49 ` Mark Kettenis 2007-09-02 19:38 ` Eli Zaretskii 1 sibling, 0 replies; 25+ messages in thread From: Mark Kettenis @ 2007-09-02 17:49 UTC (permalink / raw) To: jan.kratochvil; +Cc: eliz, mark.kettenis, gdb-patches > Date: Sun, 2 Sep 2007 15:56:36 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > > On Sat, 01 Sep 2007 15:25:14 +0200, Mark Kettenis wrote: > ... > > > +utilities (Binutils) since version 2.17.50.0.18. > > > +@end itemize > > > > I think we should stick with references to official GNU releases in > > our documentation. > > Used 2.18. Fine with me, thanks! ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch approved?] [doc] build-id .debug files load (like .gnu_debuglink) 2007-09-02 13:57 ` [patch approved?] [doc] " Jan Kratochvil 2007-09-02 17:49 ` Mark Kettenis @ 2007-09-02 19:38 ` Eli Zaretskii 1 sibling, 0 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-09-02 19:38 UTC (permalink / raw) To: Jan Kratochvil; +Cc: mark.kettenis, gdb-patches > Date: Sun, 2 Sep 2007 15:56:36 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: gdb-patches@sourceware.org > > I expect the patch is OK this way. Yes, thanks. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 13:12 ` Jan Kratochvil 2007-09-01 13:25 ` Mark Kettenis @ 2007-09-01 14:16 ` Eli Zaretskii 1 sibling, 0 replies; 25+ messages in thread From: Eli Zaretskii @ 2007-09-01 14:16 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches, roland > Date: Sat, 1 Sep 2007 15:12:12 +0200 > From: Jan Kratochvil <jan.kratochvil@redhat.com> > Cc: gdb-patches@sourceware.org, roland@redhat.com > > On Sat, 01 Sep 2007 14:15:07 +0200, Eli Zaretskii wrote: > ... > > But the first command, the one to create the separate debug info file, > > is still needed, right? > > > > In any case, we should tell that these commands (or at least the last > > one) is only needed for the debug-link method. > > Enhanced the section I hope according to your advice. Thanks, this is okay. > +foo.debug} has the same functionality as the two separating commands and the > +one linking command above. I'd suggest to rewrite this as follows: +foo.debug} has the same functionality as the two @code{objcopy} commands +and the @code{ln -s} command above, together. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-01 12:15 ` Eli Zaretskii 2007-09-01 13:12 ` Jan Kratochvil @ 2007-09-04 2:21 ` Roland McGrath 2007-09-04 3:23 ` Eli Zaretskii 1 sibling, 1 reply; 25+ messages in thread From: Roland McGrath @ 2007-09-04 2:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Jan Kratochvil, gdb-patches > But the first command, the one to create the separate debug info file, > is still needed, right? Nothing about the recommended user procedure for making separate debug files has changed. Using --add-gnu-debuglink is not strictly required when using only new consumers that honor build ID notes, and dealing only with binaries that were linked with ld --build-id. But there is no reason not to do it and it is still required in the event of linking without --build-id or if concerned with all existing tools that understand .gnu_debuglink but not build ID notes. It is the case that strip and objcopy behavior wrt allocated notes sections has changed, and that the new behavior is required for build IDs to be preserved in separate debug files. However, I don't think there is any reason to burden the user with these details explicitly in the primary documentation on the subject. (Hence, there is no need to worry about how to identify versions of binutils here in the manual.) No version, derivative release, snapshot, or chronological state of development in binutils has included an ld supporting --build-id but an objcopy that treated it with the old rules. The objcopy and other tools involved in splitting a binary into a separate debug file should be no older than the ld used to create the original binary. If anything, that's all that needs to be said in the recipe. It's beyond unusual for the ld and objcopy et al one is usng not to have come from the very same build/package, so it's really not something to worry about. > This is fine, but there's no need to quote ``debug ID'' every time you > use it. I quoted it only when I used it as a name of a method of > embedding information about the debug file; in other cases I used it > without quotes. The canonical term is "build ID", and I do not think it is helpful to introduce "debug ID" in any documentation. In fact, the feature per se does not relate directly to debugging information, though that is indeed the largest motivation for its use. It is also not good to use the term "signature" loosely with relation to build ID bits. I would prefer to avoid that term entirely, except perhaps in a section devoted to discussing selection of ID bits and the issues of uniqueness and repeatability in detail. I am concerned about too easily creating misunderstandings that build ID bits relate to some sort of guarantee about the origin of binaries or security checks, which they do not. (As far as the fundamental feature itself goes, a build ID gives some bits that the creator of the binary decided to tell you were useful as an identifier for the binary. binutils and ld have nothing more to say about it than that.) Thanks, Roland ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-04 2:21 ` Roland McGrath @ 2007-09-04 3:23 ` Eli Zaretskii 2007-09-04 7:21 ` Roland McGrath 0 siblings, 1 reply; 25+ messages in thread From: Eli Zaretskii @ 2007-09-04 3:23 UTC (permalink / raw) To: Roland McGrath; +Cc: jan.kratochvil, gdb-patches > From: Roland McGrath <roland@redhat.com> > Cc: Jan Kratochvil <jan.kratochvil@redhat.com>, > gdb-patches@sourceware.org > Date: Mon, 3 Sep 2007 19:21:23 -0700 (PDT) > > > This is fine, but there's no need to quote ``debug ID'' every time you > > use it. I quoted it only when I used it as a name of a method of > > embedding information about the debug file; in other cases I used it > > without quotes. > > The canonical term is "build ID", and I do not think it is helpful to > introduce "debug ID" in any documentation. We don't introduce such a new term, the above was a typo. The manual does not use this term anywhere, it uses "build ID". > It is also not good to use the term "signature" loosely with relation to > build ID bits. What alternative term would you suggest? I have no shares in this particular word, if a good alternative exists. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-04 3:23 ` Eli Zaretskii @ 2007-09-04 7:21 ` Roland McGrath 2007-09-15 9:52 ` Eli Zaretskii 0 siblings, 1 reply; 25+ messages in thread From: Roland McGrath @ 2007-09-04 7:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jan.kratochvil, gdb-patches > We don't introduce such a new term, the above was a typo. The manual > does not use this term anywhere, it uses "build ID". Great. > > It is also not good to use the term "signature" loosely with relation to > > build ID bits. > > What alternative term would you suggest? I have no shares in this > particular word, if a good alternative exists. Well, there is "ID". Also "bit string", or "set of bits", or "sequence of bytes" come to mind. Whatever flows in the particular context to say what is so, which is that it is a small chunk of data taken solely as an identifier with no instrinsic meaning to its bits. The text I wrote in the ld manual (ld/ld.texinfo @node Options) uses "unique bits" and "bit string". Also, I don't think it is proper to refer to this as GNU/Linux operating system magic and refer to the Fedora wiki. The build ID note is a GNU convention for ELF binaries and the tool involved in creating it is GNU ld. It is the linker, and how the linker is used, that determines whether creating a binary normally gives it one. The GDB manual should refer directly to the GNU ld manual about how it's created. If you mean the manual to document precise format details, then it should not say that a build ID section is "named @code{.note.gnu.build-id}". That is the name of the input section that ld synthesizes under --build-id, and will often be the name of the final section seen in an executable or DSO. But the name is in no way magical and any tool would be broken if it worked only on a section by that name. It should be mentioned only as a common case. It is only the normative ELF data that controls what constitutes a proper build ID in an ELF file. That is, SHT_NOTE sections, or PT_NOTE segments in sectionless files, with proper ELF note formats of name "GNU" and type NT_GNU_BUILD_ID. The wording now says "executable" a lot, while in reality it can be any kind of ELF file that gdb would consider. That is, executables or DSOs (ET_EXEC/ET_DYN), or ET_REL files that are contemplated in their own right, as is done for Linux kernel modules. For all of these, gdb can find separate debug info, and should use build IDs to do so. Thanks, Roland ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-04 7:21 ` Roland McGrath @ 2007-09-15 9:52 ` Eli Zaretskii 2007-09-16 17:19 ` Roland McGrath 0 siblings, 1 reply; 25+ messages in thread From: Eli Zaretskii @ 2007-09-15 9:52 UTC (permalink / raw) To: Roland McGrath; +Cc: jan.kratochvil, gdb-patches > From: Roland McGrath <roland@redhat.com> > Cc: jan.kratochvil@redhat.com, gdb-patches@sourceware.org > Date: Tue, 4 Sep 2007 00:21:29 -0700 (PDT) > > > > It is also not good to use the term "signature" loosely with relation to > > > build ID bits. > > > > What alternative term would you suggest? I have no shares in this > > particular word, if a good alternative exists. > > Well, there is "ID". Also "bit string", or "set of bits", or "sequence of > bytes" come to mind. Whatever flows in the particular context to say what > is so, which is that it is a small chunk of data taken solely as an > identifier with no instrinsic meaning to its bits. The text I wrote in the > ld manual (ld/ld.texinfo @node Options) uses "unique bits" and "bit string". > > Also, I don't think it is proper to refer to this as GNU/Linux operating > system magic and refer to the Fedora wiki. The build ID note is a GNU > convention for ELF binaries and the tool involved in creating it is GNU ld. > It is the linker, and how the linker is used, that determines whether > creating a binary normally gives it one. The GDB manual should refer > directly to the GNU ld manual about how it's created. > > If you mean the manual to document precise format details, then it should > not say that a build ID section is "named @code{.note.gnu.build-id}". That > is the name of the input section that ld synthesizes under --build-id, and > will often be the name of the final section seen in an executable or DSO. > But the name is in no way magical and any tool would be broken if it worked > only on a section by that name. It should be mentioned only as a common > case. It is only the normative ELF data that controls what constitutes a > proper build ID in an ELF file. That is, SHT_NOTE sections, or PT_NOTE > segments in sectionless files, with proper ELF note formats of name "GNU" > and type NT_GNU_BUILD_ID. > > The wording now says "executable" a lot, while in reality it can be any > kind of ELF file that gdb would consider. That is, executables or DSOs > (ET_EXEC/ET_DYN), or ET_REL files that are contemplated in their own right, > as is done for Linux kernel modules. For all of these, gdb can find > separate debug info, and should use build IDs to do so. Thanks for your comments and explanations. I believe I've fixed the manual according to your suggestions, the patch I committed is attached below. 2007-09-15 Eli Zaretskii <eliz@gnu.org> * gdb.texinfo (Separate Debug Files): More accurate wording regarding build ID and a reference to the ld manual rather than the Fedora wiki. Index: gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.430 diff -u -r1.430 gdb.texinfo --- gdb.texinfo 15 Sep 2007 08:54:26 -0000 1.430 +++ gdb.texinfo 15 Sep 2007 09:48:18 -0000 @@ -11933,14 +11933,15 @@ came from the same build. @item -The executable contains a @dfn{build ID}, a unique signature that is +The executable contains a @dfn{build ID}, a unique bit string that is also present in the corresponding debug info file. (This is supported -only on some operating systems, notably on @sc{gnu}/Linux. For more -details about this feature, see -@uref{http://fedoraproject.org/wiki/Releases/FeatureBuildId, the -Fedora Project's description of the buid ID feature}.) The debug info -file's name is not specified explicitly by the build ID, but can be -computed from the build ID, see below. +only on some operating systems, notably those which use the ELF format +for binary files and the @sc{gnu} Binutils.) For more details about +this feature, see the description of the @option{--build-id} +command-line option in @ref{Options, , Command Line Options, ld.info, +The GNU Linker}. The debug info file's name is not specified +explicitly by the build ID, but can be computed from the build ID, see +below. @end itemize Depending on the way the debug info file is specified, @value{GDBN} @@ -11958,14 +11959,14 @@ For the ``build ID'' method, @value{GDBN} looks in the @file{.build-id} subdirectory of the global debug directory for a file named @file{@var{nn}/@var{nnnnnnnn}.debug}, where @var{nn} are the -first 2 hex characters of the build ID signature, and @var{nnnnnnnn} -are the rest of the signature. (Real signatures are 32 or more -characters, not 10.) +first 2 hex characters of the build ID bit string, and @var{nnnnnnnn} +are the rest of the bit string. (Real build ID strings are 32 or more +hex characters, not 10.) @end itemize So, for example, suppose you ask @value{GDBN} to debug -@file{/usr/bin/ls}, which has a @dfn{debug link} that specifies the -file @file{ls.debug}, and a @dfn{build id} whose value in hex is +@file{/usr/bin/ls}, which has a debug link that specifies the +file @file{ls.debug}, and a build ID whose value in hex is @code{abcdef1234}. If the global debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look for the following debug information files, in the indicated order: @@ -12023,14 +12024,15 @@ @cindex @code{.note.gnu.build-id} sections @cindex build ID sections -A build ID is a special section of the executable file named -@code{.note.gnu.build-id}. This section contains unique -identification for the built files---it remains the same across -multiple builds of the same build tree. The default algorithm SHA1 -produces 160 bits (40 hexadecimal characters) of the content. The -same section with an identical value is present in the original built -binary with symbols, in its stripped variant, and in the separate -debugging information file. +The build ID is a special section in the executable file (and in other +ELF binary files that @value{GDBN} may consider). This section is +often named @code{.note.gnu.build-id}, but that name is not mandatory. +It contains unique identification for the built files---the ID remains +the same across multiple builds of the same build tree. The default +algorithm SHA1 produces 160 bits (40 hexadecimal characters) of the +content for the build ID string. The same section with an identical +value is present in the original built binary with symbols, in its +stripped variant, and in the separate debugging information file. The debugging information file itself should be an ordinary executable, containing a full set of linker symbols, sections, and @@ -12039,7 +12041,7 @@ but they need not contain any data---much like a @code{.bss} section in an ordinary executable. -@sc{gnu} binary utilities (Binutils) package includes the +The @sc{gnu} binary utilities (Binutils) package includes the @samp{objcopy} utility that can produce the separated executable / debugging information file pairs using the following commands: @@ -12073,7 +12075,7 @@ Build ID gets embedded into the main executable using @code{ld --build-id} or the @value{NGCC} counterpart @code{gcc -Wl,--build-id}. Build ID support plus compatibility fixes for debug files separation are present in @sc{gnu} binary -utilities (Binutils) since version 2.18. +utilities (Binutils) package since version 2.18. @end itemize @noindent ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-09-15 9:52 ` Eli Zaretskii @ 2007-09-16 17:19 ` Roland McGrath 0 siblings, 0 replies; 25+ messages in thread From: Roland McGrath @ 2007-09-16 17:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jan.kratochvil, gdb-patches That looks ok to me. If you want to be technically precise, the build ID note is not necessarily a section per se. It's an input section, but may be just part of the middle of a larger output section. Precisely speaking, it's an ELF note, which is a self-identifying portion of a SHT_NOTE section or of the linked image as selected by a PT_NOTE program header. Thanks, Roland ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [patch] build-id .debug files load (like .gnu_debuglink) 2007-08-24 18:05 [patch] build-id .debug files load (like .gnu_debuglink) Jan Kratochvil 2007-08-24 18:20 ` Daniel Jacobowitz @ 2007-08-25 22:48 ` Roland McGrath 1 sibling, 0 replies; 25+ messages in thread From: Roland McGrath @ 2007-08-25 22:48 UTC (permalink / raw) To: Jan Kratochvil; +Cc: gdb-patches > This part may be questionable: > - debugfile = find_separate_debug_file (objfile); > + /* If the file has its own symbol tables it has no separate debug info. */ > + if (objfile->psymtabs == NULL) > + debugfile = find_separate_debug_file (objfile); As Daniel mentioned, this is certainly not correct. The main file might have a symbol table, but not have any debug info (i.e. DWARF sections). The condition I would use is the direct one: if the main file has no DWARF sections, then look for a separate debug file. > So far .gnu_debuglink existed only in the main file (not the .debug file) and > it existed only if the debug info was stripped to a separate file from it. This is still true. It's not entirely unreasonable to use presence of .gnu_debuglink as the sign that you should look for separate debug info, even if for the actual searching you ignore its contents when you have a build ID note. Thanks, Roland ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2007-09-16 17:19 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-24 18:05 [patch] build-id .debug files load (like .gnu_debuglink) Jan Kratochvil
2007-08-24 18:20 ` Daniel Jacobowitz
2007-08-25 22:49 ` Jan Kratochvil
2007-08-25 23:58 ` Daniel Jacobowitz
2007-08-26 9:41 ` Jan Kratochvil
2007-08-31 9:38 ` Eli Zaretskii
2007-08-31 20:51 ` [patch approval?] " Jan Kratochvil
2007-08-31 21:12 ` Daniel Jacobowitz
2007-09-01 8:01 ` Eli Zaretskii
[not found] ` <20070901081934.GA31205@host0.dyn.jankratochvil.net>
2007-09-01 10:31 ` [patch] " Eli Zaretskii
2007-09-01 11:35 ` Jan Kratochvil
2007-09-01 12:15 ` Eli Zaretskii
2007-09-01 13:12 ` Jan Kratochvil
2007-09-01 13:25 ` Mark Kettenis
2007-09-01 14:22 ` Eli Zaretskii
2007-09-02 13:57 ` [patch approved?] [doc] " Jan Kratochvil
2007-09-02 17:49 ` Mark Kettenis
2007-09-02 19:38 ` Eli Zaretskii
2007-09-01 14:16 ` [patch] " Eli Zaretskii
2007-09-04 2:21 ` Roland McGrath
2007-09-04 3:23 ` Eli Zaretskii
2007-09-04 7:21 ` Roland McGrath
2007-09-15 9:52 ` Eli Zaretskii
2007-09-16 17:19 ` Roland McGrath
2007-08-25 22:48 ` Roland McGrath
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox