20#include "diagnostics.h"
22#include "gdbsupport/scoped_fd.h"
24#include "gdbsupport/gdb_optional.h"
51#if defined(HAVE_LIBDEBUGINFOD)
59#if defined(HAVE_LIBDEBUGINFOD_FIND_SECTION)
67#ifndef HAVE_LIBDEBUGINFOD
72 gdb::unique_xmalloc_ptr<char> *destname)
74 return scoped_fd (-ENOSYS);
81 gdb::unique_xmalloc_ptr<char> *destname)
83 return scoped_fd (-ENOSYS);
90 gdb::unique_xmalloc_ptr<char> *destname)
92 return scoped_fd (-ENOSYS);
99 const char *section_name,
100 gdb::unique_xmalloc_ptr<char> *destname)
102 return scoped_fd (-ENOSYS);
104#define NO_IMPL _("Support for debuginfod is not compiled into GDB.")
107#include <elfutils/debuginfod.h>
111 user_data (
const char *desc,
const char *fname)
112 : desc (desc), fname (fname)
115 const char *
const desc;
116 const char *
const fname;
126get_size_and_unit (
double &
size)
147progressfn (debuginfod_client *c,
long cur,
long total)
149 user_data *
data =
static_cast<user_data *
> (debuginfod_get_user_data (c));
150 gdb_assert (data !=
nullptr);
158 gdb_printf (
"Cancelling download of %s %s...\n",
159 data->desc, styled_fname.c_str ());
170 double howmuch = (double) cur / (
double) total;
172 if (howmuch >= 0.0 && howmuch <= 1.0)
174 double d_total = (double) total;
175 const char *unit = get_size_and_unit (d_total);
176 std::string msg = string_printf (
"Downloading %0.2f %s %s %s",
177 d_total, unit,
data->desc,
178 styled_fname.c_str ());
179 data->progress.update_progress (msg, unit, howmuch, d_total);
184 std::string msg = string_printf (
"Downloading %s %s",
185 data->desc, styled_fname.c_str ());
186 data->progress.update_progress (msg);
193cleanup_debuginfod_client (
void *arg)
195 debuginfod_client *client =
static_cast<debuginfod_client *
> (arg);
196 debuginfod_end (client);
202static debuginfod_client *
203get_debuginfod_client ()
205 static debuginfod_client *global_client =
nullptr;
207 if (global_client ==
nullptr)
209 global_client = debuginfod_begin ();
211 if (global_client !=
nullptr)
223 make_final_cleanup (cleanup_debuginfod_client, global_client);
224 debuginfod_set_progressfn (global_client, progressfn);
228 return global_client;
235debuginfod_is_enabled ()
237 const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
246 gdb_printf (_(
"\nThis GDB supports auto-downloading debuginfo " \
247 "from the following URLs:\n"));
249 gdb::string_view url_view (urls);
252 size_t off = url_view.find_first_not_of (
' ');
253 if (off == gdb::string_view::npos)
255 url_view = url_view.substr (off);
261 DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
262 off = url_view.find_first_of (
' ');
267 gdb::to_string (url_view.substr (0,
269 if (off == gdb::string_view::npos)
271 url_view = url_view.substr (off);
274 int resp =
nquery (_(
"Enable debuginfod for this session? "));
277 gdb_printf (_(
"Debuginfod has been disabled.\nTo make this " \
278 "setting permanent, add \'set debuginfod " \
279 "enabled off\' to .gdbinit.\n"));
284 gdb_printf (_(
"Debuginfod has been enabled.\nTo make this " \
285 "setting permanent, add \'set debuginfod enabled " \
286 "on\' to .gdbinit.\n"));
296print_outcome (
int fd,
const char *desc,
const char *fname)
298 if (fd < 0 && fd != -ENOENT)
299 gdb_printf (_(
"Download failed: %s. Continuing without %s %ps.\n"),
311 gdb::unique_xmalloc_ptr<char> *destname)
313 if (!debuginfod_is_enabled ())
314 return scoped_fd (-ENOSYS);
316 debuginfod_client *c = get_debuginfod_client ();
319 return scoped_fd (-ENOMEM);
321 char *dname =
nullptr;
323 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
326 user_data
data (
"source file", srcpath);
328 debuginfod_set_user_data (c, &data);
331 term_state.emplace ();
335 fd = scoped_fd (debuginfod_find_source (c,
340 debuginfod_set_user_data (c,
nullptr);
343 print_outcome (fd.get (),
"source file", srcpath);
346 destname->reset (dname);
356 const char *filename,
357 gdb::unique_xmalloc_ptr<char> *destname)
359 if (!debuginfod_is_enabled ())
360 return scoped_fd (-ENOSYS);
362 debuginfod_client *c = get_debuginfod_client ();
365 return scoped_fd (-ENOMEM);
367 char *dname =
nullptr;
369 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
372 user_data
data (
"separate debug info for", filename);
374 debuginfod_set_user_data (c, &data);
377 term_state.emplace ();
381 fd = scoped_fd (debuginfod_find_debuginfo (c, build_id, build_id_len,
383 debuginfod_set_user_data (c,
nullptr);
386 print_outcome (fd.get (),
"separate debug info for", filename);
389 destname->reset (dname);
399 const char *filename,
400 gdb::unique_xmalloc_ptr<char> *destname)
402 if (!debuginfod_is_enabled ())
403 return scoped_fd (-ENOSYS);
405 debuginfod_client *c = get_debuginfod_client ();
408 return scoped_fd (-ENOMEM);
410 char *dname =
nullptr;
412 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
415 user_data
data (
"executable for", filename);
417 debuginfod_set_user_data (c, &data);
420 term_state.emplace ();
424 fd = scoped_fd (debuginfod_find_executable (c, build_id, build_id_len,
426 debuginfod_set_user_data (c,
nullptr);
429 print_outcome (fd.get (),
"executable for", filename);
432 destname->reset (dname);
442 const char *filename,
443 const char *section_name,
444 gdb::unique_xmalloc_ptr<char> *destname)
446#if !defined (HAVE_LIBDEBUGINFOD_FIND_SECTION)
447 return scoped_fd (-ENOSYS);
451 return scoped_fd (-ENOSYS);
453 debuginfod_client *c = get_debuginfod_client ();
456 return scoped_fd (-ENOMEM);
458 char *dname =
nullptr;
459 std::string desc = std::string (
"section ") + section_name +
" for";
461 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
464 user_data
data (desc.c_str (), filename);
465 debuginfod_set_user_data (c, &data);
468 term_state.emplace ();
472 fd = scoped_fd (debuginfod_find_section (c, build_id, build_id_len,
473 section_name, &dname));
474 debuginfod_set_user_data (c,
nullptr);
477 print_outcome (fd.get (), desc.c_str (), filename);
478 gdb_assert (destname !=
nullptr);
481 destname->reset (dname);
494#if defined(HAVE_LIBDEBUGINFOD)
518 _(
"Debuginfod functionality is currently set to "
527#if defined(HAVE_LIBDEBUGINFOD)
528 if (setenv (DEBUGINFOD_URLS_ENV_VAR, urls.c_str (), 1) != 0)
529 warning (_(
"Unable to set debuginfod URLs: %s"), safe_strerror (errno));
537static const std::string&
540 static std::string urls;
541#if defined(HAVE_LIBDEBUGINFOD)
542 const char *envvar = getenv (DEBUGINFOD_URLS_ENV_VAR);
544 if (envvar !=
nullptr)
559 if (
value[0] ==
'\0')
560 gdb_printf (file, _(
"Debuginfod URLs have not been set.\n"));
562 gdb_printf (file, _(
"Debuginfod URLs are currently set to:\n%s\n"),
572 gdb_printf (file, _(
"Debuginfod verbose output is set to %s.\n"),
581#if !defined(HAVE_LIBDEBUGINFOD_FIND_SECTION)
583 error (_(
"Support for section downloading is not compiled into GDB. " \
584"Defaulting to \"off\"."));
606 _(
"Set debuginfod options."),
607 _(
"Show debuginfod options."),
613 _(
"Set whether to use debuginfod."),
614 _(
"Show whether to use debuginfod."),
616When set to \"on\", enable the use of debuginfod to download missing\n\
617debug info and source files. GDB may also download components of debug\n\
618info instead of entire files. \"off\" disables the use of debuginfod.\n\
619When set to \"ask\", prompt whether to enable or disable debuginfod." ),
628Set the list of debuginfod server URLs."), _(
"\
629Show the list of debuginfod server URLs."), _(
"\
630Manage the space-separated list of debuginfod server URLs that GDB will query \
631when missing debuginfo, executables or source files.\nThe default value is \
632copied from the DEBUGINFOD_URLS environment variable."),
642Set verbosity of debuginfod output."), _(
"\
643Show debuginfod debugging."), _(
"\
644When set to a non-zero value, display verbose output for each debuginfod \
645query.\nTo disable, set to zero. Verbose output is displayed by default."),
653 _(
"Set debuginfod specific variables."),
654 _(
"Show debuginfod specific variables."),
661Set whether debuginfod may download individual ELF/DWARF sections."), _(
"\
662Show whether debuginfod may download individual ELF/DWARF sections."), _(
"\
663When enabled, debuginfod may attempt to download individual ELF/DWARF \
664sections from debug info files.\nIf disabled, only whole debug info files \
ui_file_style style() const
struct cmd_list_element * showlist
struct cmd_list_element * setlist
struct cmd_list_element * maintenance_show_cmdlist
struct cmd_list_element * maintenance_set_cmdlist
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_boolean_cmd(const char *name, enum command_class theclass, bool *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_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()
static bool maint_get_debuginfod_download_sections()
scoped_fd debuginfod_exec_query(const unsigned char *build_id, int build_id_len, const char *filename, gdb::unique_xmalloc_ptr< char > *destname)
scoped_fd debuginfod_section_query(const unsigned char *build_id, int build_id_len, const char *filename, const char *section_name, 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 bool debuginfod_download_sections
static cmd_list_element * show_debuginfod_prefix_list
static void maint_set_debuginfod_download_sections(bool value)
static cmd_list_element * maint_show_debuginfod_cmdlist
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()
static cmd_list_element * maint_set_debuginfod_cmdlist
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,...)