#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;
#ifndef HAVE_LIBDEBUGINFOD
scoped_fd
{
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 std::string& urls)
+{
+ error (NO_IMPL);
+}
+
+static const std::string&
+get_debuginfod_urls_command ()
+{
+ static std::string empty;
+ return empty;
+}
+
+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>
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 std::string& urls)
+{
+ if (setenv ("DEBUGINFOD_URLS", urls.c_str (), 1) != 0)
+ warning (_("Unable to set debuginfod URLs: %s"), safe_strerror (errno));
+}
+
+/* Get current debuginfod URLs. */
+
+static const std::string&
+get_debuginfod_urls_command ()
+{
+ static std::string urls;
+ const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);
+
+ if (envvar != nullptr)
+ urls = envvar;
+ else
+ urls.clear ();
+
+ return urls;
+}
+
+/* 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)
{
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
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 ();
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));
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 ();
&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));
return fd;
}
#endif
+
+/* Register debuginfod commands. */
+
+void _initialize_debuginfod ();
+void
+_initialize_debuginfod ()
+{
+ /* set/show debuginfod */
+ add_setshow_prefix_cmd ("debuginfod", class_run,
+ _("Set debuginfod options"),
+ _("Show debuginfod options"),
+ &set_debuginfod_prefix_list,
+ &show_debuginfod_prefix_list,
+ &setlist, &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, _("\
+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,
+ get_debuginfod_urls_command,
+ show_debuginfod_urls_command,
+ &set_debuginfod_prefix_list,
+ &show_debuginfod_prefix_list);
+
+ /* 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);
+}