415 lines
13 KiB
Diff
415 lines
13 KiB
Diff
|
From FEDORA_PATCHES Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Alexandra=20H=C3=A1jkov=C3=A1?= <ahajkova@redhat.com>
|
||
|
Date: Mon, 10 Jan 2022 13:35:45 +0100
|
||
|
Subject: gdb-rhbz2024875-set_show-for-managing-debuginfod.patch
|
||
|
|
||
|
;;Backport upstream commit from Aaron Merey
|
||
|
;;7811fa5995f gdb: add set/show commands for managing debuginfo
|
||
|
|
||
|
gdb: add set/show commands for managing debuginfod
|
||
|
|
||
|
Add 'set 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 for this session? (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, 'off' is the default.
|
||
|
|
||
|
Add 'show debuginfod status' command. Displays whether debuginfod
|
||
|
is set to 'on', 'off' or 'ask'.
|
||
|
|
||
|
Add 'set/show debuginfod urls' commands. Accepts a string of
|
||
|
space-separated debuginfod server URLs to be queried. The default
|
||
|
value is copied from the DEBUGINFOD_URLS environment variable.
|
||
|
|
||
|
Finally add 'set/show debuginfod verbose' commands to control whether
|
||
|
debuginfod-related output is displayed. Verbose output is enabled
|
||
|
by default.
|
||
|
|
||
|
(gdb) run
|
||
|
Starting program: /bin/sleep 5
|
||
|
Download failed: No route to host. Continuing without debug info for /lib64/libc.so.6.
|
||
|
|
||
|
If GDB is not built with debuginfod then these commands will just display
|
||
|
|
||
|
Support for debuginfod is not compiled into GDB.
|
||
|
|
||
|
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
|
||
|
--- a/gdb/debuginfod-support.c
|
||
|
+++ b/gdb/debuginfod-support.c
|
||
|
@@ -18,10 +18,26 @@
|
||
|
|
||
|
#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"
|
||
|
+#include "cli/cli-cmds.h"
|
||
|
+#include "cli/cli-style.h"
|
||
|
+
|
||
|
+/* Set/show debuginfod commands. */
|
||
|
+static cmd_list_element *set_debuginfod_prefix_list;
|
||
|
+static cmd_list_element *show_debuginfod_prefix_list;
|
||
|
+
|
||
|
+static const char debuginfod_on[] = "on";
|
||
|
+static const char debuginfod_off[] = "off";
|
||
|
+static const char debuginfod_ask[] = "ask";
|
||
|
+
|
||
|
+static const char *debuginfod_enable = debuginfod_ask;
|
||
|
+static unsigned debuginfod_verbose = 1;
|
||
|
+
|
||
|
+/* This is never actually used. URLs are always pulled from the
|
||
|
+ environment. */
|
||
|
+static char *debuginfod_urls;
|
||
|
|
||
|
#ifndef HAVE_LIBDEBUGINFOD
|
||
|
scoped_fd
|
||
|
@@ -41,6 +57,67 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
|
||
|
{
|
||
|
return scoped_fd (-ENOSYS);
|
||
|
}
|
||
|
+
|
||
|
+#define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
|
||
|
+
|
||
|
+/* Stub set/show commands that indicate debuginfod is not supported. */
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_on_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+ debuginfod_enable = debuginfod_off;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_off_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+ debuginfod_enable = debuginfod_off;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_ask_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+ debuginfod_enable = debuginfod_off;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+show_debuginfod_status_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_urls_command (const char *ignore, int from_tty,
|
||
|
+ struct cmd_list_element *c)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+show_debuginfod_urls_command (struct ui_file *file, int from_tty,
|
||
|
+ struct cmd_list_element *cmd, const char *value)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_verbose_command (const char *args, int from_tty,
|
||
|
+ struct cmd_list_element *c)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+ debuginfod_verbose = 0;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+show_debuginfod_verbose_command (struct ui_file *file, int from_tty,
|
||
|
+ struct cmd_list_element *cmd,
|
||
|
+ const char *value)
|
||
|
+{
|
||
|
+ error (NO_IMPL);
|
||
|
+}
|
||
|
#else
|
||
|
#include <elfutils/debuginfod.h>
|
||
|
|
||
|
@@ -68,6 +145,82 @@ struct debuginfod_client_deleter
|
||
|
using debuginfod_client_up
|
||
|
= std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
|
||
|
|
||
|
+/* Enable debuginfod. */
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_on_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ debuginfod_enable = debuginfod_on;
|
||
|
+}
|
||
|
+
|
||
|
+/* Disable debuginfod. */
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_off_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ debuginfod_enable = debuginfod_off;
|
||
|
+}
|
||
|
+
|
||
|
+/* Before next query, ask user whether to enable debuginfod. */
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_ask_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ debuginfod_enable = debuginfod_ask;
|
||
|
+}
|
||
|
+
|
||
|
+/* Show whether debuginfod is enabled. */
|
||
|
+
|
||
|
+static void
|
||
|
+show_debuginfod_status_command (const char *args, int from_tty)
|
||
|
+{
|
||
|
+ printf_unfiltered (_("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 *ignore, int from_tty,
|
||
|
+ struct cmd_list_element *c)
|
||
|
+{
|
||
|
+ gdb_assert (debuginfod_urls != nullptr);
|
||
|
+ if (setenv ("DEBUGINFOD_URLS", debuginfod_urls, 1) != 0)
|
||
|
+ warning (_("Unable to set debuginfod URLs: %s"), safe_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 (value == nullptr || value[0] == '\0')
|
||
|
+ fprintf_unfiltered (file, _("Debuginfod URLs have not been set.\n"));
|
||
|
+ else
|
||
|
+ fprintf_filtered (file, _("Debuginfod URLs are currently set to:\n%s\n"),
|
||
|
+ value);
|
||
|
+}
|
||
|
+
|
||
|
+/* No-op setter used for compatibility when gdb is built without debuginfod. */
|
||
|
+
|
||
|
+static void
|
||
|
+set_debuginfod_verbose_command (const char *args, int from_tty,
|
||
|
+ struct cmd_list_element *c)
|
||
|
+{
|
||
|
+ return;
|
||
|
+}
|
||
|
+
|
||
|
+/* Show verbosity. */
|
||
|
+
|
||
|
+static void
|
||
|
+show_debuginfod_verbose_command (struct ui_file *file, int from_tty,
|
||
|
+ struct cmd_list_element *cmd, const char *value)
|
||
|
+{
|
||
|
+ fprintf_filtered (file, _("Debuginfod verbose output is set to %s.\n"),
|
||
|
+ value);
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
progressfn (debuginfod_client *c, long cur, long total)
|
||
|
{
|
||
|
@@ -120,6 +273,42 @@ 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 ()
|
||
|
+{
|
||
|
+ const char *urls = getenv (DEBUGINFOD_URLS_ENV_VAR);
|
||
|
+
|
||
|
+ if (urls == nullptr || urls[0] == '\0'
|
||
|
+ || debuginfod_enable == debuginfod_off)
|
||
|
+ return false;
|
||
|
+
|
||
|
+ if (debuginfod_enable == debuginfod_ask)
|
||
|
+ {
|
||
|
+ int resp = nquery (_("\nThis GDB supports auto-downloading debuginfo " \
|
||
|
+ "from the following URLs:\n%s\nEnable debuginfod " \
|
||
|
+ "for this session? "),
|
||
|
+ urls);
|
||
|
+ 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 +317,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 +335,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_verbose > 0 && 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 +354,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 +370,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_verbose > 0 && 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 +381,63 @@ debuginfod_debuginfo_query (const unsigned char *build_id,
|
||
|
return fd;
|
||
|
}
|
||
|
#endif
|
||
|
+
|
||
|
+/* Register debuginfod commands. */
|
||
|
+
|
||
|
+void _initialize_debuginfod ();
|
||
|
+void
|
||
|
+_initialize_debuginfod ()
|
||
|
+{
|
||
|
+ /* set/show debuginfod */
|
||
|
+ add_basic_prefix_cmd ("debuginfod", class_run,
|
||
|
+ _("Set debuginfod options"),
|
||
|
+ &set_debuginfod_prefix_list, 0, &setlist);
|
||
|
+
|
||
|
+ add_show_prefix_cmd ("debuginfod", class_run,
|
||
|
+ _("Show debuginfod options"),
|
||
|
+ &show_debuginfod_prefix_list, 0, &showlist);
|
||
|
+
|
||
|
+ /* set debuginfod on */
|
||
|
+ add_cmd ("on", class_run, set_debuginfod_on_command,
|
||
|
+ _("Enable debuginfod."), &set_debuginfod_prefix_list);
|
||
|
+
|
||
|
+ /* set debuginfod off */
|
||
|
+ add_cmd ("off", class_run, set_debuginfod_off_command,
|
||
|
+ _("Disable debuginfod."), &set_debuginfod_prefix_list);
|
||
|
+
|
||
|
+ /* set debuginfod ask */
|
||
|
+ add_cmd ("ask", class_run, set_debuginfod_ask_command, _("\
|
||
|
+Ask the user whether to enable debuginfod before performing the next query."),
|
||
|
+ &set_debuginfod_prefix_list);
|
||
|
+
|
||
|
+ /* show debuginfod status */
|
||
|
+ add_cmd ("status", class_run, show_debuginfod_status_command,
|
||
|
+ _("Show whether debuginfod is set to \"on\", \"off\" or \"ask\"."),
|
||
|
+ &show_debuginfod_prefix_list);
|
||
|
+
|
||
|
+ /* set/show debuginfod urls */
|
||
|
+ add_setshow_string_noescape_cmd ("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 the DEBUGINFOD_URLS environment variable."),
|
||
|
+ set_debuginfod_urls_command,
|
||
|
+ show_debuginfod_urls_command,
|
||
|
+ &set_debuginfod_prefix_list,
|
||
|
+ &show_debuginfod_prefix_list);
|
||
|
+ if (getenv ("DEBUGINFOD_URLS") != nullptr)
|
||
|
+ debuginfod_urls = xstrdup (getenv ("DEBUGINFOD_URLS"));
|
||
|
+
|
||
|
+ /* set/show debuginfod verbose */
|
||
|
+ add_setshow_zuinteger_cmd ("verbose", class_support,
|
||
|
+ &debuginfod_verbose, _("\
|
||
|
+Set verbosity of debuginfod output."), _("\
|
||
|
+Show debuginfod debugging."), _("\
|
||
|
+When set to a non-zero value, display verbose output for each debuginfod \
|
||
|
+query.\nTo disable, set to zero. Verbose output is displayed by default."),
|
||
|
+ set_debuginfod_verbose_command,
|
||
|
+ show_debuginfod_verbose_command,
|
||
|
+ &set_debuginfod_prefix_list,
|
||
|
+ &show_debuginfod_prefix_list);
|
||
|
+}
|
||
|
diff --git a/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp b/gdb/testsuite/gdb.debuginfod/fetch_src_and_symbols.exp
|
||
|
--- 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 \
|