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

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