aboutsummaryrefslogtreecommitdiff
path: root/gdb/stack.c
diff options
context:
space:
mode:
authorAaron Merey <amerey@redhat.com>2024-01-12 14:38:45 -0500
committerAaron Merey <amerey@redhat.com>2024-01-19 00:18:00 -0500
commit519d634396592c5698add4a327468e6e6920576e (patch)
tree695c241945e77efdfae59af2a33922425cb8f290 /gdb/stack.c
parent64db3e4d881d347704139c89d90048082774c9cc (diff)
downloadbinutils-519d634396592c5698add4a327468e6e6920576e.zip
binutils-519d634396592c5698add4a327468e6e6920576e.tar.gz
binutils-519d634396592c5698add4a327468e6e6920576e.tar.bz2
gdb: Buffer output streams during events that might download debuginfo
Introduce new ui_file buffering_file to temporarily collect output written to gdb_std* output streams during print_thread, print_frame_info and print_stop_event. This ensures that output during these functions is not interrupted by debuginfod progress messages. With the addition of deferred debuginfo downloading it is possible for download progress messages to print during these events. Without any intervention we can end up with poorly formatted output: (gdb) backtrace [...] #8 0x00007fbe8af7d7cf in pygi_invoke_c_callable (Downloading separate debug info for /lib64/libpython3.11.so.1.0 function_cache=0x561221b224d0, state=<optimized out>... To fix this we buffer writes to gdb_std* output streams while allowing debuginfod progress messages to skip the buffers and print to the underlying output streams immediately. Buffered output is then written to the output streams. This ensures that progress messages print first, followed by uninterrupted frame/thread/stop info: (gdb) backtrace [...] Downloading separate debug info for /lib64/libpython3.11.so.1.0 #8 0x00007fbe8af7d7cf in pygi_invoke_c_callable (function_cache=0x561221b224d0, state=<optimized out>... Co-Authored-By: Andrew Burgess <aburgess@redhat.com> Approved-By: Andrew Burgess <aburgess@redhat.com>
Diffstat (limited to 'gdb/stack.c')
-rw-r--r--gdb/stack.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/gdb/stack.c b/gdb/stack.c
index 2de3e36..96a9cd4 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -220,7 +220,8 @@ static void print_frame_local_vars (frame_info_ptr frame,
const char *regexp, const char *t_regexp,
int num_tabs, struct ui_file *stream);
-static void print_frame (const frame_print_options &opts,
+static void print_frame (struct ui_out *uiout,
+ const frame_print_options &opts,
frame_info_ptr frame, int print_level,
enum print_what print_what, int print_args,
struct symtab_and_line sal);
@@ -1020,16 +1021,15 @@ get_user_print_what_frame_info (std::optional<enum print_what> *what)
Used in "where" output, and to emit breakpoint or step
messages. */
-void
-print_frame_info (const frame_print_options &fp_opts,
- frame_info_ptr frame, int print_level,
- enum print_what print_what, int print_args,
- int set_current_sal)
+static void
+do_print_frame_info (struct ui_out *uiout, const frame_print_options &fp_opts,
+ frame_info_ptr frame, int print_level,
+ enum print_what print_what, int print_args,
+ int set_current_sal)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
int source_print;
int location_print;
- struct ui_out *uiout = current_uiout;
if (!current_uiout->is_mi_like_p ()
&& fp_opts.print_frame_info != print_frame_info_auto)
@@ -1105,7 +1105,8 @@ print_frame_info (const frame_print_options &fp_opts,
|| print_what == LOC_AND_ADDRESS
|| print_what == SHORT_LOCATION);
if (location_print || !sal.symtab)
- print_frame (fp_opts, frame, print_level, print_what, print_args, sal);
+ print_frame (uiout, fp_opts, frame, print_level,
+ print_what, print_args, sal);
source_print = (print_what == SRC_LINE || print_what == SRC_AND_LOC);
@@ -1185,6 +1186,20 @@ print_frame_info (const frame_print_options &fp_opts,
gdb_flush (gdb_stdout);
}
+/* Redirect output to a temporary buffer for the duration
+ of do_print_frame_info. */
+
+void
+print_frame_info (const frame_print_options &fp_opts,
+ frame_info_ptr frame, int print_level,
+ enum print_what print_what, int print_args,
+ int set_current_sal)
+{
+ do_with_buffered_output (do_print_frame_info, current_uiout,
+ fp_opts, frame, print_level, print_what,
+ print_args, set_current_sal);
+}
+
/* See stack.h. */
void
@@ -1309,13 +1324,13 @@ find_frame_funname (frame_info_ptr frame, enum language *funlang,
}
static void
-print_frame (const frame_print_options &fp_opts,
+print_frame (struct ui_out *uiout,
+ const frame_print_options &fp_opts,
frame_info_ptr frame, int print_level,
enum print_what print_what, int print_args,
struct symtab_and_line sal)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- struct ui_out *uiout = current_uiout;
enum language funlang = language_unknown;
struct value_print_options opts;
struct symbol *func;