diff --git a/.gcc-toolset-10-gdb.metadata b/.gcc-toolset-10-gdb.metadata index 7bc6f10..41122e6 100644 --- a/.gcc-toolset-10-gdb.metadata +++ b/.gcc-toolset-10-gdb.metadata @@ -1,3 +1,3 @@ -a50e13e1eecea468ea28c4a23d8c5a84f4db25be SOURCES/gdb-9.1.tar.xz +356ee474a24bfb2f133894730916557dfea9da2e SOURCES/gdb-9.2.tar.xz 1ad1d2c6f0141b37bbe32b8add91b5691ecc6412 SOURCES/gdb-libstdc++-v3-python-8.1.1-20180626.tar.xz 36faaa9361ace9421579d6c2a66a8f0779fc8cf3 SOURCES/v2.0.1.tar.gz diff --git a/.gitignore b/.gitignore index 38358a2..de80160 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -SOURCES/gdb-9.1.tar.xz +SOURCES/gdb-9.2.tar.xz SOURCES/gdb-libstdc++-v3-python-8.1.1-20180626.tar.xz SOURCES/v2.0.1.tar.gz diff --git a/SOURCES/_gdb.spec.Patch.include b/SOURCES/_gdb.spec.Patch.include index 1d8ffd9..1bf37e7 100644 --- a/SOURCES/_gdb.spec.Patch.include +++ b/SOURCES/_gdb.spec.Patch.include @@ -400,3 +400,15 @@ Patch098: gdb-rhbz1818011-bfd-gcc10-error.patch # Backport fix for deprecation of PyEval_InitThreads in Python 3.9. Patch099: gdb-rhbz1822715-fix-python-deprecation.patch +# Backport "Fix Python 3.9 related runtime problems" +# Kevin Buettner and Keith Seitz +Patch100: gdb-rhbz1829702-fix-python39.patch + +# Fix fput?_unfiltered functions +# RH BZ 1844458 (Sergio Durigan Junior and Tom Tromey) +Patch101: gdb-rhbz1844458-use-fputX_unfiltered.patch + +# Backport debuginofd support. +# (Aaron Merey, RH BZ 183877) +Patch102: gdb-rhbz1838777-debuginfod.patch + diff --git a/SOURCES/_gdb.spec.patch.include b/SOURCES/_gdb.spec.patch.include index dddd45a..48f09cd 100644 --- a/SOURCES/_gdb.spec.patch.include +++ b/SOURCES/_gdb.spec.patch.include @@ -97,3 +97,6 @@ %patch097 -p1 %patch098 -p1 %patch099 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 diff --git a/SOURCES/gdb-6.3-inferior-notification-20050721.patch b/SOURCES/gdb-6.3-inferior-notification-20050721.patch index b94b432..d09fe1e 100644 --- a/SOURCES/gdb-6.3-inferior-notification-20050721.patch +++ b/SOURCES/gdb-6.3-inferior-notification-20050721.patch @@ -262,7 +262,7 @@ new file mode 100644 +} + +set GDBFLAGS_orig $GDBFLAGS -+set GDBFLAGS "--pid=$testpid" ++set GDBFLAGS "-iex \"set height 0\" --pid=$testpid" +gdb_start +set GDBFLAGS $GDBFLAGS_orig + @@ -284,7 +284,7 @@ new file mode 100644 +} + +set GDBFLAGS_orig $GDBFLAGS -+set GDBFLAGS "--pid=$testpid" ++set GDBFLAGS "-iex \"set height 0\" --pid=$testpid" +gdb_start +set GDBFLAGS $GDBFLAGS_orig + diff --git a/SOURCES/gdb-6.3-rh-testversion-20041202.patch b/SOURCES/gdb-6.3-rh-testversion-20041202.patch index 48ca4b5..e283832 100644 --- a/SOURCES/gdb-6.3-rh-testversion-20041202.patch +++ b/SOURCES/gdb-6.3-rh-testversion-20041202.patch @@ -32,7 +32,7 @@ diff --git a/gdb/top.c b/gdb/top.c struct internalvar *minor_version_var = create_internalvar ("_gdb_minor"); int vmajor = 0, vminor = 0, vrevision = 0; - sscanf (version, "%d.%d.%d", &vmajor, &vminor, &vrevision); -+ sscanf (version, "Fedora %d.%d.%d", &vmajor, &vminor, &vrevision); ++ sscanf (version, "Red Hat Enterprise Linux %d.%d.%d", &vmajor, &vminor, &vrevision); set_internalvar_integer (major_version_var, vmajor); set_internalvar_integer (minor_version_var, vminor + (vrevision > 0)); } diff --git a/SOURCES/gdb-rhbz1829702-fix-python39.patch b/SOURCES/gdb-rhbz1829702-fix-python39.patch new file mode 100644 index 0000000..d4eef56 --- /dev/null +++ b/SOURCES/gdb-rhbz1829702-fix-python39.patch @@ -0,0 +1,224 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Thu, 4 Jun 2020 17:16:48 -0700 +Subject: gdb-rhbz1829702-fix-python39.patch + +;; Backport "Fix Python 3.9 related runtime problems" +;; Kevin Buettner and Keith Seitz + +commit c47bae859a5af0d95224d90000df0e529f7c5aa0 +Author: Kevin Buettner +Date: Wed May 27 20:05:40 2020 -0700 + + Fix Python3.9 related runtime problems + + Python3.9b1 is now available on Rawhide. GDB w/ Python 3.9 support + can be built using the configure switch -with-python=/usr/bin/python3.9. + + Attempting to run gdb/Python3.9 segfaults on startup: + + #0 0x00007ffff7b0582c in PyEval_ReleaseLock () from /lib64/libpython3.9 +.so.1.0 + #1 0x000000000069ccbf in do_start_initialization () + at worktree-test1/gdb/python/python.c:1789 + #2 _initialize_python () + at worktree-test1/gdb/python/python.c:1877 + #3 0x00000000007afb0a in initialize_all_files () at init.c:237 + ... + + Consulting the the documentation... + + https://docs.python.org/3/c-api/init.html + + ...we find that PyEval_ReleaseLock() has been deprecated since version + 3.2. It recommends using PyEval_SaveThread or PyEval_ReleaseThread() + instead. In do_start_initialization, in gdb/python/python.c, we + can replace the calls to PyThreadState_Swap() and PyEval_ReleaseLock() + with a single call to PyEval_SaveThread. (Thanks to Keith Seitz + for working this out.) + + With that in place, GDB gets a little bit further. It still dies + on startup, but the backtrace is different: + + #0 0x00007ffff7b04306 in PyOS_InterruptOccurred () + from /lib64/libpython3.9.so.1.0 + #1 0x0000000000576e86 in check_quit_flag () + at worktree-test1/gdb/extension.c:776 + #2 0x0000000000576f8a in set_active_ext_lang (now_active=now_active@entry=0x983c00 ) + at worktree-test1/gdb/extension.c:705 + #3 0x000000000069d399 in gdbpy_enter::gdbpy_enter (this=0x7fffffffd2d0, + gdbarch=0x0, language=0x0) + at worktree-test1/gdb/python/python.c:211 + #4 0x0000000000686e00 in python_new_inferior (inf=0xddeb10) + at worktree-test1/gdb/python/py-inferior.c:251 + #5 0x00000000005d9fb9 in std::function::operator()(inferior*) const (__args#0=, this=0xccad20) + at /usr/include/c++/10/bits/std_function.h:617 + #6 gdb::observers::observable::notify (args#0=0xddeb10, + this=) + at worktree-test1/gdb/../gdbsupport/observable.h:106 + #7 add_inferior_silent (pid=0) + at worktree-test1/gdb/inferior.c:113 + #8 0x00000000005dbcb8 in initialize_inferiors () + at worktree-test1/gdb/inferior.c:947 + ... + + We checked with some Python Developers and were told that we should + acquire the GIL prior to calling any Python C API function. We + definitely don't have the GIL for calls of PyOS_InterruptOccurred(). + + I moved class_gdbpy_gil earlier in the file and use it in + gdbpy_check_quit_flag() to acquire (and automatically release) the + GIL. + + With those changes in place, I was able to run to a GDB prompt. But, + when trying to quit, it segfaulted again due to due to some other + problems with gdbpy_check_quit_flag(): + + Thread 1 "gdb" received signal SIGSEGV, Segmentation fault. + 0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0 + (top-gdb) bt 8 + #0 0x00007ffff7bbab0c in new_threadstate () from /lib64/libpython3.9.so.1.0 + #1 0x00007ffff7afa5ea in PyGILState_Ensure.cold () + from /lib64/libpython3.9.so.1.0 + #2 0x000000000069b58c in gdbpy_gil::gdbpy_gil (this=) + at worktree-test1/gdb/python/python.c:278 + #3 gdbpy_check_quit_flag (extlang=) + at worktree-test1/gdb/python/python.c:278 + #4 0x0000000000576e96 in check_quit_flag () + at worktree-test1/gdb/extension.c:776 + #5 0x000000000057700c in restore_active_ext_lang (previous=0xe9c050) + at worktree-test1/gdb/extension.c:729 + #6 0x000000000088913a in do_my_cleanups ( + pmy_chain=0xc31870 , + old_chain=0xae5720 ) + at worktree-test1/gdbsupport/cleanups.cc:131 + #7 do_final_cleanups () + at worktree-test1/gdbsupport/cleanups.cc:143 + + In this case, we're trying to call a Python C API function after + Py_Finalize() has been called from finalize_python(). I made + finalize_python set gdb_python_initialized to false and then cause + check_quit_flag() to return early when it's false. + + With these changes in place, GDB seems to be working again with + Python3.9b1. I think it likely that there are other problems lurking. + I wouldn't be surprised to find that there are other calls into Python + where we don't first make sure that we have the GIL. Further changes + may well be needed. + + I see no regressions testing on Rawhide using a GDB built with the + default Python version (3.8.3) versus one built using Python 3.9b1. + + I've also tested on Fedora 28, 29, 30, 31, and 32 (all x86_64) using + the default (though updated) system installed versions of Python on + those OSes. This means that I've tested against Python versions + 2.7.15, 2.7.17, 2.7.18, 3.7.7, 3.8.2, and 3.8.3. In each case GDB + still builds without problem and shows no regressions after applying + this patch. + + gdb/ChangeLog: + + 2020-MM-DD Kevin Buettner + Keith Seitz + + * python/python.c (do_start_initialization): For Python 3.9 and + later, call PyEval_SaveThread instead of PyEval_ReleaseLock. + (class gdbpy_gil): Move to earlier in file. + (finalize_python): Set gdb_python_initialized. + (gdbpy_check_quit_flag): Acquire GIL via gdbpy_gil. Return early + when not initialized. + +diff --git a/gdb/python/python.c b/gdb/python/python.c +--- a/gdb/python/python.c ++++ b/gdb/python/python.c +@@ -234,6 +234,30 @@ gdbpy_enter::~gdbpy_enter () + PyGILState_Release (m_state); + } + ++/* A helper class to save and restore the GIL, but without touching ++ the other globals that are handled by gdbpy_enter. */ ++ ++class gdbpy_gil ++{ ++public: ++ ++ gdbpy_gil () ++ : m_state (PyGILState_Ensure ()) ++ { ++ } ++ ++ ~gdbpy_gil () ++ { ++ PyGILState_Release (m_state); ++ } ++ ++ DISABLE_COPY_AND_ASSIGN (gdbpy_gil); ++ ++private: ++ ++ PyGILState_STATE m_state; ++}; ++ + /* Set the quit flag. */ + + static void +@@ -247,6 +271,10 @@ gdbpy_set_quit_flag (const struct extension_language_defn *extlang) + static int + gdbpy_check_quit_flag (const struct extension_language_defn *extlang) + { ++ if (!gdb_python_initialized) ++ return 0; ++ ++ gdbpy_gil gil; + return PyOS_InterruptOccurred (); + } + +@@ -924,30 +952,6 @@ gdbpy_source_script (const struct extension_language_defn *extlang, + + /* Posting and handling events. */ + +-/* A helper class to save and restore the GIL, but without touching +- the other globals that are handled by gdbpy_enter. */ +- +-class gdbpy_gil +-{ +-public: +- +- gdbpy_gil () +- : m_state (PyGILState_Ensure ()) +- { +- } +- +- ~gdbpy_gil () +- { +- PyGILState_Release (m_state); +- } +- +- DISABLE_COPY_AND_ASSIGN (gdbpy_gil); +- +-private: +- +- PyGILState_STATE m_state; +-}; +- + /* A single event. */ + struct gdbpy_event + { +@@ -1548,6 +1552,7 @@ finalize_python (void *ignore) + + Py_Finalize (); + ++ gdb_python_initialized = false; + restore_active_ext_lang (previous_active); + } + +@@ -1720,8 +1725,7 @@ do_start_initialization () + return false; + + /* Release the GIL while gdb runs. */ +- PyThreadState_Swap (NULL); +- PyEval_ReleaseLock (); ++ PyEval_SaveThread (); + + make_final_cleanup (finalize_python, NULL); + diff --git a/SOURCES/gdb-rhbz1838777-debuginfod.patch b/SOURCES/gdb-rhbz1838777-debuginfod.patch new file mode 100644 index 0000000..fb836b3 --- /dev/null +++ b/SOURCES/gdb-rhbz1838777-debuginfod.patch @@ -0,0 +1,1187 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Tue, 9 Jun 2020 08:29:41 -0700 +Subject: gdb-rhbz1838777-debuginfod.patch + +;; Backport debuginofd support. +;; (Aaron Merey, RH BZ 183877) + +commit 0d79cdc494d5eb9db26a602d62c92d49f83f407e +Author: Aaron Merey +Date: Wed Feb 26 17:40:49 2020 -0500 + + Add debuginfod support to GDB + + debuginfod is a lightweight web service that indexes ELF/DWARF debugging + resources by build-id and serves them over HTTP. + + This patch enables GDB to query debuginfod servers for separate debug + files and source code when it is otherwise not able to find them. + + GDB can be built with debuginfod using the --with-debuginfod configure + option. + + This requires that libdebuginfod be installed and found at configure time. + + debuginfod is packaged with elfutils, starting with version 0.178. + + For more information see https://sourceware.org/elfutils/. + + Tested on x86_64 Fedora 31. + + gdb/ChangeLog: + 2020-02-26 Aaron Merey + + * Makefile.in: Handle optional debuginfod support. + * NEWS: Update. + * README: Add --with-debuginfod summary. + * config.in: Regenerate. + * configure: Regenerate. + * configure.ac: Handle optional debuginfod support. + * debuginfod-support.c: debuginfod helper functions. + * debuginfod-support.h: Ditto. + * doc/gdb.texinfo: Add --with-debuginfod to configure options + summary. + * dwarf2/read.c (dwarf2_get_dwz_file): Query debuginfod servers + when a dwz file cannot be found. + * elfread.c (elf_symfile_read): Query debuginfod servers when a + debuginfo file cannot be found. + * source.c (open_source_file): Query debuginfod servers when a + source file cannot be found. + * top.c (print_gdb_configuration): Include + --{with,without}-debuginfod in the output. + + gdb/testsuite/ChangeLog: + 2020-02-26 Aaron Merey + + * gdb.debuginfod: New directory for debuginfod tests. + * gdb.debuginfod/main.c: New test file. + * gdb.debuginfod/fetch_src_and_symbols.exp: New tests. + +diff --git a/config/debuginfod.m4 b/config/debuginfod.m4 +new file mode 100644 +--- /dev/null ++++ b/config/debuginfod.m4 +@@ -0,0 +1,38 @@ ++dnl Copyright (C) 1997-2019 Free Software Foundation, Inc. ++dnl This file is free software, distributed under the terms of the GNU ++dnl General Public License. As a special exception to the GNU General ++dnl Public License, this file may be distributed as part of a program ++dnl that contains a configuration script generated by Autoconf, under ++dnl the same distribution terms as the rest of that program. ++ ++AC_DEFUN([AC_DEBUGINFOD], ++[ ++# Enable debuginfod ++AC_ARG_WITH([debuginfod], ++ AC_HELP_STRING([--with-debuginfod], ++ [Enable debuginfo lookups with debuginfod (auto/yes/no)]), ++ [], [with_debuginfod=auto]) ++AC_MSG_CHECKING([whether to use debuginfod]) ++AC_MSG_RESULT([$with_debuginfod]) ++ ++if test "${with_debuginfod}" = no; then ++ AC_MSG_WARN([debuginfod support disabled; some features may be unavailable.]) ++else ++ AC_CHECK_LIB([debuginfod], [debuginfod_begin], [have_debuginfod_lib=yes]) ++ AC_CHECK_DECL([debuginfod_begin], [have_debuginfod_h=yes], [], ++ [#include ]) ++ if test "x$have_debuginfod_lib" = "xyes" -a \ ++ "x$have_debuginfod_h" = "xyes"; then ++ AC_DEFINE([HAVE_LIBDEBUGINFOD], [1], ++ [Define to 1 if debuginfod is enabled.]) ++ AC_SUBST([LIBDEBUGINFOD], ["-ldebuginfod"]) ++ else ++ AC_SUBST([LIBDEBUGINFOD], []) ++ if test "$with_debuginfod" = yes; then ++ AC_MSG_ERROR([debuginfod is missing or unusable]) ++ else ++ AC_MSG_WARN([debuginfod is missing or unusable; some features may be unavailable.]) ++ fi ++ fi ++fi ++]) +diff --git a/gdb/Makefile.in b/gdb/Makefile.in +--- a/gdb/Makefile.in ++++ b/gdb/Makefile.in +@@ -612,7 +612,8 @@ CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(LIBCTF) $(ZLIB) \ + @LIBS@ @GUILE_LIBS@ @PYTHON_LIBS@ \ + $(LIBEXPAT) $(LIBLZMA) $(LIBBABELTRACE) $(LIBIPT) \ + $(LIBIBERTY) $(WIN32LIBS) $(LIBGNU) $(LIBICONV) $(LIBMPFR) \ +- $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) ++ $(SRCHIGH_LIBS) $(LIBXXHASH) $(PTHREAD_LIBS) \ ++ @LIBDEBUGINFOD@ + CDEPS = $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) $(LIBCTF) \ + $(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU) + +@@ -1016,6 +1017,7 @@ COMMON_SFILES = \ + dbxread.c \ + dcache.c \ + debug.c \ ++ debuginfod-support.c \ + dictionary.c \ + disasm.c \ + disasm-selftests.c \ +diff --git a/gdb/NEWS b/gdb/NEWS +--- a/gdb/NEWS ++++ b/gdb/NEWS +@@ -932,6 +932,20 @@ SH-5/SH64 running OpenBSD SH-5/SH64 support in sh*-*-openbsd* + manual for a further description of this feature. + + ++* GDB now supports debuginfod, an HTTP server for distributing ELF/DWARF ++ debugging information as well as source code. ++ ++ When built with debuginfod, GDB can automatically query debuginfod ++ servers for the separate debug files and source code of the executable ++ being debugged. ++ ++ To build GDB with debuginfod, pass --with-debuginfod to configure (this ++ requires libdebuginfod, the debuginfod client library). ++ ++ debuginfod is distributed with elfutils, starting with version 0.178. ++ ++ You can get the latest version from https://sourceware.org/elfutils. ++ + * New features in the GDB remote stub, GDBserver + + ** GDBserver is now able to start inferior processes with a +diff --git a/gdb/README b/gdb/README +--- a/gdb/README ++++ b/gdb/README +@@ -432,6 +432,15 @@ more obscure GDB `configure' options are not listed here. + Use the curses library instead of the termcap library, for + text-mode terminal operations. + ++`--with-debuginfod' ++ Build GDB with libdebuginfod, the debuginfod client library. Used ++ to automatically fetch source files and separate debug files from ++ debuginfod servers using the associated executable's build ID. ++ Enabled by default if libdebuginfod is installed and found at ++ configure time. debuginfod is packaged with elfutils, starting ++ with version 0.178. You can get the latest version from ++ 'https://sourceware.org/elfutils/'. ++ + `--with-libunwind-ia64' + Use the libunwind library for unwinding function call stack on ia64 + target platforms. +diff --git a/gdb/config.in b/gdb/config.in +--- a/gdb/config.in ++++ b/gdb/config.in +@@ -230,6 +230,9 @@ + /* Define if you have the babeltrace library. */ + #undef HAVE_LIBBABELTRACE + ++/* Define to 1 if debuginfod is enabled. */ ++#undef HAVE_LIBDEBUGINFOD ++ + /* Define if you have the expat library. */ + #undef HAVE_LIBEXPAT + +diff --git a/gdb/configure b/gdb/configure +--- a/gdb/configure ++++ b/gdb/configure +@@ -758,6 +758,7 @@ REPORT_BUGS_TEXI + REPORT_BUGS_TO + PKGVERSION + CODESIGN_CERT ++LIBDEBUGINFOD + HAVE_NATIVE_GCORE_TARGET + TARGET_OBS + subdirs +@@ -875,6 +876,7 @@ enable_64_bit_bfd + enable_gdbmi + enable_tui + enable_gdbtk ++with_debuginfod + with_libunwind_ia64 + with_curses + enable_profiling +@@ -1611,6 +1613,8 @@ Optional Packages: + do not restrict auto-loaded files locations + --with-rpm query rpm database for missing debuginfos (yes/no, + def. auto=librpm.so) ++ --with-debuginfod Enable debuginfo lookups with debuginfod ++ (auto/yes/no) + --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets + --with-curses use the curses library instead of the termcap + library +@@ -2271,6 +2275,52 @@ rm -f conftest.val + + } # ac_fn_c_compute_int + ++# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES ++# --------------------------------------------- ++# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR ++# accordingly. ++ac_fn_c_check_decl () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ as_decl_name=`echo $2|sed 's/ *(.*//'` ++ as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 ++$as_echo_n "checking whether $as_decl_name is declared... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++$4 ++int ++main () ++{ ++#ifndef $as_decl_name ++#ifdef __cplusplus ++ (void) $as_decl_use; ++#else ++ (void) $as_decl_name; ++#endif ++#endif ++ ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_compile "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_decl ++ + # ac_fn_c_check_func LINENO FUNC VAR + # ---------------------------------- + # Tests whether FUNC exists, setting the cache variable VAR accordingly +@@ -2449,52 +2499,6 @@ $as_echo "$ac_res" >&6; } + + } # ac_fn_c_check_type + +-# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +-# --------------------------------------------- +-# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +-# accordingly. +-ac_fn_c_check_decl () +-{ +- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack +- as_decl_name=`echo $2|sed 's/ *(.*//'` +- as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +-$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +-if eval \${$3+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +-$4 +-int +-main () +-{ +-#ifndef $as_decl_name +-#ifdef __cplusplus +- (void) $as_decl_use; +-#else +- (void) $as_decl_name; +-#endif +-#endif +- +- ; +- return 0; +-} +-_ACEOF +-if ac_fn_c_try_compile "$LINENO"; then : +- eval "$3=yes" +-else +- eval "$3=no" +-fi +-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +-fi +-eval ac_res=\$$3 +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +-$as_echo "$ac_res" >&6; } +- eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno +- +-} # ac_fn_c_check_decl +- + # ac_fn_cxx_try_link LINENO + # ------------------------- + # Try to link conftest.$ac_ext, and return whether this succeeded. +@@ -6658,8 +6662,8 @@ $as_echo_n "checking specific librpm version... " >&6; } + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error "cannot run test program while cross compiling +-See \`config.log' for more details." "$LINENO" 5; } ++as_fn_error $? "cannot run test program while cross compiling ++See \`config.log' for more details" "$LINENO" 5; } + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ +@@ -6830,7 +6834,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h + $as_echo "no" >&6; } + LIBS="$save_LIBS" + if $DLOPEN_REQUIRE; then +- as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 ++ as_fn_error $? "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 + fi + + +@@ -6845,7 +6849,7 @@ if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 + $as_echo_n "checking for $ac_word... " >&6; } +-if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : ++if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 + else + case $PKG_CONFIG in +@@ -6859,7 +6863,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -6888,7 +6892,7 @@ if test -z "$ac_cv_path_PKG_CONFIG"; then + set dummy pkg-config; ac_word=$2 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 + $as_echo_n "checking for $ac_word... " >&6; } +-if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : ++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 + else + case $ac_pt_PKG_CONFIG in +@@ -6902,7 +6906,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -7086,7 +7090,7 @@ $as_echo "#define HAVE_LIBRPM 1" >>confdefs.h + LIBS="$LIBS $RPM_LIBS" + else + if $RPM_REQUIRE; then +- as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 ++ as_fn_error $? "$RPM_PKG_ERRORS" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 + $as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} +@@ -7332,8 +7336,92 @@ $as_echo "$as_me: WARNING: gdbtk isn't supported on $host; disabling" >&2;} + enable_gdbtk=no ;; + esac + +-# Libunwind support for ia64. ++# Handle optional debuginfod support ++ ++# Enable debuginfod ++ ++# Check whether --with-debuginfod was given. ++if test "${with_debuginfod+set}" = set; then : ++ withval=$with_debuginfod; ++else ++ with_debuginfod=auto ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use debuginfod" >&5 ++$as_echo_n "checking whether to use debuginfod... " >&6; } ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_debuginfod" >&5 ++$as_echo "$with_debuginfod" >&6; } ++ ++if test "${with_debuginfod}" = no; then ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod support disabled; some features may be unavailable." >&5 ++$as_echo "$as_me: WARNING: debuginfod support disabled; some features may be unavailable." >&2;} ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for debuginfod_begin in -ldebuginfod" >&5 ++$as_echo_n "checking for debuginfod_begin in -ldebuginfod... " >&6; } ++if ${ac_cv_lib_debuginfod_debuginfod_begin+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_check_lib_save_LIBS=$LIBS ++LIBS="-ldebuginfod $LIBS" ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char debuginfod_begin (); ++int ++main () ++{ ++return debuginfod_begin (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_lib_debuginfod_debuginfod_begin=yes ++else ++ ac_cv_lib_debuginfod_debuginfod_begin=no ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++LIBS=$ac_check_lib_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_debuginfod_debuginfod_begin" >&5 ++$as_echo "$ac_cv_lib_debuginfod_debuginfod_begin" >&6; } ++if test "x$ac_cv_lib_debuginfod_debuginfod_begin" = xyes; then : ++ have_debuginfod_lib=yes ++fi ++ ++ ac_fn_c_check_decl "$LINENO" "debuginfod_begin" "ac_cv_have_decl_debuginfod_begin" "#include ++" ++if test "x$ac_cv_have_decl_debuginfod_begin" = xyes; then : ++ have_debuginfod_h=yes ++fi ++ ++ if test "x$have_debuginfod_lib" = "xyes" -a \ ++ "x$have_debuginfod_h" = "xyes"; then ++ ++$as_echo "#define HAVE_LIBDEBUGINFOD 1" >>confdefs.h ++ ++ LIBDEBUGINFOD="-ldebuginfod" + ++ else ++ ++ if test "$with_debuginfod" = yes; then ++ as_fn_error $? "debuginfod is missing or unusable" "$LINENO" 5 ++ else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&5 ++$as_echo "$as_me: WARNING: debuginfod is missing or unusable; some features may be unavailable." >&2;} ++ fi ++ fi ++fi ++ ++ ++# Libunwind support for ia64. + + # Check whether --with-libunwind-ia64 was given. + if test "${with_libunwind_ia64+set}" = set; then : +@@ -16441,7 +16529,7 @@ _ACEOF + for ac_header in selinux/selinux.h + do : + ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" +-if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then : ++if test "x$ac_cv_header_selinux_selinux_h" = xyes; then : + cat >>confdefs.h <<_ACEOF + #define HAVE_SELINUX_SELINUX_H 1 + _ACEOF +@@ -16452,7 +16540,7 @@ done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5 + $as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; } +-if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then : ++if ${ac_cv_lib_selinux_security_get_boolean_active+:} false; then : + $as_echo_n "(cached) " >&6 + else + ac_check_lib_save_LIBS=$LIBS +@@ -16486,7 +16574,7 @@ LIBS=$ac_check_lib_save_LIBS + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_selinux_security_get_boolean_active" >&5 + $as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; } +-if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then : ++if test "x$ac_cv_lib_selinux_security_get_boolean_active" = xyes; then : + cat >>confdefs.h <<_ACEOF + #define HAVE_LIBSELINUX 1 + _ACEOF +diff --git a/gdb/configure.ac b/gdb/configure.ac +--- a/gdb/configure.ac ++++ b/gdb/configure.ac +@@ -18,6 +18,8 @@ dnl along with this program. If not, see . + + dnl Process this file with autoconf to produce a configure script. + ++m4_include(../config/debuginfod.m4) ++ + AC_INIT(main.c) + AC_CONFIG_HEADERS(config.h:config.in, [echo > stamp-h]) + AM_MAINTAINER_MODE +@@ -516,8 +518,10 @@ case $host_os in + enable_gdbtk=no ;; + esac + +-# Libunwind support for ia64. ++# Handle optional debuginfod support ++AC_DEBUGINFOD + ++# Libunwind support for ia64. + AC_ARG_WITH(libunwind-ia64, + AS_HELP_STRING([--with-libunwind-ia64], + [use libunwind frame unwinding for ia64 targets]),, +diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c +new file mode 100644 +--- /dev/null ++++ b/gdb/debuginfod-support.c +@@ -0,0 +1,155 @@ ++/* debuginfod utilities for GDB. ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#include "defs.h" ++#include ++#include "cli/cli-style.h" ++#include "gdbsupport/scoped_fd.h" ++#include "debuginfod-support.h" ++ ++#ifndef HAVE_LIBDEBUGINFOD ++scoped_fd ++debuginfod_source_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *srcpath, ++ gdb::unique_xmalloc_ptr *destname) ++{ ++ return scoped_fd (-ENOSYS); ++} ++ ++scoped_fd ++debuginfod_debuginfo_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *filename, ++ gdb::unique_xmalloc_ptr *destname) ++{ ++ return scoped_fd (-ENOSYS); ++} ++#else ++#include ++ ++/* TODO: Use debuginfod API extensions instead of these globals. */ ++static std::string desc; ++static std::string fname; ++static bool has_printed; ++ ++static int ++progressfn (debuginfod_client *c, long cur, long total) ++{ ++ if (check_quit_flag ()) ++ { ++ printf_filtered ("Cancelling download of %s %ps...\n", ++ desc.c_str (), ++ styled_string (file_name_style.style (), fname.c_str ())); ++ return 1; ++ } ++ ++ if (!has_printed && total != 0) ++ { ++ /* Print this message only once. */ ++ has_printed = true; ++ printf_filtered ("Downloading %s %ps...\n", ++ desc.c_str (), ++ styled_string (file_name_style.style (), fname.c_str ())); ++ } ++ ++ return 0; ++} ++ ++static debuginfod_client * ++debuginfod_init () ++{ ++ debuginfod_client *c = debuginfod_begin (); ++ ++ if (c != nullptr) ++ debuginfod_set_progressfn (c, progressfn); ++ ++ return c; ++} ++ ++/* See debuginfod-support.h */ ++ ++scoped_fd ++debuginfod_source_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *srcpath, ++ gdb::unique_xmalloc_ptr *destname) ++{ ++ if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL) ++ return scoped_fd (-ENOSYS); ++ ++ debuginfod_client *c = debuginfod_init (); ++ ++ if (c == nullptr) ++ return scoped_fd (-ENOMEM); ++ ++ desc = std::string ("source file"); ++ fname = std::string (srcpath); ++ has_printed = false; ++ ++ scoped_fd fd (debuginfod_find_source (c, ++ build_id, ++ build_id_len, ++ srcpath, ++ nullptr)); ++ ++ /* TODO: Add 'set debug debuginfod' command to control when error messages are shown. */ ++ if (fd.get () < 0 && fd.get () != -ENOENT) ++ printf_filtered (_("Download failed: %s. Continuing without source file %ps.\n"), ++ safe_strerror (-fd.get ()), ++ styled_string (file_name_style.style (), srcpath)); ++ else ++ destname->reset (xstrdup (srcpath)); ++ ++ debuginfod_end (c); ++ return fd; ++} ++ ++/* See debuginfod-support.h */ ++ ++scoped_fd ++debuginfod_debuginfo_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *filename, ++ gdb::unique_xmalloc_ptr *destname) ++{ ++ if (getenv (DEBUGINFOD_URLS_ENV_VAR) == NULL) ++ return scoped_fd (-ENOSYS); ++ ++ debuginfod_client *c = debuginfod_init (); ++ ++ if (c == nullptr) ++ return scoped_fd (-ENOMEM); ++ ++ desc = std::string ("separate debug info for"); ++ fname = std::string (filename); ++ has_printed = false; ++ char *dname = nullptr; ++ ++ scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len, &dname)); ++ ++ if (fd.get () < 0 && fd.get () != -ENOENT) ++ printf_filtered (_("Download failed: %s. Continuing without debug info for %ps.\n"), ++ safe_strerror (-fd.get ()), ++ styled_string (file_name_style.style (), filename)); ++ ++ destname->reset (dname); ++ debuginfod_end (c); ++ return fd; ++} ++#endif +diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h +new file mode 100644 +--- /dev/null ++++ b/gdb/debuginfod-support.h +@@ -0,0 +1,62 @@ ++/* debuginfod utilities for GDB. ++ Copyright (C) 2020 Free Software Foundation, Inc. ++ ++ This file is part of GDB. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++#ifndef DEBUGINFOD_SUPPORT_H ++#define DEBUGINFOD_SUPPORT_H ++ ++/* Query debuginfod servers for a source file associated with an ++ executable with BUILD_ID. BUILD_ID can be given as a binary blob or ++ a null-terminated string. If given as a binary blob, BUILD_ID_LEN ++ should be the number of bytes. If given as a null-terminated string, ++ BUILD_ID_LEN should be 0. ++ ++ SRC_PATH should be the source file's absolute path that includes the ++ compilation directory of the CU associated with the source file. ++ For example if a CU's compilation directory is `/my/build` and the ++ source file path is `/my/source/foo.c`, then SRC_PATH should be ++ `/my/build/../source/foo.c`. ++ ++ If the file is successfully retrieved, its path on the local machine ++ is stored in DESTNAME. If GDB is not built with debuginfod, this ++ function returns -ENOSYS. */ ++ ++extern scoped_fd ++debuginfod_source_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *src_path, ++ gdb::unique_xmalloc_ptr *destname); ++ ++/* Query debuginfod servers for a debug info file with BUILD_ID. ++ BUILD_ID can be given as a binary blob or a null-terminated string. ++ If given as a binary blob, BUILD_ID_LEN should be the number of bytes. ++ If given as a null-terminated string, BUILD_ID_LEN should be 0. ++ ++ FILENAME should be the name or path of the main binary associated with ++ the separate debug info. It is used for printing messages to the user. ++ ++ If the file is successfully retrieved, its path on the local machine ++ is stored in DESTNAME. If GDB is not built with debuginfod, this ++ function returns -ENOSYS. */ ++ ++extern scoped_fd ++debuginfod_debuginfo_query (const unsigned char *build_id, ++ int build_id_len, ++ const char *filename, ++ gdb::unique_xmalloc_ptr *destname); ++ ++#endif /* DEBUGINFOD_SUPPORT_H */ +diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo +--- a/gdb/doc/gdb.texinfo ++++ b/gdb/doc/gdb.texinfo +@@ -37726,6 +37726,14 @@ supported). + Use the curses library instead of the termcap library, for text-mode + terminal operations. + ++@item --with-debuginfod ++Build @value{GDBN} with libdebuginfod, the debuginfod client library. ++Used to automatically fetch source files and separate debug files from ++debuginfod servers using the associated executable's build ID. Enabled ++by default if libdebuginfod is installed and found at configure time. ++debuginfod is packaged with elfutils, starting with version 0.178. You ++can get the latest version from `https://sourceware.org/elfutils/'. ++ + @item --with-libunwind-ia64 + Use the libunwind library for unwinding function call stack on ia64 + target platforms. See http://www.nongnu.org/libunwind/index.html for +diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c +--- a/gdb/dwarf2read.c ++++ b/gdb/dwarf2read.c +@@ -77,6 +77,7 @@ + #include "gdbsupport/selftest.h" + #include "rust-lang.h" + #include "gdbsupport/pathstuff.h" ++#include "debuginfod-support.h" + + /* When == 1, print basic high level tracing messages. + When > 1, be more verbose. +@@ -2717,6 +2718,29 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile) + dwz_bfd.reset (nullptr); + } + ++ if (dwz_bfd == nullptr) ++ { ++ gdb::unique_xmalloc_ptr alt_filename; ++ const char *origname = dwarf2_per_objfile->objfile->original_name; ++ ++ scoped_fd fd (debuginfod_debuginfo_query (buildid, ++ buildid_len, ++ origname, ++ &alt_filename)); ++ ++ if (fd.get () >= 0) ++ { ++ /* File successfully retrieved from server. */ ++ dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1); ++ ++ if (dwz_bfd == nullptr) ++ warning (_("File \"%s\" from debuginfod cannot be opened as bfd"), ++ alt_filename.get ()); ++ else if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid)) ++ dwz_bfd.reset (nullptr); ++ } ++ } ++ + if (dwz_bfd == NULL) + dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid, NULL); + +diff --git a/gdb/elfread.c b/gdb/elfread.c +--- a/gdb/elfread.c ++++ b/gdb/elfread.c +@@ -49,6 +49,8 @@ + #include "mdebugread.h" + #include "ctfread.h" + #include "gdbsupport/gdb_string_view.h" ++#include "gdbsupport/scoped_fd.h" ++#include "debuginfod-support.h" + + /* Forward declarations. */ + extern const struct sym_fns elf_sym_fns_gdb_index; +@@ -1313,12 +1315,42 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) + symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (), + symfile_flags, objfile); + } +- /* Check if any separate debug info has been extracted out. */ +- else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink") +- != NULL) +- debug_print_missing (objfile_name (objfile), build_id_filename.get ()); + else +- has_dwarf2 = false; ++ { ++ has_dwarf2 = false; ++ const struct bfd_build_id *build_id = build_id_bfd_shdr_get (objfile->obfd); ++ ++ if (build_id != nullptr) ++ { ++ gdb::unique_xmalloc_ptr symfile_path; ++ scoped_fd fd (debuginfod_debuginfo_query (build_id->data, ++ build_id->size, ++ objfile->original_name, ++ &symfile_path)); ++ ++ if (fd.get () >= 0) ++ { ++ /* File successfully retrieved from server. */ ++ gdb_bfd_ref_ptr debug_bfd (symfile_bfd_open (symfile_path.get ())); ++ ++ if (debug_bfd == nullptr) ++ warning (_("File \"%s\" from debuginfod cannot be opened as bfd"), ++ objfile->original_name); ++ else if (build_id_verify (debug_bfd.get (), build_id->size, build_id->data)) ++ { ++ symbol_file_add_separate (debug_bfd.get (), symfile_path.get (), ++ symfile_flags, objfile); ++ has_dwarf2 = true; ++ } ++ } ++ } ++ /* Check if any separate debug info has been extracted out. */ ++ else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink") ++ != NULL) ++ debug_print_missing (objfile_name (objfile), build_id_filename.get ()); ++ else ++ has_dwarf2 = false; ++ } + } + + /* Read the CTF section only if there is no DWARF info. */ +diff --git a/gdb/source.c b/gdb/source.c +--- a/gdb/source.c ++++ b/gdb/source.c +@@ -47,6 +47,8 @@ + #include "gdbsupport/pathstuff.h" + #include "source-cache.h" + #include "cli/cli-style.h" ++#include "build-id.h" ++#include "debuginfod-support.h" + + #define OPEN_MODE (O_RDONLY | O_BINARY) + #define FDOPEN_MODE FOPEN_RB +@@ -1122,6 +1124,34 @@ open_source_file (struct symtab *s) + s->fullname = NULL; + scoped_fd fd = find_and_open_source (s->filename, SYMTAB_DIRNAME (s), + &fullname); ++ ++ if (fd.get () < 0) ++ { ++ if (SYMTAB_COMPUNIT (s) != nullptr) ++ { ++ const objfile *ofp = COMPUNIT_OBJFILE (SYMTAB_COMPUNIT (s)); ++ ++ std::string srcpath; ++ if (IS_ABSOLUTE_PATH (s->filename)) ++ srcpath = s->filename; ++ else if (SYMTAB_DIRNAME (s) != nullptr) ++ { ++ srcpath = SYMTAB_DIRNAME (s); ++ srcpath += SLASH_STRING; ++ srcpath += s->filename; ++ } ++ ++ const struct bfd_build_id *build_id = build_id_bfd_shdr_get (ofp->obfd); ++ ++ /* Query debuginfod for the source file. */ ++ if (build_id != nullptr) ++ fd = debuginfod_source_query (build_id->data, ++ build_id->size, ++ srcpath.c_str (), ++ &fullname); ++ } ++ } ++ + s->fullname = fullname.release (); + return fd; + } +diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp +@@ -0,0 +1,214 @@ ++# Copyright 2020 Free Software Foundation, Inc. ++ ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++ ++# Test debuginfod functionality ++ ++standard_testfile main.c ++ ++load_lib dwarf.exp ++ ++if { [which debuginfod] == 0 } { ++ untested "cannot find debuginfod" ++ return -1 ++} ++ ++if { [which curl] == 0 } { ++ untested "cannot find curl" ++ return -1 ++} ++ ++# Skip testing if gdb was not configured with debuginfod ++if { [string first "with-debuginfod" [exec $GDB --configuration]] == -1 } { ++ untested "gdb not configured with debuginfod" ++ return -1 ++} ++ ++set cache [standard_output_file ".client_cache"] ++set db [standard_output_file ".debuginfod.db"] ++ ++# Delete any preexisting test files ++file delete -force $cache ++file delete -force $db ++ ++set sourcetmp [standard_output_file tmp-${srcfile}] ++set outputdir [standard_output_file {}] ++ ++# Make a copy source file that we can move around ++if { [catch {file copy -force ${srcdir}/${subdir}/${srcfile} \ ++ [standard_output_file ${sourcetmp}]}] != 0 } { ++ error "create temporary file" ++ return -1 ++} ++ ++if { [gdb_compile "$sourcetmp" "$binfile" executable {debug}] != "" } { ++ fail "compile" ++ return -1 ++} ++ ++setenv DEBUGINFOD_URLS "" ++setenv DEBUGINFOD_TIMEOUT 30 ++setenv DEBUGINFOD_CACHE_PATH $cache ++ ++# Test that gdb cannot find source without debuginfod ++clean_restart $binfile ++gdb_test_no_output "set substitute-path $outputdir /dev/null" ++gdb_test "list" ".*No such file or directory.*" ++ ++# Strip symbols into separate file and move it so gdb cannot find it without debuginfod ++if { [gdb_gnu_strip_debug $binfile ""] != 0 } { ++ fail "strip debuginfo" ++ return -1 ++} ++ ++set debugdir [standard_output_file "debug"] ++set debuginfo [standard_output_file "fetch_src_and_symbols.debug"] ++ ++file mkdir $debugdir ++file rename -force $debuginfo $debugdir ++ ++# Test that gdb cannot find symbols without debuginfod ++clean_restart $binfile ++gdb_test "file" ".*No symbol file.*" ++ ++# Write some assembly that just has a .gnu_debugaltlink section. ++# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp. ++proc write_just_debugaltlink {filename dwzname buildid} { ++ set asm_file [standard_output_file $filename] ++ ++ Dwarf::assemble $asm_file { ++ upvar dwzname dwzname ++ upvar buildid buildid ++ ++ gnu_debugaltlink $dwzname $buildid ++ ++ # Only the DWARF reader checks .gnu_debugaltlink, so make sure ++ # there is a bit of DWARF in here. ++ cu {} { ++ compile_unit {{language @DW_LANG_C}} { ++ } ++ } ++ } ++} ++ ++# Write some DWARF that also sets the buildid. ++# Copied from testsuite/gdb.dwarf2/dwzbuildid.exp. ++proc write_dwarf_file {filename buildid {value 99}} { ++ set asm_file [standard_output_file $filename] ++ ++ Dwarf::assemble $asm_file { ++ declare_labels int_label int_label2 ++ ++ upvar buildid buildid ++ upvar value value ++ ++ build_id $buildid ++ ++ cu {} { ++ compile_unit {{language @DW_LANG_C}} { ++ int_label2: base_type { ++ {name int} ++ {byte_size 4 sdata} ++ {encoding @DW_ATE_signed} ++ } ++ ++ constant { ++ {name the_int} ++ {type :$int_label2} ++ {const_value $value data1} ++ } ++ } ++ } ++ } ++} ++ ++set buildid "01234567890abcdef0123456" ++ ++write_just_debugaltlink ${binfile}_has_altlink.S ${binfile}_dwz.o $buildid ++write_dwarf_file ${binfile}_dwz.S $buildid ++ ++if {[gdb_compile ${binfile}_has_altlink.S ${binfile}_alt.o object nodebug] != ""} { ++ fail "compile main with altlink" ++ return -1 ++} ++ ++if {[gdb_compile ${binfile}_dwz.S ${binfile}_dwz.o object nodebug] != ""} { ++ fail "compile altlink" ++ return -1 ++} ++ ++file rename -force ${binfile}_dwz.o $debugdir ++ ++# Test that gdb cannot find dwz without debuginfod. ++clean_restart ++gdb_test "file ${binfile}_alt.o" ".*could not find '.gnu_debugaltlink'.*" ++ ++# Find an unused port ++set port 7999 ++set found 0 ++while { ! $found } { ++ incr port ++ if { $port == 65536 } { ++ fail "no available ports" ++ return -1 ++ } ++ ++ spawn debuginfod -vvvv -d $db -p $port -F $debugdir ++ expect { ++ "started http server on IPv4 IPv6 port=$port" { set found 1 } ++ "failed to bind to port" { kill_wait_spawned_process $spawn_id } ++ timeout { ++ fail "find port timeout" ++ return -1 ++ } ++ } ++} ++ ++set metrics [list "ready 1" \ ++ "thread_work_total{role=\"traverse\"} 1" \ ++ "thread_work_pending{role=\"scan\"} 0" \ ++ "thread_busy{role=\"scan\"} 0"] ++ ++# Check server metrics to confirm init has completed. ++foreach m $metrics { ++ set timelim 20 ++ while { $timelim != 0 } { ++ sleep 0.5 ++ catch {exec curl -s http://127.0.0.1:$port/metrics} got ++ ++ if { [regexp $m $got] } { ++ break ++ } ++ ++ incr timelim -1 ++ } ++ ++ if { $timelim == 0 } { ++ fail "server init timeout" ++ break ++ } ++} ++ ++# Point the client to the server ++setenv DEBUGINFOD_URLS http://127.0.0.1:$port ++ ++# gdb should now find the symbol and source files ++clean_restart $binfile ++gdb_test_no_output "set substitute-path $outputdir /dev/null" ++gdb_test "br main" "Breakpoint 1 at.*file.*" ++gdb_test "l" ".*This program is distributed in the hope.*" ++ ++# gdb should now find the debugaltlink file ++clean_restart ++gdb_test "file ${binfile}_alt.o" ".*Reading symbols from ${binfile}_alt.o\.\.\.*" +diff --git a/gdb/testsuite/gdb.debuginfod/main.c b/gdb/testsuite/gdb.debuginfod/main.c +new file mode 100644 +--- /dev/null ++++ b/gdb/testsuite/gdb.debuginfod/main.c +@@ -0,0 +1,25 @@ ++/* This testcase is part of GDB, the GNU debugger. ++ ++ Copyright 2020 Free Software Foundation, Inc. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . */ ++ ++/* Dummy main function. */ ++ ++int ++main() ++{ ++ asm ("main_label: .globl main_label"); ++ return 0; ++} +diff --git a/gdb/top.c b/gdb/top.c +--- a/gdb/top.c ++++ b/gdb/top.c +@@ -1513,6 +1513,17 @@ This GDB was configured as follows:\n\ + --without-python\n\ + ")); + #endif ++ ++#if HAVE_LIBDEBUGINFOD ++ fprintf_filtered (stream, _("\ ++ --with-debuginfod\n\ ++")); ++#else ++ fprintf_filtered (stream, _("\ ++ --without-debuginfod\n\ ++")); ++#endif ++ + #if HAVE_GUILE + fprintf_filtered (stream, _("\ + --with-guile\n\ diff --git a/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch b/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch new file mode 100644 index 0000000..e3763fe --- /dev/null +++ b/SOURCES/gdb-rhbz1844458-use-fputX_unfiltered.patch @@ -0,0 +1,123 @@ +From FEDORA_PATCHES Mon Sep 17 00:00:00 2001 +From: Keith Seitz +Date: Mon, 8 Jun 2020 11:33:47 -0700 +Subject: gdb-rhbz1844458-use-fputX_unfiltered.patch + +;; Fix fput?_unfiltered functions +;; RH BZ 1844458 (Sergio Durigan Junior and Tom Tromey) + +From 9effb44ccbf50c16da66aaab5fd535fe17e38e32 Mon Sep 17 00:00:00 2001 +From: Sergio Durigan Junior +Date: Wed, 19 Feb 2020 16:40:48 -0500 +Subject: [PATCH] Make '{putchar,fputc}_unfiltered' use 'fputs_unfiltered' + +There is currently a regression when using +'{putchar,fputc}_unfiltered' with 'puts_unfiltered' which was +introduced by one of the commits that reworked the unfiltered print +code. + +The regression makes it impossible to use '{putchar,fputc}_unfiltered' +with 'puts_unfiltered', because the former writes directly to the +ui_file stream using 'stream->write', while the latter uses a buffered +mechanism (see 'wrap_buffer') and delays the printing. + +If you do a quick & dirty hack on e.g. top.c:show_gdb_datadir: + + @@ -2088,6 +2088,13 @@ static void + show_gdb_datadir (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) + { + + putchar_unfiltered ('\n'); + + puts_unfiltered ("TEST"); + + putchar_unfiltered ('>'); + + puts_unfiltered ("PUTS"); + + puts_unfiltered ("PUTS"); + + putchar_unfiltered ('\n'); + +rebuild GDB and invoke the "show data-directory" command, you will +see: + + (gdb) show data-directory + + > + TESTPUTSGDB's data directory is "/usr/local/share/gdb". + +Note how the '>' was printed before the output, and "TEST" and "PUTS" +were printed together. + +My first attempt to fix this was to always call 'flush_wrap_buffer' at +the end of 'fputs_maybe_filtered', since it seemed to me that the +function should always print what was requested. But I wasn't sure +this was the right thing to do, so I talked to Tom on IRC and he gave +me another, simpler idea: make '{putchar,fputc}_unfiltered' call into +the already existing 'fputs_unfiltered' function. + +This patch implements the idea. I regtested it on the Buildbot, and +no regressions were detected. + +gdb/ChangeLog: +2020-02-20 Sergio Durigan Junior + Tom Tromey + + * utils.c (fputs_maybe_filtered): Call 'stream->puts' instead + of 'fputc_unfiltered'. + (putchar_unfiltered): Call 'fputc_unfiltered'. + (fputc_unfiltered): Call 'fputs_unfiltered'. + +diff --git a/gdb/utils.c b/gdb/utils.c +--- a/gdb/utils.c ++++ b/gdb/utils.c +@@ -1783,7 +1783,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream, + newline -- if chars_per_line is right, we + probably just overflowed anyway; if it's wrong, + let us keep going. */ +- fputc_unfiltered ('\n', stream); ++ /* XXX: The ideal thing would be to call ++ 'stream->putc' here, but we can't because it ++ currently calls 'fputc_unfiltered', which ends up ++ calling us, which generates an infinite ++ recursion. */ ++ stream->puts ("\n"); + } + else + { +@@ -1828,7 +1833,12 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream, + wrap_here ((char *) 0); /* Spit out chars, cancel + further wraps. */ + lines_printed++; +- fputc_unfiltered ('\n', stream); ++ /* XXX: The ideal thing would be to call ++ 'stream->putc' here, but we can't because it ++ currently calls 'fputc_unfiltered', which ends up ++ calling us, which generates an infinite ++ recursion. */ ++ stream->puts ("\n"); + lineptr++; + } + } +@@ -1923,10 +1933,7 @@ fputs_highlighted (const char *str, const compiled_regex &highlight, + int + putchar_unfiltered (int c) + { +- char buf = c; +- +- ui_file_write (gdb_stdout, &buf, 1); +- return c; ++ return fputc_unfiltered (c, gdb_stdout); + } + + /* Write character C to gdb_stdout using GDB's paging mechanism and return C. +@@ -1941,9 +1948,11 @@ putchar_filtered (int c) + int + fputc_unfiltered (int c, struct ui_file *stream) + { +- char buf = c; ++ char buf[2]; + +- ui_file_write (stream, &buf, 1); ++ buf[0] = c; ++ buf[1] = 0; ++ fputs_unfiltered (buf, stream); + return c; + } + diff --git a/SPECS/gdb.spec b/SPECS/gdb.spec index f939966..4aa3055 100644 --- a/SPECS/gdb.spec +++ b/SPECS/gdb.spec @@ -1,7 +1,3 @@ -# This package depends on automagic byte compilation -# https://fedoraproject.org/wiki/Changes/No_more_automagic_Python_bytecompilation_phase_2 -%global _python_bytecompile_extra 1 - # rpmbuild parameters: # --with testsuite: Run the testsuite (biarch if possible). Default is without. # --with buildisa: Use %%{?_isa} for BuildRequires @@ -11,6 +7,9 @@ # workload gets run it decreases the general performance now. # --define 'scl somepkgname': Independent packages by scl-utils-build. +# Turn off the brp-python-bytecompile automagic +%global _python_bytecompile_extra 0 + %{?scl:%scl_package gdb} %{!?scl: %global pkg_name %{name} @@ -31,11 +30,11 @@ Name: %{?scl_prefix}gdb # See timestamp of source gnulib installed into gnulib/ . %global snapgnulib 20191216 %global tarname gdb-%{version} -Version: 9.1 +Version: 9.2 # The release always contains a leading reserved number, start it at 1. # `upstream' is not a part of `name' to stay fully rpm dependencies compatible for the testing. -Release: 7%{?dist} +Release: 2%{?dist} License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL # Do not provide URL for snapshots as the file lasts there only for 2 days. @@ -199,9 +198,9 @@ Patch1119: gdb-testsuite-readline63-sigint-revert.patch # Include the auto-generated file containing the "Patch:" directives. # See README.local-patches for more details. -Source8: _gdb.spec.Patch.include -Source9: _gdb.spec.patch.include -%include %{SOURCE8} +Patch9998: _gdb.spec.Patch.include +Patch9999: _gdb.spec.patch.include +%include %{PATCH9998} %if 0%{!?rhel:1} || 0%{?rhel} > 6 # RL_STATE_FEDORA_GDB would not be found for: @@ -263,9 +262,11 @@ BuildRequires: mpfr-devel%{buildisa} BuildRequires: source-highlight-devel # Workaround for missing boost-devel dependency (rhbz 1718480) BuildRequires: boost-devel + %if 0%{!?rhel:1} || 0%{?rhel} > 8 BuildRequires: xxhash-devel %endif +BuildRequires: elfutils-debuginfod-client-devel %if 0%{?_with_testsuite:1} @@ -377,6 +378,7 @@ BuildRequires: xz BuildRequires: rust %endif +BuildRequires: %{?scl_prefix}elfutils-debuginfod %endif # 0%{?_with_testsuite:1} %{?scl:Requires:%scl_runtime} @@ -467,7 +469,7 @@ find -name "*.info*"|xargs rm -f # Include the auto-generated "%patch" directives. # See README.local-patches for more details. -%include %{SOURCE9} +%include %{PATCH9999} %if 0%{!?el6:1} for i in \ @@ -566,7 +568,8 @@ COMMON_GDB_CONFIGURE_FLAGS="\ --with-lzma \ %else --without-lzma \ -%endif +%endif \ + --with-debuginfod " # Identify the build directory with the version of gdb as well as the @@ -954,6 +957,11 @@ for pyo in "" "-O";do done %endif # 0%{?_enable_debug_packages:1} && 0%{!?_without_python:1} +# Compile python files +%if 0%{!?_without_python:1} +%py_byte_compile %{__python3} %{buildroot}%{_datadir}/gdb/python/gdb +%endif + %if 0%{!?_without_python:1} %if 0%{!?rhel:1} || 0%{?rhel} > 6 # BZ 999645: /usr/share/gdb/auto-load/ needs filesystem symlinks @@ -1159,9 +1167,21 @@ fi %endif %changelog -* Thu May 28 2020 Keith Seitz - 9.1-7 -- Add fedora/rhel conditional for xxhash-devel BuildRequire. -- Include workaround for RHBZ 1718480. +* Tue Jun 9 2020 Keith Seitz - 9.2-2 +- Backport debuginfod support. + +* Tue Jun 9 2020 Keith Seitz - 9.2-1 +- Rebase to FSF GDB 9.2. +- Add explicit python bytecode compilation. +- Change included files to patches to quell error from rpminspect. +- Fix attach-32.exp from gdb-6.3-inferior-notification-20050721.patch. + +* Fri Jun 5 2020 Keith Seitz - 9.1-8 +- Add patch for Python 3.9 and re-enable python. +- Update generate-*.sh to include stgit support. + +* Thu May 21 2020 Miro HronĨok - 9.1-7 +- Disable Python support to workaround problems with Python 3.9 (RHBZ 1829702) * Thu Apr 16 2020 Kevin Buettner - 9.1-6 - Fix build breakage of gdb/python/python.c due to use of deprecated