* [PATCH v5 1/4] [gdb] Simplify debuginfod_is_enabled
2026-03-14 17:37 [PATCH v5 0/4] [gdb/tui] Fix crash with debuginfod query Tom de Vries
@ 2026-03-14 17:37 ` Tom de Vries
2026-04-14 12:40 ` Tom de Vries
2026-03-14 17:37 ` [PATCH v5 2/4] [gdb] Add debuginfod_enabled_ask_p Tom de Vries
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Tom de Vries @ 2026-03-14 17:37 UTC (permalink / raw)
To: gdb-patches
Simplify debuginfod_is_enabled by adding an early-exit for the
debuginfod_enabled == debuginfod_on case.
---
gdb/debuginfod-support.c | 81 ++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 40 deletions(-)
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
index 3da3edc432d..ca4a5b1a7af 100644
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -232,57 +232,58 @@ debuginfod_is_enabled ()
{
const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
- if (debuginfod_enabled == debuginfod_off
- || urls == nullptr
+ if (urls == nullptr
|| *urls == '\0')
return false;
- if (debuginfod_enabled == debuginfod_ask)
- {
- gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
- "from the following URLs:\n"));
+ if (debuginfod_enabled != debuginfod_ask)
+ return debuginfod_enabled == debuginfod_on;
- std::string_view url_view (urls);
- while (true)
- {
- size_t off = url_view.find_first_not_of (' ');
- if (off == std::string_view::npos)
- break;
- url_view = url_view.substr (off);
- /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
- hppa seem convinced url_view might be of SIZE_MAX length.
- And so complains because the length of an array can only
- be PTRDIFF_MAX. */
- DIAGNOSTIC_PUSH
- DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
- off = url_view.find_first_of (' ');
- DIAGNOSTIC_POP
- gdb_printf
- (_(" <%ps>\n"),
- styled_string (file_name_style.style (),
- std::string (url_view.substr (0, off)).c_str ()));
- if (off == std::string_view::npos)
- break;
- url_view = url_view.substr (off);
- }
+ gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
+ "from the following URLs:\n"));
- int resp = nquery (_("Enable debuginfod for this session? "));
- if (!resp)
- {
- gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
- "setting permanent, add \'set debuginfod " \
- "enabled off\' to .gdbinit.\n"));
- debuginfod_enabled = debuginfod_off;
- return false;
- }
+ std::string_view url_view (urls);
+ while (true)
+ {
+ size_t off = url_view.find_first_not_of (' ');
+ if (off == std::string_view::npos)
+ break;
+ url_view = url_view.substr (off);
+ /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
+ hppa seem convinced url_view might be of SIZE_MAX length.
+ And so complains because the length of an array can only
+ be PTRDIFF_MAX. */
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
+ off = url_view.find_first_of (' ');
+ DIAGNOSTIC_POP
+ gdb_printf
+ (_(" <%ps>\n"),
+ styled_string (file_name_style.style (),
+ std::string (url_view.substr (0, off)).c_str ()));
+ if (off == std::string_view::npos)
+ break;
+ url_view = url_view.substr (off);
+ }
- gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
+ int resp = nquery (_("Enable debuginfod for this session? "));
+ if (!resp)
+ {
+ gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
+ "setting permanent, add \'set debuginfod " \
+ "enabled off\' to .gdbinit.\n"));
+ debuginfod_enabled = debuginfod_off;
+ }
+ else
+ {
+ gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
"setting permanent, add \'set debuginfod enabled " \
"on\' to .gdbinit.\n"));
debuginfod_enabled = debuginfod_on;
}
- return true;
+ gdb_assert (debuginfod_enabled != debuginfod_ask);
+ return debuginfod_enabled == debuginfod_on;
}
/* Print the result of the most recent attempted download. */
--
2.51.0
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH v5 1/4] [gdb] Simplify debuginfod_is_enabled
2026-03-14 17:37 ` [PATCH v5 1/4] [gdb] Simplify debuginfod_is_enabled Tom de Vries
@ 2026-04-14 12:40 ` Tom de Vries
0 siblings, 0 replies; 6+ messages in thread
From: Tom de Vries @ 2026-04-14 12:40 UTC (permalink / raw)
To: gdb-patches
On 3/14/26 6:37 PM, Tom de Vries wrote:
> Simplify debuginfod_is_enabled by adding an early-exit for the
> debuginfod_enabled == debuginfod_on case.
I've pushed this.
I noticed I got the indentation of this bit wrong (I used emacs auto-ident):
...
DIAGNOSTIC_PUSH
DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
off = url_view.find_first_of (' ');
DIAGNOSTIC_POP
...
so I've fixed that before pushing.
Thanks,
- Tom
> ---
> gdb/debuginfod-support.c | 81 ++++++++++++++++++++--------------------
> 1 file changed, 41 insertions(+), 40 deletions(-)
>
> diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
> index 3da3edc432d..ca4a5b1a7af 100644
> --- a/gdb/debuginfod-support.c
> +++ b/gdb/debuginfod-support.c
> @@ -232,57 +232,58 @@ debuginfod_is_enabled ()
> {
> const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
>
> - if (debuginfod_enabled == debuginfod_off
> - || urls == nullptr
> + if (urls == nullptr
> || *urls == '\0')
> return false;
>
> - if (debuginfod_enabled == debuginfod_ask)
> - {
> - gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
> - "from the following URLs:\n"));
> + if (debuginfod_enabled != debuginfod_ask)
> + return debuginfod_enabled == debuginfod_on;
>
> - std::string_view url_view (urls);
> - while (true)
> - {
> - size_t off = url_view.find_first_not_of (' ');
> - if (off == std::string_view::npos)
> - break;
> - url_view = url_view.substr (off);
> - /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
> - hppa seem convinced url_view might be of SIZE_MAX length.
> - And so complains because the length of an array can only
> - be PTRDIFF_MAX. */
> - DIAGNOSTIC_PUSH
> - DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
> - off = url_view.find_first_of (' ');
> - DIAGNOSTIC_POP
> - gdb_printf
> - (_(" <%ps>\n"),
> - styled_string (file_name_style.style (),
> - std::string (url_view.substr (0, off)).c_str ()));
> - if (off == std::string_view::npos)
> - break;
> - url_view = url_view.substr (off);
> - }
> + gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
> + "from the following URLs:\n"));
>
> - int resp = nquery (_("Enable debuginfod for this session? "));
> - if (!resp)
> - {
> - gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
> - "setting permanent, add \'set debuginfod " \
> - "enabled off\' to .gdbinit.\n"));
> - debuginfod_enabled = debuginfod_off;
> - return false;
> - }
> + std::string_view url_view (urls);
> + while (true)
> + {
> + size_t off = url_view.find_first_not_of (' ');
> + if (off == std::string_view::npos)
> + break;
> + url_view = url_view.substr (off);
> + /* g++ 11.2.1 on s390x, g++ 11.3.1 on ppc64le and g++ 11 on
> + hppa seem convinced url_view might be of SIZE_MAX length.
> + And so complains because the length of an array can only
> + be PTRDIFF_MAX. */
> + DIAGNOSTIC_PUSH
> + DIAGNOSTIC_IGNORE_STRINGOP_OVERREAD
> + off = url_view.find_first_of (' ');
> + DIAGNOSTIC_POP
> + gdb_printf
> + (_(" <%ps>\n"),
> + styled_string (file_name_style.style (),
> + std::string (url_view.substr (0, off)).c_str ()));
> + if (off == std::string_view::npos)
> + break;
> + url_view = url_view.substr (off);
> + }
>
> - gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
> + int resp = nquery (_("Enable debuginfod for this session? "));
> + if (!resp)
> + {
> + gdb_printf (_("Debuginfod has been disabled.\nTo make this " \
> + "setting permanent, add \'set debuginfod " \
> + "enabled off\' to .gdbinit.\n"));
> + debuginfod_enabled = debuginfod_off;
> + }
> + else
> + {
> + gdb_printf (_("Debuginfod has been enabled.\nTo make this " \
> "setting permanent, add \'set debuginfod enabled " \
> "on\' to .gdbinit.\n"));
> debuginfod_enabled = debuginfod_on;
> }
>
> - return true;
> + gdb_assert (debuginfod_enabled != debuginfod_ask);
> + return debuginfod_enabled == debuginfod_on;
> }
>
> /* Print the result of the most recent attempted download. */
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v5 2/4] [gdb] Add debuginfod_enabled_ask_p
2026-03-14 17:37 [PATCH v5 0/4] [gdb/tui] Fix crash with debuginfod query Tom de Vries
2026-03-14 17:37 ` [PATCH v5 1/4] [gdb] Simplify debuginfod_is_enabled Tom de Vries
@ 2026-03-14 17:37 ` Tom de Vries
2026-03-14 17:37 ` [PATCH v5 3/4] [gdb] Add defaulted_query_auto_answers_p Tom de Vries
2026-03-14 17:37 ` [PATCH v5 4/4] [gdb/tui] Don't enter TUI if debuginfod enabled == ask Tom de Vries
3 siblings, 0 replies; 6+ messages in thread
From: Tom de Vries @ 2026-03-14 17:37 UTC (permalink / raw)
To: gdb-patches
Factor out debuginfod_is_enabled_1 out of debuginfod_is_enabled, and use it to
implement debuginfod_enabled_ask_p.
---
gdb/debuginfod-support.c | 40 +++++++++++++++++++++++++++++++---------
gdb/debuginfod-support.h | 5 +++++
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/gdb/debuginfod-support.c b/gdb/debuginfod-support.c
index ca4a5b1a7af..9751cd64319 100644
--- a/gdb/debuginfod-support.c
+++ b/gdb/debuginfod-support.c
@@ -224,20 +224,20 @@ get_debuginfod_client ()
return global_client;
}
-/* Check if debuginfod is enabled. If configured to do so, ask the user
- whether to enable debuginfod. */
+/* Check if debuginfod is enabled. If configured to do so and ALLOW_ASK, ask
+ the user whether to enable debuginfod. */
-static bool
-debuginfod_is_enabled ()
+static const char *
+debuginfod_is_enabled_1 (bool allow_ask)
{
const char *urls = skip_spaces (getenv (DEBUGINFOD_URLS_ENV_VAR));
if (urls == nullptr
|| *urls == '\0')
- return false;
+ return debuginfod_off;
- if (debuginfod_enabled != debuginfod_ask)
- return debuginfod_enabled == debuginfod_on;
+ if (debuginfod_enabled != debuginfod_ask || !allow_ask)
+ return debuginfod_enabled;
gdb_printf (_("\nThis GDB supports auto-downloading debuginfo " \
"from the following URLs:\n"));
@@ -282,8 +282,18 @@ debuginfod_is_enabled ()
debuginfod_enabled = debuginfod_on;
}
- gdb_assert (debuginfod_enabled != debuginfod_ask);
- return debuginfod_enabled == debuginfod_on;
+ return debuginfod_enabled;
+}
+
+/* Check if debuginfod is enabled. If configured to do so, ask the user
+ whether to enable debuginfod. */
+
+static bool
+debuginfod_is_enabled ()
+{
+ const char *res = debuginfod_is_enabled_1 (true);
+ gdb_assert (res != debuginfod_ask);
+ return res == debuginfod_on;
}
/* Print the result of the most recent attempted download. */
@@ -486,6 +496,18 @@ debuginfod_section_query (const unsigned char *build_id,
#endif
+/* See debuginfod-support.h. */
+
+bool
+debuginfod_enabled_ask_p ()
+{
+#if defined(HAVE_LIBDEBUGINFOD)
+ return debuginfod_is_enabled_1 (false) == debuginfod_ask;
+#else
+ return false;
+#endif
+}
+
/* Set callback for "set debuginfod enabled". */
static void
diff --git a/gdb/debuginfod-support.h b/gdb/debuginfod-support.h
index cc5bf331812..7e7b5965c3b 100644
--- a/gdb/debuginfod-support.h
+++ b/gdb/debuginfod-support.h
@@ -105,4 +105,9 @@ extern scoped_fd debuginfod_section_query (const unsigned char *build_id,
const char *section_name,
gdb::unique_xmalloc_ptr<char>
*destname);
+
+/* Check if debuginfod enabled is set to ask. */
+
+extern bool debuginfod_enabled_ask_p ();
+
#endif /* GDB_DEBUGINFOD_SUPPORT_H */
--
2.51.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v5 3/4] [gdb] Add defaulted_query_auto_answers_p
2026-03-14 17:37 [PATCH v5 0/4] [gdb/tui] Fix crash with debuginfod query Tom de Vries
2026-03-14 17:37 ` [PATCH v5 1/4] [gdb] Simplify debuginfod_is_enabled Tom de Vries
2026-03-14 17:37 ` [PATCH v5 2/4] [gdb] Add debuginfod_enabled_ask_p Tom de Vries
@ 2026-03-14 17:37 ` Tom de Vries
2026-03-14 17:37 ` [PATCH v5 4/4] [gdb/tui] Don't enter TUI if debuginfod enabled == ask Tom de Vries
3 siblings, 0 replies; 6+ messages in thread
From: Tom de Vries @ 2026-03-14 17:37 UTC (permalink / raw)
To: gdb-patches
Factor out "static bool defaulted_query_auto_answers_p (bool)" out of
defaulted_query, and use it to implement
"extern tribool defaulted_query_auto_answers_p (void)".
---
gdb/utils.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-----
gdb/utils.h | 4 ++++
2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/gdb/utils.c b/gdb/utils.c
index ef8ef87bc5b..0de356eac80 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -742,6 +742,54 @@ class scoped_input_handler
};
\f
+/* Return true if defaulted queries should be answered:
+ - if VERBOSELY, automatically and verbosely
+ - otherwise, automatically and quietly. */
+
+static bool
+defaulted_query_auto_answers_p (bool verbosely)
+{
+ if (verbosely)
+ {
+ /* Automatically answer verbosely if input isn't coming from the user
+ directly. */
+ return (current_ui->instream != current_ui->stdin_stream
+ || !current_ui->input_interactive_p ()
+ /* Restrict queries to the main UI. */
+ || current_ui != main_ui);
+ }
+ else
+ {
+ /* Automatically answer quietly if:
+ - the user did not want prompts, or
+ - the command was issued with the server prefix. */
+ return !confirm || server_command;
+ }
+}
+
+/* See utils.h. */
+
+tribool
+defaulted_query_auto_answers_p ()
+{
+ if (defaulted_query_auto_answers_p (false)
+ || defaulted_query_auto_answers_p (true))
+ return TRIBOOL_TRUE;
+
+ if (deprecated_query_hook)
+ {
+ /* The only user of deprecated_query_hook in core gdb seems to be
+ mi_interp_query_hook, for which we could return TRIBOOL_TRUE here.
+ If that turns out to be required, we could accomplish this by
+ changing the hook interface to say:
+ int (*deprecated_query_hook) (const char *, va_list,
+ bool auto_answers_p = false)
+ and calling it here with auto_answers_p == true. */
+ return TRIBOOL_UNKNOWN;
+ }
+
+ return TRIBOOL_FALSE;
+}
/* This function supports the query, nquery, and yquery functions.
Ask user a y-or-n question and return 0 if answer is no, 1 if
@@ -789,17 +837,14 @@ defaulted_query (const char *ctlstr, const char defchar, va_list args)
/* Automatically answer the default value if the user did not want
prompts or the command was issued with the server prefix. */
- if (!confirm || server_command)
+ if (defaulted_query_auto_answers_p (false))
return def_value;
/* If input isn't coming from the user directly, just say what
question we're asking, and then answer the default automatically. This
way, important error messages don't get lost when talking to GDB
over a pipe. */
- if (current_ui->instream != current_ui->stdin_stream
- || !current_ui->input_interactive_p ()
- /* Restrict queries to the main UI. */
- || current_ui != main_ui)
+ if (defaulted_query_auto_answers_p (true))
{
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
diff --git a/gdb/utils.h b/gdb/utils.h
index 7cab021e7a9..6ef2049b2a4 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -515,4 +515,8 @@ struct deferred_warnings final : public warning_hook_handler_type
std::vector<string_file> m_warnings;
};
+/* Whether defaulted queries are answered automatically. */
+
+extern tribool defaulted_query_auto_answers_p ();
+
#endif /* GDB_UTILS_H */
--
2.51.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v5 4/4] [gdb/tui] Don't enter TUI if debuginfod enabled == ask
2026-03-14 17:37 [PATCH v5 0/4] [gdb/tui] Fix crash with debuginfod query Tom de Vries
` (2 preceding siblings ...)
2026-03-14 17:37 ` [PATCH v5 3/4] [gdb] Add defaulted_query_auto_answers_p Tom de Vries
@ 2026-03-14 17:37 ` Tom de Vries
3 siblings, 0 replies; 6+ messages in thread
From: Tom de Vries @ 2026-03-14 17:37 UTC (permalink / raw)
To: gdb-patches
PR tui/31449 reports a SIGFPE when the debuginfod query happens while enabling
TUI using the "tui enable" command:
...
Thread 1 "gdb" received signal SIGFPE, Arithmetic exception.
0x0000000001021084 in tui_inject_newline_into_command_window ()
at /data/vries/gdb/src/gdb/tui/tui-io.c:1096
1096 py += px / tui_cmd_win ()->width;
...
due to divide-by-zero because tui_cmd_win ()->width == 0.
The corresponding backtrace is:
...
(gdb) bt
#0 0x0000000001021084 in tui_inject_newline_into_command_window ()
at gdb/tui/tui-io.c:1096
#1 0x0000000000fe65fd in gdb_readline_wrapper_line (line=...) at gdb/top.c:939
#2 0x0000000000944eef in gdb_rl_callback_handler (rl=0x2cc865a0 "n")
at gdb/event-top.c:288
#3 0x0000000001175779 in rl_callback_read_char ()
at readline/readline/callback.c:302
#4 0x0000000000944bc3 in gdb_rl_callback_read_char_wrapper_sjlj ()
at gdb/event-top.c:197
#5 0x0000000000944cd4 in gdb_rl_callback_read_char_wrapper_noexcept ()
at gdb/event-top.c:240
#6 0x0000000000944d52 in gdb_rl_callback_read_char_wrapper (...)
at gdb/event-top.c:252
#7 0x0000000001062352 in stdin_event_handler (error=0, client_data=0x2c865150)
at gdb/ui.c:154
#8 0x0000000001a04edf in handle_file_event (file_ptr=0x2ccf8850, ready_mask=1)
at gdbsupport/event-loop.cc:551
#9 0x0000000001a05522 in gdb_wait_for_event (block=1)
at gdbsupport/event-loop.cc:672
#10 0x0000000001a043ff in gdb_do_one_event (mstimeout=-1)
at gdbsupport/event-loop.cc:263
#11 0x00000000006d5480 in interp::do_one_event (this=0x2cc2af20, mstimeout=-1)
at gdb/interps.h:93
#12 0x0000000000fe670d in gdb_readline_wrapper (
prompt=0x2ccca4e0 "Enable debuginfod for this session? (y or [n]) ")
at gdb/top.c:1033
#13 0x00000000010c6853 in defaulted_query(...) (...)
at gdb/utils.c:844
#14 0x00000000010c6b8a in nquery (...)
at gdb/utils.c:901
#15 0x00000000007a9324 in debuginfod_is_enabled ()
at gdb/debuginfod-support.c:268
#16 0x00000000007a950d in debuginfod_source_query (...)
at gdb/debuginfod-support.c:311
#17 0x0000000000efc2c7 in open_source_file (s=0x2cc8f4b0) at gdb/source.c:1152
#18 0x0000000000efc619 in symtab_to_fullname (...) at gdb/source.c:1214
#19 0x0000000000f5ebb3 in find_line_symtab (...)
at gdb/symtab.c:3287
#20 0x0000000000f5f0e5 in find_pc_for_line (...)
at gdb/symtab.c:3391
#21 0x0000000001011f54 in tui_get_begin_asm_address (...)
at gdb/tui/tui-disasm.c:404
#22 0x000000000104888d in tui_source_window_base::rerender (this=0x2cbdc570)
at gdb/tui/tui-winsource.c:474
#23 0x0000000001028e81 in tui_win_info::resize (this=0x2cbdc570,
height_=21, width_=127, origin_x_=0,
origin_y_=0) at gdb/tui/tui-layout.c:299
#24 0x00000000010297d0 in tui_layout_window::apply (this=0x2cc50350,
x_=0, y_=0, width_=127,
height_=21, preserve_cmd_win_size_p=false) at gdb/tui/tui-layout.c:432
#25 0x000000000102bfea in tui_layout_split::apply (this=0x2caea920,
x_=0, y_=0, width_=127,
height_=33, preserve_cmd_win_size_p=false) at gdb/tui/tui-layout.c:1026
#26 0x0000000001028267 in tui_apply_current_layout (...)
at gdb/tui/tui-layout.c:68
#27 0x0000000001028737 in tui_set_layout (layout=0x2c9b9e90)
at gdb/tui/tui-layout.c:133
#28 0x0000000001028af5 in tui_set_initial_layout () at gdb/tui/tui-layout.c:209
#29 0x000000000104b795 in tui_enable () at gdb/tui/tui.c:496
#30 0x000000000104bab3 in tui_enable_command (args=0x0, from_tty=1)
at gdb/tui/tui.c:591
#31 0x00000000006c5ffe in do_simple_func (args=0x0, from_tty=1, c=0x2c9bb2f0)
at gdb/cli/cli-decode.c:94
#32 0x00000000006cc94f in cmd_func (cmd=0x2c9bb2f0, args=0x0, from_tty=1)
at gdb/cli/cli-decode.c:2831
#33 0x0000000000fe53ad in execute_command (p=0x2c86699a "", from_tty=1)
at gdb/top.c:563
#34 0x000000000094584d in command_handler (command=0x2c866990 "tui enable")
at gdb/event-top.c:611
#35 0x0000000000945dfe in command_line_handler (rl=...) at gdb/event-top.c:844
#36 0x000000000101e916 in tui_command_line_handler (rl=...)
at gdb/tui/tui-interp.c:101
#37 0x0000000000944eef in gdb_rl_callback_handler (rl=0x2cc86a30 "tui enable")
at gdb/event-top.c:288
#38 0x0000000001175779 in rl_callback_read_char ()
at readline/readline/callback.c:302
#39 0x0000000000944bc3 in gdb_rl_callback_read_char_wrapper_sjlj ()
at gdb/event-top.c:197
#40 0x0000000000944cd4 in gdb_rl_callback_read_char_wrapper_noexcept ()
at gdb/event-top.c:240
#41 0x0000000000944d52 in gdb_rl_callback_read_char_wrapper (...)
at gdb/event-top.c:252
#42 0x0000000001062352 in stdin_event_handler (error=0, client_data=0x2c865150)
at gdb/ui.c:154
#43 0x0000000001a04edf in handle_file_event (file_ptr=0x2ccf8850, ready_mask=1)
at gdbsupport/event-loop.cc:551
#44 0x0000000001a05522 in gdb_wait_for_event (block=1)
at gdbsupport/event-loop.cc:672
#45 0x0000000001a043ff in gdb_do_one_event (mstimeout=-1)
at gdbsupport/event-loop.cc:263
#46 0x00000000006d5480 in interp::do_one_event (this=0x2cc2af20, mstimeout=-1)
at gdb/interps.h:93
#47 0x0000000000b77f25 in start_event_loop () at gdb/main.c:403
#48 0x0000000000b78113 in captured_command_loop () at gdb/main.c:468
#49 0x0000000000b7a07c in captured_main (context=0x7fff660b9e60)
at gdb/main.c:1381
#50 0x0000000000b7a178 in gdb_main (args=0x7fff660b9e60) at gdb/main.c:1400
#51 0x0000000000419705 in main (argc=5, argv=0x7fff660b9f98) at gdb/gdb.c:38
(gdb)
...
The problem is that the command window is used (during initialization of the
source window) before it's properly initialized.
A patch [1] was posted for this PR, which fixes the problem by calling
a function that will force the debuginfod query to happen before enabling the
TUI:
...
static void
tui_enable_command (const char *args, int from_tty)
{
+ /* Trigger any debuginfod-related y/n prompts now to avoid having
+ it occur during tui initialization. Handling the prompt while
+ tui windows are initializing can cause crashes. */
+ debuginfod_is_enabled ();
+
tui_enable ();
}
...
A review comment reported a problem when using C-x C-a to enable TUI instead
of "tui enable", not fixed by the previous patch. This was filed as PR33794.
Another patch [2] took the following approach: add a layout with only the
command window, and activate that layout first, making sure that we finalize
the initialization of the command window before we activate the initial layout.
However, that approach made the debuginfod query happen in an empty screen
in between the CLI and TUI interfaces, which is confusing.
So yet another patch [3] took the following approach:
- adding a facility defer_tui_rerender that allows deferral of calling the
rerender methods (which draws everything but the window borders), and
- using that facility to postpone rerendering in tui_enable until after io has
been initialized.
Then yet another patch [4] tried a minimal fix: add a check at the start of
tui_inject_newline_into_command_window that avoids the SIGFPE.
This patch handles the problem by simply bailing out if debuginfod enabled is
set to ask when entering TUI, which is very similar to [1]. Unlike all
other approaches, it does fix PR33794 as well.
The v4 version of this patch [5] unnecessarily bailed out for:
...
$ gdb -q outputs/gdb.tui/query/query -ex "set confirm off" -ex "tui enable"
...
This v5 version fixes that using defaulted_query_auto_answers_p.
Tested on x86_64-linux, on top of current trunk and gdb-17-branch.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31449
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33794
[1] https://sourceware.org/pipermail/gdb-patches/2024-March/207224.html
[2] v1 https://sourceware.org/pipermail/gdb-patches/2026-January/224038.html
[3] v2 https://sourceware.org/pipermail/gdb-patches/2026-January/224103.html
[4] v3 https://sourceware.org/pipermail/gdb-patches/2026-February/225210.html
[5] v4 https://sourceware.org/pipermail/gdb-patches/2026-February/225351.html
---
gdb/testsuite/gdb.tui/query-foo.c | 24 ++++++++
gdb/testsuite/gdb.tui/query.exp | 92 +++++++++++++++++++++++++++++++
gdb/tui/tui.c | 5 ++
3 files changed, 121 insertions(+)
create mode 100644 gdb/testsuite/gdb.tui/query-foo.c
create mode 100644 gdb/testsuite/gdb.tui/query.exp
diff --git a/gdb/testsuite/gdb.tui/query-foo.c b/gdb/testsuite/gdb.tui/query-foo.c
new file mode 100644
index 00000000000..bf4a8766dcd
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/query-foo.c
@@ -0,0 +1,24 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2026 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+extern int foo (void);
+
+int
+foo (void)
+{
+ return 0;
+}
diff --git a/gdb/testsuite/gdb.tui/query.exp b/gdb/testsuite/gdb.tui/query.exp
new file mode 100644
index 00000000000..bc1a55a1b96
--- /dev/null
+++ b/gdb/testsuite/gdb.tui/query.exp
@@ -0,0 +1,92 @@
+# Copyright 2026 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Check that a debuginfod query during TUI initialization doesn't cause a
+# crash.
+
+require allow_tui_tests
+
+load_lib debuginfod-support.exp
+require allow_debuginfod_tests
+
+tuiterm_env
+
+standard_testfile -main.c -foo.c
+
+set tmpfile [standard_output_file $srcfile]
+set srcfiles [list $tmpfile $srcfile2]
+
+set fd [open $tmpfile w]
+puts $fd {
+ extern int foo (void);
+ int
+ main (void)
+ {
+ return foo ();
+ }
+}
+close $fd
+
+if { [build_executable "failed to prepare" $testfile $srcfiles] == -1 } {
+ return
+}
+
+# Delete query-main.c to trigger the debuginfod query during TUI
+# initialization.
+file delete $tmpfile
+
+set l {}
+lappend l "command"
+lappend l "keys"
+
+foreach_with_prefix how $l {
+ save_vars { env(DEBUGINFOD_URLS) } {
+ setenv DEBUGINFOD_URLS "foo"
+ Term::clean_restart 24 80 $testfile
+ }
+
+ if {![Term::prepare_for_tui]} {
+ return 0
+ }
+
+ Term::gen_prompt
+
+ if { $how == "command" } {
+ send_gdb "tui enable\n"
+ } else {
+ send_gdb "\030\001"
+ }
+ set re \
+ "Please set debuginfod enabled to on or off before enabling TUI"
+ gdb_assert { [Term::wait_for_region_contents 0 0 80 24 $re] }
+
+ # Check that prompt is responsive.
+ gdb_assert { [Term::command "print 1"] } "responsive prompt"
+
+ set cmd "set debuginfod enabled off"
+ gdb_assert { [Term::command "$cmd"] } $cmd
+
+ with_test_prefix tui {
+ if { $how == "command" } {
+ send_gdb "tui enable\n"
+ } else {
+ send_gdb "\030\001"
+ }
+ gdb_assert { [Term::wait_for ""] } "entered"
+
+ # Check that prompt is responsive.
+ gdb_assert { [Term::command "print 1"] } "responsive prompt"
+ }
+}
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
index fb94823f0fe..4b8e46f2068 100644
--- a/gdb/tui/tui.c
+++ b/gdb/tui/tui.c
@@ -41,6 +41,7 @@
#include "top.h"
#include "ui.h"
#include "observable.h"
+#include "debuginfod-support.h"
#include <fcntl.h>
@@ -405,6 +406,10 @@ tui_enable (void)
if (tui_active)
return;
+ if (debuginfod_enabled_ask_p ()
+ && defaulted_query_auto_answers_p () != TRIBOOL_TRUE)
+ error (_("Please set debuginfod enabled to on or off before enabling TUI"));
+
tui_batch_rendering defer;
/* To avoid to initialize curses when gdb starts, there is a deferred
--
2.51.0
^ permalink raw reply [flat|nested] 6+ messages in thread