1 Star 0 Fork 44

hwzjyggsddu/gdb

forked from src-openEuler/gdb 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
gdb-rhbz1838777-debuginfod.patch 35.68 KB
一键复制 编辑 原始数据 按行查看 历史
qinyu 提交于 2020-07-24 10:59 . update gdb to 9.2
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
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 <elfutils/debuginfod.h>])
+ 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 <elfutils/debuginfod.h>
+"
+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 <http://www.gnu.org/licenses/>.
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 <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include <errno.h>
+#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<char> *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<char> *destname)
+{
+ return scoped_fd (-ENOSYS);
+}
+#else
+#include <elfutils/debuginfod.h>
+
+/* 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<char> *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<char> *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 <http://www.gnu.org/licenses/>. */
+
+#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<char> *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<char> *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<char> 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<char> 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,215 @@
+# 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 <http://www.gnu.org/licenses/>.
+
+# 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" \
+ [eval exec $GDB $INTERNAL_GDBFLAGS --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"
+ return -1
+ }
+}
+
+# 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 <http://www.gnu.org/licenses/>. */
+
+/* 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\
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/hwzjyggsddu/gdb.git
git@gitee.com:hwzjyggsddu/gdb.git
hwzjyggsddu
gdb
gdb
master

搜索帮助