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

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