From d9433c08c4c8292b9791d67f2e5dfb9601cfb627 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Mar 10 2008 10:05:57 +0000 Subject: - build-id warnings integrated more with rpm and the lists of the warnings got replaced usually by a single-line `debuginfo-install' advice. - FIXME: Testsuite needs an update for the new pre-prompt messages. --- diff --git a/gdb-6.6-buildid-locate.patch b/gdb-6.6-buildid-locate.patch index d7aa70f..10d981f 100644 --- a/gdb-6.6-buildid-locate.patch +++ b/gdb-6.6-buildid-locate.patch @@ -1,12 +1,16 @@ [base] +2007-10-16 Jan Kratochvil + + Port to GDB-6.7. + 2008-01-22 Jan Kratochvil option "build-id-core-loads": Fix it to be an "on"/"off" type. More intuitive build-id missing files messages. Lookup also the main executable from the rpm database. Suppress duplicite buil-id missing files warnings. -2008-01-24 Jan Kratochvil +2008-01-26 Jan Kratochvil Print the shared libraries names unconditionally. 2008-02-21 Jan Kratochvil @@ -15,9 +19,23 @@ New description of `build-id-verbose' in the documentation. Resolve the RH Bug 432164. -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/Makefile.in gdb-6.6-patched/gdb/Makefile.in ---- gdb-6.6-unpatched/gdb/Makefile.in 2008-02-21 04:44:49.000000000 +0100 -+++ gdb-6.6-patched/gdb/Makefile.in 2008-02-21 04:10:55.000000000 +0100 +2008-02-24 Jan Kratochvil + + Port to GDB-6.8pre. + +2008-03-09 Jan Kratochvil + + Implement the `debuginfo-install' rpm/yum integration. + Resolve the RH Bug 435581. + +2008-03-09 Jan Kratochvil + + Backport to GDB-6.6. + +Index: gdb-6.6/gdb/Makefile.in +=================================================================== +--- gdb-6.6.orig/gdb/Makefile.in 2008-03-10 00:42:35.000000000 +0100 ++++ gdb-6.6/gdb/Makefile.in 2008-03-10 00:42:35.000000000 +0100 @@ -383,7 +383,7 @@ INSTALLED_LIBS=-lbfd -lreadline -lopcode CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) \ $(XM_CLIBS) $(TM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ \ @@ -37,7 +55,17 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/Makefile.in gdb core-regset.o: core-regset.c $(defs_h) $(command_h) $(gdbcore_h) \ $(inferior_h) $(target_h) $(gdb_string_h) $(gregset_h) cp-abi.o: cp-abi.c $(defs_h) $(value_h) $(cp_abi_h) $(command_h) $(gdbcmd_h) \ -@@ -2785,7 +2786,8 @@ symfile.o: symfile.c $(defs_h) $(bfdlink +@@ -2009,7 +2010,8 @@ event-loop.o: event-loop.c $(defs_h) $(e + $(gdb_string_h) $(exceptions_h) $(gdb_assert_h) $(gdb_select_h) + event-top.o: event-top.c $(defs_h) $(top_h) $(inferior_h) $(target_h) \ + $(terminal_h) $(event_loop_h) $(event_top_h) $(interps_h) \ +- $(exceptions_h) $(gdbcmd_h) $(readline_h) $(readline_history_h) ++ $(exceptions_h) $(gdbcmd_h) $(readline_h) $(readline_history_h) \ ++ $(symfile_h) + exceptions.o: exceptions.c $(defs_h) $(exceptions_h) $(breakpoint_h) \ + $(target_h) $(inferior_h) $(annotate_h) $(ui_out_h) $(gdb_assert_h) \ + $(gdb_string_h) $(serial_h) +@@ -2785,7 +2787,8 @@ 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) \ @@ -47,9 +75,19 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/Makefile.in gdb 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) -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6.6-patched/gdb/corelow.c ---- gdb-6.6-unpatched/gdb/corelow.c 2008-02-21 04:44:49.000000000 +0100 -+++ gdb-6.6-patched/gdb/corelow.c 2008-02-21 04:10:55.000000000 +0100 +@@ -3216,7 +3219,7 @@ tui-hooks.o: $(srcdir)/tui/tui-hooks.c $ + tui-interp.o: $(srcdir)/tui/tui-interp.c $(defs_h) $(interps_h) $(top_h) \ + $(event_top_h) $(event_loop_h) $(ui_out_h) $(cli_out_h) \ + $(tui_data_h) $(readline_h) $(tui_win_h) $(tui_h) $(tui_io_h) \ +- $(exceptions_h) ++ $(exceptions_h) $(symtab_h) $(symfile_h) + $(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-interp.c + tui-io.o: $(srcdir)/tui/tui-io.c $(defs_h) $(target_h) \ + $(event_loop_h) $(event_top_h) $(command_h) $(top_h) $(tui_h) \ +Index: gdb-6.6/gdb/corelow.c +=================================================================== +--- gdb-6.6.orig/gdb/corelow.c 2006-04-18 21:20:06.000000000 +0200 ++++ gdb-6.6/gdb/corelow.c 2008-03-10 00:42:58.000000000 +0100 @@ -46,6 +46,10 @@ #include "gdb_assert.h" #include "exceptions.h" @@ -61,13 +99,13 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 #ifndef O_LARGEFILE -@@ -253,6 +257,57 @@ add_to_thread_list (bfd *abfd, asection +@@ -253,6 +257,56 @@ add_to_thread_list (bfd *abfd, asection inferior_ptid = pid_to_ptid (thread_id); /* Yes, make it current */ } +static int build_id_core_loads = 1; + -+static void ++static void +build_id_locate_exec (int from_tty) +{ + CORE_ADDR at_entry; @@ -89,8 +127,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 + if (exec_filename != NULL) + exec_file_attach (exec_filename, from_tty); + else -+ build_id_print_missing (_("the main executable file"), build_id_filename, -+ 1); ++ debug_print_missing (_("the main executable file"), build_id_filename); + xfree (build_id_filename); + + /* `.note.gnu.build-id' section exists even for files without a separate @@ -107,7 +144,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 + symbol_file_add_main (exec_filename, from_tty); + /* For EXEC_FILENAME NULL we were already complaining above. */ + if (symfile_objfile == NULL && exec_filename != NULL) -+ build_id_print_missing (exec_filename, build_id_filename, 1); ++ debug_print_missing (exec_filename, build_id_filename); + } + xfree (build_id_filename); + @@ -119,7 +156,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 /* This routine opens and sets up the core file bfd. */ static void -@@ -349,6 +404,15 @@ core_open (char *filename, int from_tty) +@@ -349,6 +403,15 @@ core_open (char *filename, int from_tty) ontop = !push_target (&core_ops); discard_cleanups (old_chain); @@ -135,7 +172,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 /* This is done first, before anything has a chance to query the inferior for information such as symbols. */ post_create_inferior (&core_ops, from_tty); -@@ -662,4 +726,11 @@ _initialize_corelow (void) +@@ -662,4 +725,11 @@ _initialize_corelow (void) if (!coreops_suppress_target) add_target (&core_ops); @@ -147,10 +184,11 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/corelow.c gdb-6 + NULL, NULL, NULL, + &setlist, &showlist); } -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/doc/gdb.texinfo gdb-6.6-patched/gdb/doc/gdb.texinfo ---- gdb-6.6-unpatched/gdb/doc/gdb.texinfo 2008-02-21 04:44:15.000000000 +0100 -+++ gdb-6.6-patched/gdb/doc/gdb.texinfo 2008-02-21 04:43:15.000000000 +0100 -@@ -11940,6 +11940,27 @@ information files. +Index: gdb-6.6/gdb/doc/gdb.texinfo +=================================================================== +--- gdb-6.6.orig/gdb/doc/gdb.texinfo 2008-03-10 00:42:35.000000000 +0100 ++++ gdb-6.6/gdb/doc/gdb.texinfo 2008-03-10 00:43:33.000000000 +0100 +@@ -11939,6 +11939,27 @@ information files. @end table @@ -158,7 +196,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/doc/gdb.texinfo + +@table @code + -+@kindex set build-id-verbose ++@kindex set build-id-verbose +@item set build-id-verbose 0 +No additional messages are printed. + @@ -178,10 +216,41 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/doc/gdb.texinfo @cindex @code{.gnu_debuglink} sections @cindex debug links A debug link is a special section of the executable file named -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/solib-svr4.c gdb-6.6-patched/gdb/solib-svr4.c ---- gdb-6.6-unpatched/gdb/solib-svr4.c 2008-02-21 04:44:49.000000000 +0100 -+++ gdb-6.6-patched/gdb/solib-svr4.c 2008-02-21 04:10:55.000000000 +0100 -@@ -943,10 +943,35 @@ svr4_current_sos (void) +Index: gdb-6.6/gdb/event-top.c +=================================================================== +--- gdb-6.6.orig/gdb/event-top.c 2006-12-06 17:54:13.000000000 +0100 ++++ gdb-6.6/gdb/event-top.c 2008-03-10 00:42:35.000000000 +0100 +@@ -33,6 +33,7 @@ + #include + #include "exceptions.h" + #include "cli/cli-script.h" /* for reset_command_nest_depth */ ++#include "symfile.h" + + /* For dont_repeat() */ + #include "gdbcmd.h" +@@ -194,6 +195,8 @@ cli_command_loop (void) + prompt, otherwise just print the prompt. */ + if (async_command_editing_p) + { ++ debug_flush_missing (); ++ + /* Tell readline what the prompt to display is and what function it + will need to call after a whole line is read. This also displays + the first prompt. */ +@@ -264,6 +267,8 @@ display_gdb_prompt (char *new_prompt) + /* Reset the nesting depth used when trace-commands is set. */ + reset_command_nest_depth (); + ++ debug_flush_missing (); ++ + /* Each interpreter has its own rules on displaying the command + prompt. */ + if (!current_interp_display_prompt_p ()) +Index: gdb-6.6/gdb/solib-svr4.c +=================================================================== +--- gdb-6.6.orig/gdb/solib-svr4.c 2008-03-10 00:42:32.000000000 +0100 ++++ gdb-6.6/gdb/solib-svr4.c 2008-03-10 00:42:35.000000000 +0100 +@@ -943,10 +943,36 @@ svr4_current_sos (void) } else { @@ -191,8 +260,6 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/solib-svr4.c gd + + strncpy (new->so_original_name, buffer, SO_NAME_MAX_PATH_SIZE - 1); + new->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; - xfree (buffer); -- strcpy (new->so_original_name, new->so_name); + /* May get overwritten below. */ + strcpy (new->so_name, new->so_original_name); + @@ -211,18 +278,22 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/solib-svr4.c gd + xfree (name); + } + else -+ build_id_print_missing (new->so_name, build_id_filename, -+ 1); ++ debug_print_missing (new->so_name, build_id_filename); ++ + xfree (build_id_filename); + xfree (build_id); + } + + xfree (buffer); +- strcpy (new->so_original_name, new->so_name); ++ if (debug_solib) { fprintf_unfiltered (gdb_stdlog, -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6.6-patched/gdb/symfile.c ---- gdb-6.6-unpatched/gdb/symfile.c 2008-02-21 04:46:25.000000000 +0100 -+++ gdb-6.6-patched/gdb/symfile.c 2008-02-21 04:47:36.000000000 +0100 +Index: gdb-6.6/gdb/symfile.c +=================================================================== +--- gdb-6.6.orig/gdb/symfile.c 2008-03-10 00:42:35.000000000 +0100 ++++ gdb-6.6/gdb/symfile.c 2008-03-10 00:43:24.000000000 +0100 @@ -54,6 +54,9 @@ #include "exec.h" #include "parser-defs.h" @@ -241,7 +312,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 int (*deprecated_ui_load_progress_hook) (const char *section, unsigned long num); -@@ -1141,16 +1145,65 @@ symbol_file_clear (int from_tty) +@@ -1120,16 +1124,65 @@ symbol_file_clear (int from_tty) printf_unfiltered (_("No symbol file now.\n")); } @@ -309,7 +380,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 { struct build_id *retval; -@@ -1166,6 +1219,348 @@ build_id_bfd_get (bfd *abfd) +@@ -1145,6 +1198,348 @@ build_id_bfd_get (bfd *abfd) return retval; } @@ -658,7 +729,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 /* Return if FILENAME has NT_GNU_BUILD_ID matching the CHECK value. */ static int -@@ -1180,7 +1575,7 @@ build_id_verify (const char *filename, s +@@ -1159,7 +1554,7 @@ build_id_verify (const char *filename, s if (abfd == NULL) return 0; @@ -667,7 +738,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 if (found == NULL) warning (_("File \"%s\" has no build-id, file skipped"), filename); -@@ -1198,8 +1593,9 @@ build_id_verify (const char *filename, s +@@ -1177,8 +1572,9 @@ build_id_verify (const char *filename, s static char *debug_file_directory = NULL; @@ -679,7 +750,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 { char *link, *s, *retval = NULL; gdb_byte *data = build_id->data; -@@ -1207,7 +1603,9 @@ build_id_to_debug_filename (struct build +@@ -1186,7 +1582,9 @@ build_id_to_debug_filename (struct build /* DEBUG_FILE_DIRECTORY/.build-id/ab/cdef */ link = xmalloc (strlen (debug_file_directory) + (sizeof "/.build-id/" - 1) + 1 @@ -690,7 +761,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 s = link + sprintf (link, "%s/.build-id/", debug_file_directory); if (size > 0) { -@@ -1218,12 +1616,14 @@ build_id_to_debug_filename (struct build +@@ -1197,12 +1595,14 @@ build_id_to_debug_filename (struct build *s++ = '/'; while (size-- > 0) s += sprintf (s, "%02x", (unsigned) *data++); @@ -707,7 +778,7 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 if (retval != NULL && !build_id_verify (retval, build_id)) { -@@ -1231,9 +1631,206 @@ build_id_to_debug_filename (struct build +@@ -1210,9 +1610,433 @@ build_id_to_debug_filename (struct build retval = NULL; } @@ -725,152 +796,378 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 +#include +#include + -+static void -+rpm_print_debuginfo (const char *filename) ++/* This MISSING_RPM_HASH tracker is used to collect all the missing rpm files ++ and avoid their duplicities during a single inferior run. */ ++ ++static struct htab *missing_rpm_hash; ++ ++/* This MISSING_RPM_LIST tracker is used to collect and print as a single line ++ all the rpms right before the nearest GDB prompt. It gets cleared after ++ each such print (it is questionable if we should clear it after the print). ++ */ ++ ++struct missing_rpm ++ { ++ struct missing_rpm *next; ++ char rpm[1]; ++ }; ++static struct missing_rpm *missing_rpm_list; ++static int missing_rpm_list_entries; ++ ++/* Returns the count of newly added rpms. */ ++ ++static int ++missing_rpm_enlist (const char *filename) +{ + static int rpm_init_done = 0; + rpmts ts; + rpmdbMatchIterator mi; ++ int count = 0; ++ ++ if (filename == NULL) ++ return 0; + + if (!rpm_init_done) + { + if (rpmReadConfigFiles(NULL, NULL) != 0) + { + warning (_("Error reading the rpm configuration files")); -+ return; ++ return 0; + } + rpm_init_done = 1; + } + + ts = rpmtsCreate (); -+ ++ + mi = rpmtsInitIterator (ts, RPMTAG_BASENAMES, filename, 0); + if (mi != NULL) + { -+ int printed = 0; -+ + for (;;) + { + Header h; -+ char *s; -+ const char *errmsg; ++ char *s, *srcrpm, *verrel, *debuginfo; ++ union ++ { ++ void *voidp; ++ char *s; ++ } ++ sourcerpm, arch; ++ char **slot; ++ rpmdbMatchIterator mi_debuginfo; + + h = rpmdbNextIterator (mi); + if (h == NULL) + break; + -+ s = headerSprintf (h, " %{name}", rpmTagTable, rpmHeaderFormats, -+ &errmsg); -+ if (s == NULL) -+ warning (_("Error querying rpm file `%s': %s"), filename, errmsg); -+ else ++ if (!headerGetEntry (h, RPMTAG_SOURCERPM, NULL, &sourcerpm.voidp, ++ NULL)) + { -+ if (!printed) -+ { -+ fprintf_unfiltered (gdb_stdout, -+ _("Getting all the debuginfos: %s"), -+ "debuginfo-install"); -+ printed = 1; ++ warning (_("Error querying the rpm file `%s' %s"), filename, ++ "RPMTAG_SOURCERPM"); ++ continue; ++ } ++ srcrpm = sourcerpm.s + strlen (sourcerpm.s) - (sizeof ".src.rpm" - 1); ++ if (srcrpm < sourcerpm.s || strcmp (srcrpm, ".src.rpm") != 0) ++ { ++error_parsing_sourcerpm: ++ warning (_("Error parsing %%{sourcerpm} of the rpm file `%s': %s"), ++ filename, sourcerpm.s); ++ continue; ++ } ++ s = srcrpm; ++ ++ /* Skip the release. */ ++ ++ while (s > sourcerpm.s && s[-1] != '-') ++ s--; ++ if (s == sourcerpm.s) ++ goto error_parsing_sourcerpm; ++ s--; ++ ++ /* Skip the version. */ ++ ++ while (s > sourcerpm.s && s[-1] != '-') ++ s--; ++ if (s == sourcerpm.s) ++ goto error_parsing_sourcerpm; ++ s--; ++ verrel = s; ++ ++ if (!headerGetEntry (h, RPMTAG_ARCH, NULL, &arch.voidp, NULL)) ++ { ++ warning (_("Error querying the rpm file `%s' %s"), filename, ++ "RPMTAG_ARCH"); ++ continue; ++ } ++ ++ /* The allocated memory gets utilized below for MISSING_RPM_HASH. */ ++ ++ debuginfo = xmalloc (strlen (sourcerpm.s) + strlen (arch.s) + 32); ++ ++ /* Verify the debuginfo file is not already installed. */ ++ ++ sprintf (debuginfo, "%.*s-debuginfo%.*s.%s", ++ (int) (verrel - sourcerpm.s), sourcerpm.s, ++ (int) (srcrpm - verrel), verrel, arch.s); ++ mi_debuginfo = rpmtsInitIterator (ts, RPMDBI_LABEL, debuginfo, 0); ++ if (mi_debuginfo != NULL) ++ { ++ Header h_debuginfo; ++ ++ h_debuginfo = rpmdbNextIterator (mi_debuginfo); ++ rpmdbFreeIterator (mi_debuginfo); ++ if (h_debuginfo != NULL) ++ { ++ xfree (debuginfo); ++ ++ /* We ignore any != 0 for possibly already enlisted rpms as ++ it should not hurt much. */ ++ ++ count = 0; ++ break; + } -+ /* Space (' ') delimited was insted by HEADERSPRINTF above. */ -+ fputs_unfiltered (s, gdb_stdout); + } -+ } + -+ if (printed) -+ fputs_unfiltered ("\n", gdb_stdout); ++ /* Base package name for `debuginfo-install'. We do not use `yum' ++ as its command ++ yum --enablerepo='*-debuginfo' install BASE-debuginfo.ARCH ++ would be more complicated than just: ++ debuginfo-install BASE.ARCH ++ We do not need to supply the version-release as ++ `debuginfo-install' always installs only the debuginfo matching ++ the currently installed rpm. Still we must supply `.%{arch}' as ++ we may have multilib (multiple arch-differing rpm packages) ++ installed. ++ FUTURE: After multiple debuginfo versions simultaneously installed ++ get supported we may need to supply the version-release here. */ ++ ++ sprintf (debuginfo, "%.*s.%s", (int) (verrel - sourcerpm.s), ++ sourcerpm.s, arch.s); ++ ++ if (missing_rpm_hash == NULL) ++ { ++ /* DEL_F is passed NULL as MISSING_RPM_LIST's HTAB_DELETE ++ should not deallocate the entries. */ ++ ++ missing_rpm_hash = htab_create_alloc (64, htab_hash_string, ++ (int (*) (const void *, const void *)) streq, ++ NULL, xcalloc, xfree); ++ } ++ slot = (char **) htab_find_slot (missing_rpm_hash, debuginfo, INSERT); ++ /* XCALLOC never returns NULL. */ ++ gdb_assert (slot != NULL); ++ if (*slot == NULL) ++ { ++ struct missing_rpm *missing_rpm; ++ ++ *slot = debuginfo; ++ ++ missing_rpm = xmalloc (sizeof (*missing_rpm) + strlen (debuginfo)); ++ strcpy (missing_rpm->rpm, debuginfo); ++ missing_rpm->next = missing_rpm_list; ++ missing_rpm_list = missing_rpm; ++ missing_rpm_list_entries++; ++ } ++ else ++ xfree (debuginfo); ++ count++; ++ } + + rpmdbFreeIterator (mi); + } + + rpmtsFree (ts); ++ ++ return count; ++} ++ ++static int ++missing_rpm_list_compar (const char *const *ap, const char *const *bp) ++{ ++ return strcoll (*ap, *bp); ++} ++ ++/* It returns a NULL-terminated array of strings needing to be FREEd. It may ++ also return only NULL. */ ++ ++static void ++missing_rpm_list_print (void) ++{ ++ char **array, **array_iter; ++ struct missing_rpm *list_iter; ++ ++ if (missing_rpm_list_entries == 0) ++ return; ++ ++ array = xmalloc (sizeof (*array) * missing_rpm_list_entries); ++ array_iter = array; ++ for (list_iter = missing_rpm_list; list_iter != NULL; ++ list_iter = list_iter->next) ++ { ++ *array_iter++ = list_iter->rpm; ++ } ++ gdb_assert (array_iter == array + missing_rpm_list_entries); ++ ++ qsort (array, missing_rpm_list_entries, sizeof (*array), ++ (int (*) (const void *, const void *)) missing_rpm_list_compar); ++ ++ printf (_("Missing separate debuginfos, use: %s"), "debuginfo-install"); ++ for (array_iter = array; array_iter < array + missing_rpm_list_entries; ++ array_iter++) ++ { ++ putchar (' '); ++ fputs (*array_iter, stdout); ++ } ++ putchar ('\n'); ++ ++ xfree (array); ++ while (missing_rpm_list != NULL) ++ { ++ list_iter = missing_rpm_list; ++ missing_rpm_list = list_iter->next; ++ xfree (list_iter); ++ } ++ missing_rpm_list_entries = 0; +} + -+struct missing_debuginfos ++static void ++missing_rpm_change (void) ++{ ++ debug_flush_missing (); ++ ++ gdb_assert (missing_rpm_list == NULL); ++ if (missing_rpm_hash != NULL) ++ { ++ htab_delete (missing_rpm_hash); ++ missing_rpm_hash = NULL; ++ } ++} ++ ++enum missing_exec ++ { ++ /* Init state. EXEC_BFD also still could be NULL. */ ++ MISSING_EXEC_NOT_TRIED, ++ /* We saw a non-NULL EXEC_BFD but RPM has no info about it. */ ++ MISSING_EXEC_NOT_FOUND, ++ /* We found EXEC_BFD by RPM and we either have its symbols (either embedded ++ or separate) or the main executable's RPM is now contained in ++ MISSING_RPM_HASH. */ ++ MISSING_EXEC_ENLISTED ++ }; ++static enum missing_exec missing_exec = MISSING_EXEC_NOT_TRIED; ++ ++void ++debug_flush_missing (void) ++{ ++ missing_rpm_list_print (); ++} ++ ++/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages ++ yum --enablerepo='*-debuginfo' install ... ++ avoidance. */ ++ ++struct missing_filepair + { + char *binary; + char *debug; + char data[1]; + }; + -+static struct htab *missing_debuginfos_hash; -+static struct obstack missing_debuginfos_obstack; ++static struct htab *missing_filepair_hash; ++static struct obstack missing_filepair_obstack; + +static void * -+missing_debuginfos_xcalloc (size_t nmemb, size_t nmemb_size) ++missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size) +{ + void *retval; + size_t size = nmemb * nmemb_size; -+ -+ retval = obstack_alloc (&missing_debuginfos_obstack, size); ++ ++ retval = obstack_alloc (&missing_filepair_obstack, size); + memset (retval, 0, size); + return retval; +} + +static hashval_t -+missing_debuginfos_hash_func (const struct missing_debuginfos *elem) ++missing_filepair_hash_func (const struct missing_filepair *elem) +{ -+ return htab_hash_string (elem->binary) ^ htab_hash_string (elem->debug); ++ hashval_t retval = 0; ++ ++ retval ^= htab_hash_string (elem->binary); ++ if (elem->debug != NULL) ++ retval ^= htab_hash_string (elem->debug); ++ ++ return retval; +} + +static int -+missing_debuginfos_eq (const struct missing_debuginfos *elem1, -+ const struct missing_debuginfos *elem2) ++missing_filepair_eq (const struct missing_filepair *elem1, ++ const struct missing_filepair *elem2) +{ + return strcmp (elem1->binary, elem2->binary) == 0 -+ && strcmp (elem1->debug, elem2->debug) == 0; ++ && ((elem1->debug == NULL && elem2->debug == NULL) ++ || strcmp (elem1->debug, elem2->debug) == 0); +} + +static void -+missing_debuginfos_change (void) ++missing_filepair_change (void) +{ -+ if (missing_debuginfos_hash != NULL) ++ if (missing_filepair_hash != NULL) + { -+ obstack_free (&missing_debuginfos_obstack, NULL); -+ /* All their memory came just from MISSING_DEBUGINFOS_OBSTACK. */ -+ missing_debuginfos_hash = NULL; ++ obstack_free (&missing_filepair_obstack, NULL); ++ /* All their memory came just from missing_filepair_OBSTACK. */ ++ missing_filepair_hash = NULL; + } ++ missing_exec = MISSING_EXEC_NOT_TRIED; +} + +static void -+missing_debuginfos_change_inferior_created (struct target_ops *objfile, -+ int from_tty) ++debug_print_executable_changed (void *unused) +{ -+ missing_debuginfos_change (); ++ missing_rpm_change (); ++ missing_filepair_change (); +} + ++/* Notify user the file BINARY with (possibly NULL) associated separate debug ++ information file DEBUG is missing. DEBUG may or may not be the build-id ++ file such as would be: ++ /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug ++ */ ++ +void -+build_id_print_missing (const char *binary, const char *debug, -+ int print_filename) ++debug_print_missing (const char *binary, const char *debug) +{ -+ char *exec_filename = NULL; + size_t binary_len0 = strlen (binary) + 1; -+ size_t debug_len0 = strlen (debug) + 1; -+ struct missing_debuginfos *missing_debuginfos; -+ struct missing_debuginfos **slot; ++ size_t debug_len0 = debug ? strlen (debug) + 1 : 0; ++ struct missing_filepair *missing_filepair; ++ struct missing_filepair **slot; + + if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES) + return; + -+ if (missing_debuginfos_hash == NULL) ++ if (missing_filepair_hash == NULL) + { -+ obstack_init (&missing_debuginfos_obstack); -+ missing_debuginfos_hash = htab_create_alloc (64, -+ (hashval_t (*) (const void *)) missing_debuginfos_hash_func, -+ (int (*) (const void *, const void *)) missing_debuginfos_eq, NULL, -+ missing_debuginfos_xcalloc, NULL); ++ obstack_init (&missing_filepair_obstack); ++ missing_filepair_hash = htab_create_alloc (64, ++ (hashval_t (*) (const void *)) missing_filepair_hash_func, ++ (int (*) (const void *, const void *)) missing_filepair_eq, NULL, ++ missing_filepair_xcalloc, NULL); + } + -+ missing_debuginfos = obstack_alloc (&missing_debuginfos_obstack, -+ sizeof (*missing_debuginfos) - 1 ++ missing_filepair = obstack_alloc (&missing_filepair_obstack, ++ sizeof (*missing_filepair) - 1 + + binary_len0 + debug_len0); -+ missing_debuginfos->binary = missing_debuginfos->data; -+ memcpy (missing_debuginfos->binary, binary, binary_len0); -+ missing_debuginfos->debug = missing_debuginfos->binary + binary_len0; -+ memcpy (missing_debuginfos->debug, debug, debug_len0); ++ missing_filepair->binary = missing_filepair->data; ++ memcpy (missing_filepair->binary, binary, binary_len0); ++ if (debug != NULL) ++ { ++ missing_filepair->debug = missing_filepair->binary + binary_len0; ++ memcpy (missing_filepair->debug, debug, debug_len0); ++ } ++ else ++ missing_filepair->debug = NULL; + -+ slot = (struct missing_debuginfos **) htab_find_slot (missing_debuginfos_hash, -+ missing_debuginfos, ++ slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash, ++ missing_filepair, + INSERT); + + /* While it may be still printed duplicitely with the missing debuginfo file @@ -880,41 +1177,53 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 + + if (*slot != NULL) + { -+ obstack_free (&missing_debuginfos_obstack, missing_debuginfos); ++ obstack_free (&missing_filepair_obstack, missing_filepair); + return; + } -+ *slot = missing_debuginfos; -+ -+ if (print_filename) -+ fprintf_unfiltered (gdb_stdlog, _("Missing separate debuginfo for %s\n"), -+ binary); -+ else -+ fprintf_unfiltered (gdb_stdlog, _("(no separate debuginfo file found)\n")); ++ *slot = missing_filepair; + -+ fprintf_unfiltered (gdb_stdlog, _("Try: %s %s\n"), -+ "yum --enablerepo='*-debuginfo' install", debug); -+ -+ if (exec_bfd != NULL) -+ exec_filename = bfd_get_filename (exec_bfd); -+ if (exec_filename != NULL) ++ if (missing_exec == MISSING_EXEC_NOT_TRIED) + { -+ static char *last_exec_filename; ++ char *exec_filename; + -+ if (last_exec_filename == NULL -+ || strcmp (exec_filename, last_exec_filename) != 0) ++ exec_filename = get_exec_file (0); ++ if (exec_filename != NULL) + { -+ xfree (last_exec_filename); -+ last_exec_filename = xstrdup (exec_filename); -+ -+ rpm_print_debuginfo (exec_filename); ++ if (missing_rpm_enlist (exec_filename) == 0) ++ missing_exec = MISSING_EXEC_NOT_FOUND; ++ else ++ missing_exec = MISSING_EXEC_ENLISTED; + } + } ++ if (missing_exec != MISSING_EXEC_ENLISTED) ++ if (missing_rpm_enlist (binary) == 0 && missing_rpm_enlist (debug) == 0) ++ { ++ /* We do not collect and flush these messages as each such message ++ already requires its own separate lines. */ ++ ++ fprintf_unfiltered (gdb_stdlog, ++ _("Missing separate debuginfo for %s\n"), binary); ++ if (debug != NULL) ++ fprintf_unfiltered (gdb_stdlog, _("Try: %s %s\n"), ++ "yum --enablerepo='*-debuginfo' install", debug); ++ } +} + static char * get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) { -@@ -1326,23 +1923,27 @@ find_separate_debug_file (struct objfile +@@ -1297,31 +2121,35 @@ static char * + find_separate_debug_file (struct objfile *objfile) + { + asection *sect; +- char *basename; +- char *dir; +- char *debugfile; ++ char *basename = NULL; ++ char *dir = NULL; ++ char *debugfile = NULL; + char *name_copy; + bfd_size_type debuglink_size; unsigned long crc32; int i; struct build_id *build_id; @@ -940,63 +1249,90 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 } else if (build_id_name != NULL) - return build_id_name; -+ { ++ { + xfree (build_id_filename); + return build_id_name; + } } basename = get_debug_link_info (objfile, &crc32); -@@ -1350,7 +1951,10 @@ find_separate_debug_file (struct objfile +@@ -1329,7 +2157,7 @@ find_separate_debug_file (struct objfile if (basename == NULL) /* There's no separate debug info, hence there's no way we could load it => no warning. */ - return NULL; -+ { -+ xfree (build_id_filename); -+ return NULL; -+ } ++ goto cleanup_return_debugfile; dir = xstrdup (objfile->name); -@@ -1379,6 +1983,7 @@ find_separate_debug_file (struct objfile +@@ -1345,23 +2173,19 @@ find_separate_debug_file (struct objfile + gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i])); + dir[i+1] = '\0'; + +- debugfile = alloca (strlen (debug_file_directory) + 1 +- + strlen (dir) +- + strlen (DEBUG_SUBDIRECTORY) +- + strlen ("/") +- + strlen (basename) +- + 1); ++ debugfile = xmalloc (strlen (debug_file_directory) + 1 ++ + strlen (dir) ++ + strlen (DEBUG_SUBDIRECTORY) ++ + strlen ("/") ++ + strlen (basename) ++ + 1); + + /* First try in the same directory as the original file. */ + strcpy (debugfile, dir); + strcat (debugfile, basename); if (separate_debug_file_exists (debugfile, crc32, objfile->name)) - { -+ xfree (build_id_filename); - xfree (basename); - xfree (dir); - return xstrdup (debugfile); -@@ -1392,6 +1997,7 @@ find_separate_debug_file (struct objfile +- { +- xfree (basename); +- xfree (dir); +- return xstrdup (debugfile); +- } ++ goto cleanup_return_debugfile; + + /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ + strcpy (debugfile, dir); +@@ -1370,11 +2194,7 @@ find_separate_debug_file (struct objfile + strcat (debugfile, basename); if (separate_debug_file_exists (debugfile, crc32, objfile->name)) - { -+ xfree (build_id_filename); - xfree (basename); - xfree (dir); - return xstrdup (debugfile); -@@ -1405,11 +2011,20 @@ find_separate_debug_file (struct objfile +- { +- xfree (basename); +- xfree (dir); +- return xstrdup (debugfile); +- } ++ goto cleanup_return_debugfile; + + /* Then try in the global debugfile directory. */ + strcpy (debugfile, debug_file_directory); +@@ -1383,15 +2203,16 @@ find_separate_debug_file (struct objfile + strcat (debugfile, basename); if (separate_debug_file_exists (debugfile, crc32, objfile->name)) - { -+ xfree (build_id_filename); - xfree (basename); - xfree (dir); - return xstrdup (debugfile); - } +- { +- xfree (basename); +- xfree (dir); +- return xstrdup (debugfile); +- } ++ goto cleanup_return_debugfile; -+ if (build_id_filename != NULL) -+ { -+ /* The filename is already printed for shared libraries. */ -+ build_id_print_missing (objfile->name, build_id_filename, -+ 1); -+ xfree (build_id_filename); -+ } ++ debugfile = NULL; ++ debug_print_missing (objfile->name, build_id_filename); + ++cleanup_return_debugfile: ++ xfree (build_id_filename); xfree (basename); xfree (dir); - return NULL; -@@ -4045,4 +4660,16 @@ the global debug-file directory prepende +- return NULL; ++ return debugfile; + } + + +@@ -4024,4 +4845,16 @@ the global debug-file directory prepende NULL, show_debug_file_directory, &setlist, &showlist); @@ -1011,11 +1347,12 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.c gdb-6 + show_build_id_verbose, + &setlist, &showlist); + -+ observer_attach_inferior_created (missing_debuginfos_change_inferior_created); ++ observer_attach_executable_changed (debug_print_executable_changed); } -diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.h gdb-6.6-patched/gdb/symfile.h ---- gdb-6.6-unpatched/gdb/symfile.h 2008-02-21 04:44:49.000000000 +0100 -+++ gdb-6.6-patched/gdb/symfile.h 2008-02-21 04:10:55.000000000 +0100 +Index: gdb-6.6/gdb/symfile.h +=================================================================== +--- gdb-6.6.orig/gdb/symfile.h 2005-12-17 23:34:03.000000000 +0100 ++++ gdb-6.6/gdb/symfile.h 2008-03-10 00:42:35.000000000 +0100 @@ -322,6 +322,14 @@ extern bfd_byte *symfile_relocate_debug_ extern void dwarf_build_psymtabs (struct objfile *, int, file_ptr, unsigned int, file_ptr, unsigned int); @@ -1025,9 +1362,22 @@ diff -u -X /home/jkratoch/.diffi.list -rup gdb-6.6-unpatched/gdb/symfile.h gdb-6 +extern struct build_id *build_id_addr_get (CORE_ADDR addr); +extern char *build_id_to_filename (struct build_id *build_id, + char **link_return, int add_debug_suffix); -+extern void build_id_print_missing (const char *binary, const char *debug, -+ int print_filename); ++extern void debug_print_missing (const char *binary, const char *debug); ++extern void debug_flush_missing (void); + /* From dwarf2read.c */ extern int dwarf2_has_info (struct objfile *); +Index: gdb-6.6/gdb/tui/tui-interp.c +=================================================================== +--- gdb-6.6.orig/gdb/tui/tui-interp.c 2005-12-23 20:10:02.000000000 +0100 ++++ gdb-6.6/gdb/tui/tui-interp.c 2008-03-10 00:42:35.000000000 +0100 +@@ -32,6 +32,8 @@ + #include "tui/tui.h" + #include "tui/tui-io.h" + #include "exceptions.h" ++#include "symtab.h" ++#include "symfile.h" + + /* Set to 1 when the TUI mode must be activated when we first start gdb. */ + static int tui_start_enabled = 0; diff --git a/gdb.spec b/gdb.spec index 8c659ae..b6c140c 100644 --- a/gdb.spec +++ b/gdb.spec @@ -11,7 +11,7 @@ Name: gdb Version: 6.6 # The release always contains a leading reserved number, start it at 1. -Release: 43%{?dist} +Release: 44%{?dist} License: GPL Group: Development/Debuggers @@ -721,6 +721,11 @@ fi # don't include the files in include, they are part of binutils %changelog +* Mon Mar 10 2008 Jan Kratochvil - 6.6-44 +- build-id warnings integrated more with rpm and the lists of the warnings got + replaced usually by a single-line `debuginfo-install' advice. + - FIXME: Testsuite needs an update for the new pre-prompt messages. + * Thu Feb 21 2008 Jan Kratochvil - 6.6-43 - Rename `set debug build-id' as `set build-id-verbose', former level 1 moved to level 2, default value is now 1, use `set build-id-verbose 0' now to