public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Aaron Merey <amerey@redhat.com>
To: gdb-patches@sourceware.org
Cc: simark@simark.ca, keiths@redhat.com
Subject: [PATCH 1/2] gdb: add set/show commands for managing debuginfod
Date: Mon, 18 Oct 2021 19:01:32 -0400	[thread overview]
Message-ID: <20211018230133.265619-2-amerey@redhat.com> (raw)
In-Reply-To: <20211018230133.265619-1-amerey@redhat.com>

Add 'set/show debuginfod' command.  Accepts "on", "off" or "ask" as
an argument.  "on" enables debuginfod for the current session.  "off"
disables debuginfod for the current session.  "ask" will prompt
the user to either enable or disable debuginfod when the next query
is about to be performed:

  This GDB supports auto-downloading debuginfo from the following URLs:
  <URL1> <URL2> ...
  Enable debuginfod? (y or [n]) y
  Debuginfod has been enabled.
  To make this setting permanent, add 'set debuginfod on' to .gdbinit.

For interactive sessions, "ask" is the default. For non-interactive
sessions, "no" is the default.

Also add 'set/show debuginfod-urls' command. Accepts a string of
space-separated debuginfod server URLs to be queried. The default
value is copied from $DEBUGINFOD_URLS.

Finally add 'set debug debuginfod" command to control whether
debuginfod-related debugging output is displayed. This debugging
output is displayed by default.

  (gdb) run
  Starting program: /bin/sleep 5
  Download failed: No route to host.  Continuing without debug info for /lib64/libc.so.6.
---
 gdb/debuginfod-support.c                      | 151 +++++++++++++++++-
 .../gdb.debuginfod/fetch_src_and_symbols.exp  |  25 ++-
 2 files changed, 165 insertions(+), 11 deletions(-)

diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
index 2d626e335a0..1a4a6e1dde0 100644
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -18,7 +18,6 @@
 
 #include "defs.h"
 #include <errno.h>
-#include "cli/cli-style.h"
 #include "gdbsupport/scoped_fd.h"
 #include "debuginfod-support.h"
 #include "gdbsupport/gdb_optional.h"
@@ -42,6 +41,8 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
   return scoped_fd (-ENOSYS);
 }
 #else
+#include "cli/cli-cmds.h"
+#include "cli/cli-style.h"
 #include <elfutils/debuginfod.h>
 
 struct user_data
@@ -68,6 +69,63 @@ struct debuginfod_client_deleter
 using debuginfod_client_up
   = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
 
+static const char debuginfod_on[] = "on";
+static const char debuginfod_off[] = "off";
+static const char debuginfod_ask[] = "ask";
+static const char *const debuginfod_cmd_names[] =
+{
+  debuginfod_on,
+  debuginfod_off,
+  debuginfod_ask,
+  NULL,
+};
+
+static const char *debuginfod_enable = debuginfod_ask;
+static std::string debuginfod_urls;
+static bool debuginfod_debug = true;
+
+/* Show whether debuginfod is enabled.  */
+
+static void
+show_debuginfod_command (struct ui_file *file, int from_tty,
+			 struct cmd_list_element *cmd, const char *value)
+{
+   fprintf_unfiltered (file, _("Debuginfod functionality is currently set " \
+		       "to \"%s\".\n"), debuginfod_enable);
+}
+
+/* Set the URLs that debuginfod will query.  */
+
+static void
+set_debuginfod_urls_command (const char *args, int from_tty,
+			     struct cmd_list_element *c)
+{
+  if (setenv ("DEBUGINFOD_URLS", debuginfod_urls.c_str (), 1) != 0)
+    warning (_("Unable to set debuginfod URLs: %s"), strerror (errno));
+}
+
+/* Show the URLs that debuginfod will query.  */
+
+static void
+show_debuginfod_urls_command (struct ui_file *file, int from_tty,
+			      struct cmd_list_element *cmd, const char *value)
+{
+  if (debuginfod_urls.empty ())
+    fprintf_unfiltered (file, _("You have not set debuginfod URLs.\n"));
+  else
+    fprintf_filtered (file, _("Debuginfod URLs are currently set to:\n%s\n"),
+		      value);
+}
+
+/* Show whether to display debuginfod debugging output.  */
+
+static void
+show_debuginfod_debug_command (struct ui_file *file, int from_tty,
+			       struct cmd_list_element *cmd, const char *value)
+{
+  fprintf_filtered (file, _("Debuginfod debugging output is %s.\n"), value);
+}
+
 static int
 progressfn (debuginfod_client *c, long cur, long total)
 {
@@ -120,6 +178,39 @@ get_debuginfod_client ()
   return global_client.get ();
 }
 
+/* Check if debuginfod is enabled. If configured to do so, ask the user
+   whether to enable debuginfod.  */
+
+static bool
+debuginfod_enabled ()
+{
+   if (debuginfod_urls.empty ()
+       || strcmp (debuginfod_enable, debuginfod_off) == 0)
+    return false;
+
+  if (strcmp (debuginfod_enable, debuginfod_ask) == 0)
+    {
+      int resp = nquery (_("\nThis GDB supports auto-downloading debuginfo " \
+			   "from the following URLs:\n%s\nEnable debuginfod? "),
+			 debuginfod_urls.c_str ());
+      if (!resp)
+	{
+	  printf_filtered (_("Debuginfod has been disabled.\nTo make this " \
+			     "setting permanent, add \'set debuginfod off\' " \
+			     "to .gdbinit.\n"));
+	  debuginfod_enable = debuginfod_off;
+	  return false;
+	}
+
+      printf_filtered (_("Debuginfod has been enabled.\nTo make this " \
+			 "setting permanent, add \'set debuginfod on\' " \
+			 "to .gdbinit.\n"));
+      debuginfod_enable = debuginfod_on;
+    }
+
+  return true;
+}
+
 /* See debuginfod-support.h  */
 
 scoped_fd
@@ -128,8 +219,7 @@ debuginfod_source_query (const unsigned char *build_id,
 			 const char *srcpath,
 			 gdb::unique_xmalloc_ptr<char> *destname)
 {
-  const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
-  if (urls_env_var == NULL || urls_env_var[0] == '\0')
+  if (!debuginfod_enabled ())
     return scoped_fd (-ENOSYS);
 
   debuginfod_client *c = get_debuginfod_client ();
@@ -147,8 +237,7 @@ debuginfod_source_query (const unsigned char *build_id,
 					nullptr));
   debuginfod_set_user_data (c, nullptr);
 
-  /* TODO: Add 'set debug debuginfod' command to control when error messages are shown.  */
-  if (fd.get () < 0 && fd.get () != -ENOENT)
+  if (debuginfod_debug && fd.get () < 0 && fd.get () != -ENOENT)
     printf_filtered (_("Download failed: %s.  Continuing without source file %ps.\n"),
 		     safe_strerror (-fd.get ()),
 		     styled_string (file_name_style.style (),  srcpath));
@@ -167,8 +256,7 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
 			    const char *filename,
 			    gdb::unique_xmalloc_ptr<char> *destname)
 {
-  const char *urls_env_var = getenv (DEBUGINFOD_URLS_ENV_VAR);
-  if (urls_env_var == NULL || urls_env_var[0] == '\0')
+  if (!debuginfod_enabled ())
     return scoped_fd (-ENOSYS);
 
   debuginfod_client *c = get_debuginfod_client ();
@@ -184,7 +272,7 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
 					   &dname));
   debuginfod_set_user_data (c, nullptr);
 
-  if (fd.get () < 0 && fd.get () != -ENOENT)
+  if (debuginfod_debug && fd.get () < 0 && fd.get () != -ENOENT)
     printf_filtered (_("Download failed: %s.  Continuing without debug info for %ps.\n"),
 		     safe_strerror (-fd.get ()),
 		     styled_string (file_name_style.style (),  filename));
@@ -195,3 +283,50 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
   return fd;
 }
 #endif
+
+/* Register debuginfod commands.  */
+
+void _initialize_debuginfod ();
+void
+_initialize_debuginfod ()
+{
+#ifdef HAVE_LIBDEBUGINFOD
+  char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
+
+  if (urls != nullptr)
+    debuginfod_urls = urls;
+
+  add_setshow_enum_cmd ("debuginfod", class_run, debuginfod_cmd_names,
+			&debuginfod_enable, _("\
+Set whether debuginfod is enabled."), _("\
+Show whether debuginfod is enabled."), _("\
+Automatically query debuginfod servers for missing debuginfo, executables \
+or source files. This command accepts the following arguments:\n\
+  on  - debuginfod will be enabled\n\
+  off - debuginfod will be disabled\n\
+  ask - an interactive prompt will ask whether to enable debuginfod\n\
+For interactive sessions, \"ask\" is the default. For non-interactive \
+sessions, \"off\" is the default."),
+			NULL, show_debuginfod_command, &setlist, &showlist);
+
+  add_setshow_string_noescape_cmd ("debuginfod-urls", class_run,
+				   &debuginfod_urls, _("\
+Set the list of debuginfod server URLs."), _("\
+Show the list of debuginfod server URLs."), _("\
+Manage the space-separated list of debuginfod server URLs that GDB will query \
+when missing debuginfo, executables or source files.\nThe default value is \
+copied from $DEBUGINFOD_URLS."),
+				   set_debuginfod_urls_command,
+				   show_debuginfod_urls_command,
+				   &setlist, &showlist);
+
+  add_setshow_boolean_cmd ("debuginfod", class_maintenance,
+			   &debuginfod_debug, _("\
+Set debuginfod debugging."), _("\
+Show debuginfod debugging."), _("\
+When set, display debugging output for debuginfod. \
+Displayed by default"),
+			   NULL, show_debuginfod_debug_command,
+			   &setdebuglist, &showdebuglist);
+#endif
+}
diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
index 93490fce41e..cbf4cce1b00 100644
--- a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
+++ b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
@@ -217,7 +217,8 @@ proc local_url { } {
     setenv DEBUGINFOD_URLS http://127.0.0.1:$port
 
     # gdb should now find the symbol and source files
-    clean_restart $binfile
+    clean_restart
+    gdb_test "file $binfile" "" "file [file tail $binfile]" "Enable debuginfod?.*" "y"
     gdb_test_no_output "set substitute-path $outputdir /dev/null" \
 	"set substitute-path"
     gdb_test "br main" "Breakpoint 1 at.*file.*"
@@ -226,8 +227,26 @@ proc local_url { } {
     # gdb should now find the debugaltlink file
     clean_restart
     gdb_test "file ${binfile}_alt.o" \
-	".*Reading symbols from ${binfile}_alt.o\.\.\.*" \
-	"file [file tail ${binfile}_alt.o]"
+	".*Downloading.*separate debug info.*" \
+	"file [file tail ${binfile}_alt.o]" \
+	".*Enable debuginfod?.*" "y"
+
+    # Configure debuginfod with commands
+    unsetenv DEBUGINFOD_URLS
+    clean_restart
+    gdb_test "file $binfile" ".*No debugging symbols.*" \
+	"file [file tail $binfile] cmd"
+    gdb_test_no_output "set debuginfod off"
+    gdb_test_no_output "set debuginfod-urls http://127.0.0.1:$port"
+
+    # gdb shouldn't find the debuginfo since debuginfod has been disabled
+    gdb_test "file $binfile" ".*No debugging symbols.*" \
+	"file [file tail $binfile] cmd off"
+
+    # Enable debuginfod and fetch the debuginfo
+    gdb_test_no_output "set debuginfod on"
+    gdb_test "file $binfile" ".*Reading symbols from.*debuginfo.*" \
+	"file [file tail $binfile] cmd on"
 }
 
 set envlist \
-- 
2.31.1


  reply	other threads:[~2021-10-18 23:01 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-18 23:01 [PATCH 0/2 v3] gdb: Add debuginfod first-use notification Aaron Merey
2021-10-18 23:01 ` Aaron Merey [this message]
2021-10-20 20:34   ` [PATCH 1/2] gdb: add set/show commands for managing debuginfod Keith Seitz
2021-10-21 22:23     ` Lancelot SIX
2021-10-25 22:30       ` Aaron Merey
2021-10-21 22:02   ` Lancelot SIX
2021-10-26 16:08   ` Simon Marchi
2021-10-28 22:18     ` Aaron Merey
2021-10-29  1:47       ` Simon Marchi
2021-10-30  1:09         ` Aaron Merey
2021-10-30  1:54           ` Simon Marchi
2021-10-31  2:43             ` Simon Marchi
2021-11-01 15:52               ` Simon Marchi
2021-11-01 17:39                 ` Aaron Merey
2021-11-01 18:00                   ` Simon Marchi
2021-11-02 16:51                     ` Simon Marchi
2021-11-02 20:35                       ` Aaron Merey
2021-10-18 23:01 ` [PATCH 2/2] gdb.texinfo: Expand documentation for debuginfod Aaron Merey
2021-10-19 11:17   ` Eli Zaretskii
2021-10-19 22:35     ` Aaron Merey
2021-10-20 11:38       ` Eli Zaretskii
2021-10-30  1:18         ` Aaron Merey
2021-10-30  6:57           ` Tom de Vries

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211018230133.265619-2-amerey@redhat.com \
    --to=amerey@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=keiths@redhat.com \
    --cc=simark@simark.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).