20#include "diagnostics.h"
22#include "gdbsupport/scoped_fd.h"
24#include "gdbsupport/gdb_optional.h"
47#if defined(HAVE_LIBDEBUGINFOD)
55#ifndef HAVE_LIBDEBUGINFOD
60 gdb::unique_xmalloc_ptr<char> *destname)
62 return scoped_fd (-ENOSYS);
69 gdb::unique_xmalloc_ptr<char> *destname)
71 return scoped_fd (-ENOSYS);
78 gdb::unique_xmalloc_ptr<char> *destname)
80 return scoped_fd (-ENOSYS);
83#define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
86#include <elfutils/debuginfod.h>
90 user_data (
const char *desc,
const char *fname)
91 : desc (desc), fname (fname)
94 const char *
const desc;
95 const char *
const fname;
101struct debuginfod_client_deleter
103 void operator() (debuginfod_client *c)
109using debuginfod_client_up
110 = std::unique_ptr<debuginfod_client, debuginfod_client_deleter>;
119get_size_and_unit (
double &
size)
140progressfn (debuginfod_client *c,
long cur,
long total)
142 user_data *
data =
static_cast<user_data *
> (debuginfod_get_user_data (c));
143 gdb_assert (data !=
nullptr);
151 gdb_printf (
"Cancelling download of %s %s...\n",
152 data->desc, styled_fname.c_str ());
163 double howmuch = (double) cur / (
double) total;
165 if (howmuch >= 0.0 && howmuch <= 1.0)
167 double d_total = (double) total;
168 const char *unit = get_size_and_unit (d_total);
169 std::string msg = string_printf (
"Downloading %0.2f %s %s %s",
170 d_total, unit,
data->desc,
171 styled_fname.c_str ());
172 data->progress.update_progress (msg, unit, howmuch, d_total);
177 std::string msg = string_printf (
"Downloading %s %s",
178 data->desc, styled_fname.c_str ());
179 data->progress.update_progress (msg);
183static debuginfod_client *
184get_debuginfod_client ()
186 static debuginfod_client_up global_client;
188 if (global_client ==
nullptr)
190 global_client.reset (debuginfod_begin ());
192 if (global_client !=
nullptr)
193 debuginfod_set_progressfn (global_client.get (), progressfn);
196 return global_client.get ();
203debuginfod_is_enabled ()
205 const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
214 gdb_printf (_(
"\nThis GDB supports auto-downloading debuginfo " \
215 "from the following URLs:\n"));
217 gdb::string_view url_view (urls);
220 size_t off = url_view.find_first_not_of (
' ');
221 if (off == gdb::string_view::npos)
223 url_view = url_view.substr (off);
229 DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
230 off = url_view.find_first_of (
' ');
235 gdb::to_string (url_view.substr (0,
237 if (off == gdb::string_view::npos)
239 url_view = url_view.substr (off);
242 int resp =
nquery (_(
"Enable debuginfod for this session? "));
245 gdb_printf (_(
"Debuginfod has been disabled.\nTo make this " \
246 "setting permanent, add \'set debuginfod " \
247 "enabled off\' to .gdbinit.\n"));
252 gdb_printf (_(
"Debuginfod has been enabled.\nTo make this " \
253 "setting permanent, add \'set debuginfod enabled " \
254 "on\' to .gdbinit.\n"));
264print_outcome (user_data &data,
int fd)
269 if (fd < 0 && fd != -ENOENT)
270 gdb_printf (_(
"Download failed: %s. Continuing without %s %ps.\n"),
282 gdb::unique_xmalloc_ptr<char> *destname)
284 if (!debuginfod_is_enabled ())
285 return scoped_fd (-ENOSYS);
287 debuginfod_client *c = get_debuginfod_client ();
290 return scoped_fd (-ENOMEM);
292 char *dname =
nullptr;
293 user_data
data (
"source file", srcpath);
295 debuginfod_set_user_data (c, &data);
296 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
299 term_state.emplace ();
303 scoped_fd fd (debuginfod_find_source (c,
308 debuginfod_set_user_data (c,
nullptr);
309 print_outcome (data, fd.get ());
312 destname->reset (dname);
322 const char *filename,
323 gdb::unique_xmalloc_ptr<char> *destname)
325 if (!debuginfod_is_enabled ())
326 return scoped_fd (-ENOSYS);
328 debuginfod_client *c = get_debuginfod_client ();
331 return scoped_fd (-ENOMEM);
333 char *dname =
nullptr;
334 user_data
data (
"separate debug info for", filename);
336 debuginfod_set_user_data (c, &data);
337 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
340 term_state.emplace ();
344 scoped_fd fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
346 debuginfod_set_user_data (c,
nullptr);
347 print_outcome (data, fd.get ());
350 destname->reset (dname);
360 const char *filename,
361 gdb::unique_xmalloc_ptr<char> *destname)
363 if (!debuginfod_is_enabled ())
364 return scoped_fd (-ENOSYS);
366 debuginfod_client *c = get_debuginfod_client ();
369 return scoped_fd (-ENOMEM);
371 char *dname =
nullptr;
372 user_data
data (
"executable for", filename);
374 debuginfod_set_user_data (c, &data);
375 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
378 term_state.emplace ();
382 scoped_fd fd (debuginfod_find_executable (c, build_id, build_id_len, &dname));
383 debuginfod_set_user_data (c,
nullptr);
384 print_outcome (data, fd.get ());
387 destname->reset (dname);
398#if defined(HAVE_LIBDEBUGINFOD)
422 _(
"Debuginfod functionality is currently set to "
431#if defined(HAVE_LIBDEBUGINFOD)
432 if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0)
433 warning (_(
"Unable to set debuginfod URLs: %s"), safe_strerror (errno));
441static const std::string&
444 static std::string urls;
445#if defined(HAVE_LIBDEBUGINFOD)
446 const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);
448 if (envvar !=
nullptr)
463 if (
value[0] ==
'\0')
464 gdb_printf (file, _(
"Debuginfod URLs have not been set.\n"));
466 gdb_printf (file, _(
"Debuginfod URLs are currently set to:\n%s\n"),
476 gdb_printf (file, _(
"Debuginfod verbose output is set to %s.\n"),
488 _(
"Set debuginfod options."),
489 _(
"Show debuginfod options."),
495 _(
"Set whether to use debuginfod."),
496 _(
"Show whether to use debuginfod."),
498When on, enable the use of debuginfod to download missing debug info and\n\
508Set the list of debuginfod server URLs."), _(
"\
509Show the list of debuginfod server URLs."), _(
"\
510Manage the space-separated list of debuginfod server URLs that GDB will query \
511when missing debuginfo, executables or source files.\nThe default value is \
512copied from the DEBUGINFOD_URLS environment variable."),
522Set verbosity of debuginfod output."), _(
"\
523Show debuginfod debugging."), _(
"\
524When set to a non-zero value, display verbose output for each debuginfod \
525query.\nTo disable, set to zero. Verbose output is displayed by default."),
ui_file_style style() const
struct cmd_list_element * showlist
struct cmd_list_element * setlist
set_show_commands add_setshow_enum_cmd(const char *name, enum command_class theclass, const char *const *enumlist, const char **var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
set_show_commands add_setshow_prefix_cmd(const char *name, command_class theclass, const char *set_doc, const char *show_doc, cmd_list_element **set_subcommands_list, cmd_list_element **show_subcommands_list, cmd_list_element **set_list, cmd_list_element **show_list)
set_show_commands add_setshow_string_noescape_cmd(const char *name, enum command_class theclass, std::string *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
set_show_commands add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_func_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
cli_style_option file_name_style
static const char debuginfod_on[]
static cmd_list_element * set_debuginfod_prefix_list
static void show_debuginfod_urls(ui_file *file, int from_tty, cmd_list_element *cmd, const char *value)
static void set_debuginfod_enabled(const char *value)
static unsigned int debuginfod_verbose
static const char * debuginfod_enabled
scoped_fd debuginfod_debuginfo_query(const unsigned char *build_id, int build_id_len, const char *filename, gdb::unique_xmalloc_ptr< char > *destname)
void _initialize_debuginfod()
scoped_fd debuginfod_exec_query(const unsigned char *build_id, int build_id_len, const char *filename, gdb::unique_xmalloc_ptr< char > *destname)
static const char debuginfod_ask[]
scoped_fd debuginfod_source_query(const unsigned char *build_id, int build_id_len, const char *srcpath, gdb::unique_xmalloc_ptr< char > *destname)
static void show_debuginfod_verbose_command(ui_file *file, int from_tty, cmd_list_element *cmd, const char *value)
static const char * get_debuginfod_enabled()
static void set_debuginfod_urls(const std::string &urls)
static const char debuginfod_off[]
static cmd_list_element * show_debuginfod_prefix_list
static void show_debuginfod_enabled(ui_file *file, int from_tty, cmd_list_element *cmd, const char *value)
static const char * debuginfod_enabled_enum[]
static const std::string & get_debuginfod_urls()
int check_quit_flag(void)
bool target_supports_terminal_ours(void)
static styled_string_s * styled_string(const ui_file_style &style, const char *str, styled_string_s &&tmp={})
int nquery(const char *ctlstr,...)
void fprintf_styled(struct ui_file *stream, const ui_file_style &style, const char *format,...)
void gdb_printf(struct ui_file *stream, const char *format,...)