gdb/cli-out.c: clear_current_line shouldn't trigger pagination prompt
authorAaron Merey <amerey@redhat.com>
Tue, 23 May 2023 15:03:32 +0000 (11:03 -0400)
committerAaron Merey <amerey@redhat.com>
Tue, 23 May 2023 15:12:31 +0000 (11:12 -0400)
clear_current_line overwrites the current line with chars_per_line
blank spaces.  Printing the final space triggers a condition in
pager_file::puts that causes lines_printed to be incremented.  If
lines_printed becomes greater than or equal to lines_allowed, the
pagination prompt will appear if enabled.

In this case the prompt is unnecessary since after printing the final
space clear_current_line immediately moves the cursor to the beginning
of the line with '\r'.  A new line isn't actually started, so the prompt
ends up being spurious.

Additionally it's possible for gdb to crash during this pagination prompt.
Answering the prompt with 'q' throws an exception intended to bring gdb
back to the main event loop.  But since commit 0fea10f32746,
clear_current_line may be called under the progress_update destructor.
The exception will try to propagate through the destructor, causing an abort.

To fix this, pagination is disabled for the duration for clear_current_line.
clear_current_line is also renamed to clear_progress_notify to help
indicate that it is a special purpose function intended for use with
do_progress_notify.

Acked-by: Eli Zaretskii <eliz@gnu.org>
gdb/cli-out.c
gdb/cli-out.h

index 4c598883d4bae05a964f3335fb99bd01c8ef0e8e..20d3d93f1ade3deb6a5afa086f4f54905e54d222 100644 (file)
@@ -378,15 +378,18 @@ cli_ui_out::do_progress_notify (const std::string &msg,
   return;
 }
 
-/* Clear the current line of the most recent progress update.  Overwrites
-   the current line with whitespace.  */
+/* Clear do_progress_notify output from the current line.  Overwrites the
+   notification with whitespace.  */
 
 void
-cli_ui_out::clear_current_line ()
+cli_ui_out::clear_progress_notify ()
 {
   struct ui_file *stream = m_streams.back ();
   int chars_per_line = get_chars_per_line ();
 
+  scoped_restore save_pagination
+    = make_scoped_restore (&pagination_enabled, false);
+
   if (!stream->isatty ()
       || !current_ui->input_interactive_p ()
       || chars_per_line < MIN_CHARS_PER_LINE)
@@ -413,7 +416,7 @@ cli_ui_out::do_progress_end ()
   m_progress_info.pop_back ();
 
   if (stream->isatty ())
-    clear_current_line ();
+    clear_progress_notify ();
 }
 
 /* local functions */
index 0729834cbc67d75dddf624de5e38163d56970f2a..340161822698b8d19ea99a3967b52e66331701a4 100644 (file)
@@ -104,7 +104,7 @@ private:
 
   /* Stack of progress info.  */
   std::vector<cli_progress_info> m_progress_info;
-  void clear_current_line ();
+  void clear_progress_notify ();
 };
 
 extern void cli_display_match_list (char **matches, int len, int max);