Blame SOURCES/gdb-rhbz2024875-set_show-for-managing-debuginfod.patch

b94e32
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
b94e32
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
b94e32
Date: Mon, 10 Jan 2022 13:35:45 +0100
b94e32
Subject: gdb-rhbz2024875-set_show-for-managing-debuginfod.patch
b94e32
b94e32
;;Backport upstream commit from Aaron Merey
b94e32
;;7811fa5995f gdb: add set/show commands for managing debuginfo
b94e32
b94e32
gdb: add set/show commands for managing debuginfod
b94e32
b94e32
Add 'set debuginfod' command.  Accepts 'on', 'off' or 'ask' as an
b94e32
argument.  'on' enables debuginfod for the current session.  'off'
b94e32
disables debuginfod for the current session.  'ask' will prompt
b94e32
the user to either enable or disable debuginfod when the next query
b94e32
is about to be performed:
b94e32
b94e32
    This GDB supports auto-downloading debuginfo from the following URLs:
b94e32
    <URL1> <URL2> ...
b94e32
    Enable debuginfod for this session? (y or [n]) y
b94e32
    Debuginfod has been enabled.
b94e32
    To make this setting permanent, add 'set debuginfod on' to .gdbinit.
b94e32
b94e32
For interactive sessions, 'ask' is the default.  For non-interactive
b94e32
sessions, 'off' is the default.
b94e32
b94e32
Add 'show debuginfod status' command.  Displays whether debuginfod
b94e32
is set to 'on', 'off' or 'ask'.
b94e32
b94e32
Add 'set/show debuginfod urls' commands. Accepts a string of
b94e32
space-separated debuginfod server URLs to be queried.  The default
b94e32
value is copied from the DEBUGINFOD_URLS environment variable.
b94e32
b94e32
Finally add 'set/show debuginfod verbose' commands to control whether
b94e32
debuginfod-related output is displayed.  Verbose output is enabled
b94e32
by default.
b94e32
b94e32
    (gdb) run
b94e32
    Starting program: /bin/sleep 5
b94e32
    Download failed: No route to host.  Continuing without debug info for /lib64/libc.so.6.
b94e32
b94e32
If GDB is not built with debuginfod then these commands will just display
b94e32
b94e32
    Support for debuginfod is not compiled into GDB.
b94e32
b94e32
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
b94e32
--- a/gdb/debuginfod-support.c
b94e32
+++ b/gdb/debuginfod-support.c
b94e32
@@ -18,10 +18,26 @@
b94e32
 
b94e32
 #include "defs.h"
b94e32
 #include <errno.h>
b94e32
-#include "cli/cli-style.h"
b94e32
 #include "gdbsupport/scoped_fd.h"
b94e32
 #include "debuginfod-support.h"
b94e32
 #include "gdbsupport/gdb_optional.h"
b94e32
+#include "cli/cli-cmds.h"
b94e32
+#include "cli/cli-style.h"
b94e32
+
b94e32
+/* Set/show debuginfod commands.  */
b94e32
+static cmd_list_element *set_debuginfod_prefix_list;
b94e32
+static cmd_list_element *show_debuginfod_prefix_list;
b94e32
+
b94e32
+static const char debuginfod_on[] = "on";
b94e32
+static const char debuginfod_off[] = "off";
b94e32
+static const char debuginfod_ask[] = "ask";
b94e32
+
b94e32
+static const char *debuginfod_enable = debuginfod_ask;
b94e32
+static unsigned debuginfod_verbose = 1;
b94e32
+
b94e32
+/* This is never actually used.  URLs are always pulled from the
b94e32
+   environment.  */
b94e32
+static char *debuginfod_urls;
b94e32
 
b94e32
 #ifndef HAVE_LIBDEBUGINFOD
b94e32
 scoped_fd
b94e32
@@ -41,6 +57,67 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
b94e32
 {
b94e32
   return scoped_fd (-ENOSYS);
b94e32
 }
b94e32
+
b94e32
+#define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
b94e32
+
b94e32
+/* Stub set/show commands that indicate debuginfod is not supported.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_on_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+  debuginfod_enable = debuginfod_off;
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_off_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+  debuginfod_enable = debuginfod_off;
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_ask_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+  debuginfod_enable = debuginfod_off;
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_status_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_urls_command (const char *ignore, int from_tty,
b94e32
+                             struct cmd_list_element *c)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_urls_command (struct ui_file *file, int from_tty,
b94e32
+			      struct cmd_list_element *cmd, const char *value)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_verbose_command (const char *args, int from_tty,
b94e32
+				struct cmd_list_element *c)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+  debuginfod_verbose = 0;
b94e32
+}
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_verbose_command (struct ui_file *file, int from_tty,
b94e32
+				 struct cmd_list_element *cmd,
b94e32
+				 const char *value)
b94e32
+{
b94e32
+  error (NO_IMPL);
b94e32
+}
b94e32
 #else
b94e32
 #include <elfutils/debuginfod.h>
b94e32
 
b94e32
@@ -68,6 +145,82 @@ struct debuginfod_client_deleter
b94e32
 using debuginfod_client_up
b94e32
   = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
b94e32
 
b94e32
+/* Enable debuginfod.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_on_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  debuginfod_enable = debuginfod_on;
b94e32
+}
b94e32
+
b94e32
+/* Disable debuginfod.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_off_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  debuginfod_enable = debuginfod_off;
b94e32
+}
b94e32
+
b94e32
+/* Before next query, ask user whether to enable debuginfod.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_ask_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  debuginfod_enable = debuginfod_ask;
b94e32
+}
b94e32
+
b94e32
+/* Show whether debuginfod is enabled.  */
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_status_command (const char *args, int from_tty)
b94e32
+{
b94e32
+  printf_unfiltered (_("Debuginfod functionality is currently set to " \
b94e32
+		     "\"%s\".\n"), debuginfod_enable);
b94e32
+}
b94e32
+
b94e32
+/* Set the URLs that debuginfod will query.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_urls_command (const char *ignore, int from_tty,
b94e32
+                             struct cmd_list_element *c)
b94e32
+{
b94e32
+  gdb_assert (debuginfod_urls != nullptr);
b94e32
+  if (setenv ("DEBUGINFOD_URLS", debuginfod_urls, 1) != 0)
b94e32
+    warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno));
b94e32
+}
b94e32
+
b94e32
+/* Show the URLs that debuginfod will query.  */
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_urls_command (struct ui_file *file, int from_tty,
b94e32
+			      struct cmd_list_element *cmd, const char *value)
b94e32
+{
b94e32
+  if (value == nullptr || value[0] == '\0')
b94e32
+    fprintf_unfiltered (file, _("Debuginfod URLs have not been set.\n"));
b94e32
+  else
b94e32
+    fprintf_filtered (file, _("Debuginfod URLs are currently set to:\n%s\n"),
b94e32
+		      value);
b94e32
+}
b94e32
+
b94e32
+/* No-op setter used for compatibility when gdb is built without debuginfod.  */
b94e32
+
b94e32
+static void
b94e32
+set_debuginfod_verbose_command (const char *args, int from_tty,
b94e32
+				struct cmd_list_element *c)
b94e32
+{
b94e32
+  return;
b94e32
+}
b94e32
+
b94e32
+/* Show verbosity.  */
b94e32
+
b94e32
+static void
b94e32
+show_debuginfod_verbose_command (struct ui_file *file, int from_tty,
b94e32
+				 struct cmd_list_element *cmd, const char *value)
b94e32
+{
b94e32
+  fprintf_filtered (file, _("Debuginfod verbose output is set to %s.\n"),
b94e32
+		    value);
b94e32
+}
b94e32
+
b94e32
 static int
b94e32
 progressfn (debuginfod_client *c, long cur, long total)
b94e32
 {
b94e32
@@ -120,6 +273,42 @@ get_debuginfod_client ()
b94e32
   return global_client.get ();
b94e32
 }
b94e32
 
b94e32
+/* Check if debuginfod is enabled.  If configured to do so, ask the user
b94e32
+   whether to enable debuginfod.  */
b94e32
+
b94e32
+static bool
b94e32
+debuginfod_enabled ()
b94e32
+{
b94e32
+  const char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
b94e32
+
b94e32
+  if (urls == nullptr || urls[0] == '\0'
b94e32
+      || debuginfod_enable == debuginfod_off)
b94e32
+    return false;
b94e32
+
b94e32
+  if (debuginfod_enable == debuginfod_ask)
b94e32
+    {
b94e32
+      int resp = nquery (_("\nThis GDB supports auto-downloading debuginfo " \
b94e32
+			   "from the following URLs:\n%s\nEnable debuginfod " \
b94e32
+			   "for this session? "),
b94e32
+			 urls);
b94e32
+      if (!resp)
b94e32
+	{
b94e32
+	  printf_filtered (_("Debuginfod has been disabled.\nTo make this " \
b94e32
+			     "setting permanent, add \'set debuginfod off\' " \
b94e32
+			     "to .gdbinit.\n"));
b94e32
+	  debuginfod_enable = debuginfod_off;
b94e32
+	  return false;
b94e32
+	}
b94e32
+
b94e32
+      printf_filtered (_("Debuginfod has been enabled.\nTo make this " \
b94e32
+			 "setting permanent, add \'set debuginfod on\' " \
b94e32
+			 "to .gdbinit.\n"));
b94e32
+      debuginfod_enable = debuginfod_on;
b94e32
+    }
b94e32
+
b94e32
+  return true;
b94e32
+}
b94e32
+
b94e32
 /* See debuginfod-support.h  */
b94e32
 
b94e32
 scoped_fd
b94e32
@@ -128,8 +317,7 @@ debuginfod_source_query (const unsigned char *build_id,
b94e32
 			 const char *srcpath,
b94e32
 			 gdb::unique_xmalloc_ptr<char> *destname)
b94e32
 {
b94e32
-  const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
b94e32
-  if (urls_env_var == NULL || urls_env_var[0] == '\0')
b94e32
+  if (!debuginfod_enabled ())
b94e32
     return scoped_fd (-ENOSYS);
b94e32
 
b94e32
   debuginfod_client *c = get_debuginfod_client ();
b94e32
@@ -147,8 +335,7 @@ debuginfod_source_query (const unsigned char *build_id,
b94e32
 					nullptr));
b94e32
   debuginfod_set_user_data (c, nullptr);
b94e32
 
b94e32
-  /* TODO: Add 'set debug debuginfod' command to control when error messages are shown.  */
b94e32
-  if (fd.get () < 0 && fd.get () != -ENOENT)
b94e32
+  if (debuginfod_verbose > 0 && fd.get () < 0 && fd.get () != -ENOENT)
b94e32
     printf_filtered (_("Download failed: %s.  Continuing without source file %ps.\n"),
b94e32
 		     safe_strerror (-fd.get ()),
b94e32
 		     styled_string (file_name_style.style (),  srcpath));
b94e32
@@ -167,8 +354,7 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
b94e32
 			    const char *filename,
b94e32
 			    gdb::unique_xmalloc_ptr<char> *destname)
b94e32
 {
b94e32
-  const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
b94e32
-  if (urls_env_var == NULL || urls_env_var[0] == '\0')
b94e32
+  if (!debuginfod_enabled ())
b94e32
     return scoped_fd (-ENOSYS);
b94e32
 
b94e32
   debuginfod_client *c = get_debuginfod_client ();
b94e32
@@ -184,7 +370,7 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
b94e32
 					   &dname));
b94e32
   debuginfod_set_user_data (c, nullptr);
b94e32
 
b94e32
-  if (fd.get () < 0 && fd.get () != -ENOENT)
b94e32
+  if (debuginfod_verbose > 0 && fd.get () < 0 && fd.get () != -ENOENT)
b94e32
     printf_filtered (_("Download failed: %s.  Continuing without debug info for %ps.\n"),
b94e32
 		     safe_strerror (-fd.get ()),
b94e32
 		     styled_string (file_name_style.style (),  filename));
b94e32
@@ -195,3 +381,63 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
b94e32
   return fd;
b94e32
 }
b94e32
 #endif
b94e32
+
b94e32
+/* Register debuginfod commands.  */
b94e32
+
b94e32
+void _initialize_debuginfod ();
b94e32
+void
b94e32
+_initialize_debuginfod ()
b94e32
+{
b94e32
+  /* set/show debuginfod */
b94e32
+  add_basic_prefix_cmd ("debuginfod", class_run,
b94e32
+                        _("Set debuginfod options"),
b94e32
+                        &set_debuginfod_prefix_list, 0, &setlist);
b94e32
+
b94e32
+  add_show_prefix_cmd ("debuginfod", class_run,
b94e32
+                       _("Show debuginfod options"),
b94e32
+                       &show_debuginfod_prefix_list, 0, &showlist);
b94e32
+
b94e32
+  /* set debuginfod on */
b94e32
+  add_cmd ("on", class_run, set_debuginfod_on_command,
b94e32
+	   _("Enable debuginfod."), &set_debuginfod_prefix_list);
b94e32
+
b94e32
+  /* set debuginfod off */
b94e32
+  add_cmd ("off", class_run, set_debuginfod_off_command,
b94e32
+	   _("Disable debuginfod."), &set_debuginfod_prefix_list);
b94e32
+
b94e32
+  /* set debuginfod ask */
b94e32
+  add_cmd ("ask", class_run, set_debuginfod_ask_command, _("\
b94e32
+Ask the user whether to enable debuginfod before performing the next query."),
b94e32
+	   &set_debuginfod_prefix_list);
b94e32
+
b94e32
+  /* show debuginfod status */
b94e32
+  add_cmd ("status", class_run, show_debuginfod_status_command,
b94e32
+	   _("Show whether debuginfod is set to \"on\", \"off\" or \"ask\"."),
b94e32
+	   &show_debuginfod_prefix_list);
b94e32
+
b94e32
+  /* set/show debuginfod urls */
b94e32
+  add_setshow_string_noescape_cmd ("urls", class_run, &debuginfod_urls, _("\
b94e32
+Set the list of debuginfod server URLs."), _("\
b94e32
+Show the list of debuginfod server URLs."), _("\
b94e32
+Manage the space-separated list of debuginfod server URLs that GDB will query \
b94e32
+when missing debuginfo, executables or source files.\nThe default value is \
b94e32
+copied from the DEBUGINFOD_URLS environment variable."),
b94e32
+				   set_debuginfod_urls_command,
b94e32
+				   show_debuginfod_urls_command,
b94e32
+				   &set_debuginfod_prefix_list,
b94e32
+				   &show_debuginfod_prefix_list);
b94e32
+  if (getenv ("DEBUGINFOD_URLS") != nullptr)
b94e32
+    debuginfod_urls = xstrdup (getenv ("DEBUGINFOD_URLS"));
b94e32
+
b94e32
+  /* set/show debuginfod verbose */
b94e32
+  add_setshow_zuinteger_cmd ("verbose", class_support,
b94e32
+			     &debuginfod_verbose, _("\
b94e32
+Set verbosity of debuginfod output."), _("\
b94e32
+Show debuginfod debugging."), _("\
b94e32
+When set to a non-zero value, display verbose output for each debuginfod \
b94e32
+query.\nTo disable, set to zero.  Verbose output is displayed by default."),
b94e32
+			     set_debuginfod_verbose_command,
b94e32
+			     show_debuginfod_verbose_command,
b94e32
+			     &set_debuginfod_prefix_list,
b94e32
+			     &show_debuginfod_prefix_list);
b94e32
+}
b94e32
diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
b94e32
--- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
b94e32
+++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
b94e32
@@ -217,7 +217,8 @@ proc local_url { } {
b94e32
     setenv DEBUGINFOD_URLS http://127.0.0.1:$port
b94e32
 
b94e32
     # gdb should now find the symbol and source files
b94e32
-    clean_restart $binfile
b94e32
+    clean_restart
b94e32
+    gdb_test "file $binfile" "" "file [file tail $binfile]" "Enable debuginfod?.*" "y"
b94e32
     gdb_test_no_output "set substitute-path $outputdir /dev/null" \
b94e32
 	"set substitute-path"
b94e32
     gdb_test "br main" "Breakpoint 1 at.*file.*"
b94e32
@@ -226,8 +227,26 @@ proc local_url { } {
b94e32
     # gdb should now find the debugaltlink file
b94e32
     clean_restart
b94e32
     gdb_test "file ${binfile}_alt.o" \
b94e32
-	".*Reading symbols from ${binfile}_alt.o\.\.\.*" \
b94e32
-	"file [file tail ${binfile}_alt.o]"
b94e32
+	".*Downloading.*separate debug info.*" \
b94e32
+	"file [file tail ${binfile}_alt.o]" \
b94e32
+	".*Enable debuginfod?.*" "y"
b94e32
+
b94e32
+    # Configure debuginfod with commands
b94e32
+    unsetenv DEBUGINFOD_URLS
b94e32
+    clean_restart
b94e32
+    gdb_test "file $binfile" ".*No debugging symbols.*" \
b94e32
+	"file [file tail $binfile] cmd"
b94e32
+    gdb_test_no_output "set debuginfod off"
b94e32
+    gdb_test_no_output "set debuginfod urls http://127.0.0.1:$port"
b94e32
+
b94e32
+    # gdb shouldn't find the debuginfo since debuginfod has been disabled
b94e32
+    gdb_test "file $binfile" ".*No debugging symbols.*" \
b94e32
+	"file [file tail $binfile] cmd off"
b94e32
+
b94e32
+    # Enable debuginfod and fetch the debuginfo
b94e32
+    gdb_test_no_output "set debuginfod on"
b94e32
+    gdb_test "file $binfile" ".*Reading symbols from.*debuginfo.*" \
b94e32
+	"file [file tail $binfile] cmd on"
b94e32
 }
b94e32
 
b94e32
 set envlist \