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

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