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

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