[gdb/cli] Don't count printed lines for paging when paging is off

Message ID 20230406113456.23077-1-tdevries@suse.de
State New
Headers
Series [gdb/cli] Don't count printed lines for paging when paging is off |

Commit Message

Tom de Vries April 6, 2023, 11:34 a.m. UTC
  GDB has a pagination function which is enabled by both:
- set height, and
- set pagination.

Pagination is on by default, and height is set to something appropriate for
the terminal:
...
(gdb) show pagination
State of pagination is on.
(gdb) show height
Number of lines gdb thinks are in a page is 21.
(gdb)
...

So, let's see it in action (with height set to 4 to keep it shortish):
...
(gdb) set height 4
(gdb) echo bla\nbla\nbla\nbla\n
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
(gdb) echo bla\nbla\nbla\nbla\n
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
(gdb)
...
It appears that the pagination is for a single command, and lines printed
(before or after pagination) for a previous command do not affect pagination
for the next command.

Interestingly, for commands issued from the gdb invocation, the output of both
commands is taken together, resulting in pagination at a different location:
...
$ gdb -ex "set height 4" \
    -ex "echo bla\nbla\nbla\nbla\n" \
    -ex "echo bla\nbla\nbla\nbla\n"
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
(gdb)
...

Ok, so let's try switch off paging inbetween:
...
$ gdb -ex "set height 4" \
    -ex "echo bla\nbla\nbla\nbla\n" \
    -ex "set height 0" \
    -ex "echo bla\nbla\nbla\nbla\n"
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
bla
bla
bla
(gdb)
...
Yep, that worked, we only got one pagination prompt.

OK, then let's try renable paging afterwards:
...
$ gdb -ex "set height 4" \
  -ex "echo bla\nbla\nbla\nbla\n" \
  -ex "set height 0" \
  -ex "echo bla\nbla\nbla\nbla\n" \
  -ex "set height 4" \
  -ex "echo bla\nbla\nbla\nbla\n"
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
(gdb)
...

So, what happened?  After renabling paging, we get a paging prompt immediately.
Appearantly switching off paging did not reset the
lines-printed-since-last-paging-prompt counter (lines_printed in GDB).

Fix this by:
- resetting lines_printed to 0 when setting pagination to off, or
  setting height to 0, and
- not increasing lines_printed when paging is effectively off,
such that we have instead:
...
$ gdb -ex "set height 4" \
    -ex "echo bla\nbla\nbla\nbla\n" \
    -ex "set height 0" \
    -ex "echo bla\nbla\nbla\nbla\n" \
    -ex "set height 4" \
    -ex "echo bla\nbla\nbla\nbla\n"
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
bla
bla
bla
bla
bla
bla
bla
--Type <RET> for more, q to quit, c to continue without paging--
bla
(gdb)
...

Tested on x86_64-linux.

PR cli/30320
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30320
---
 .../gdb.base/paginate-execution-startup.exp   | 22 +++++--------------
 gdb/utils.c                                   | 22 ++++++++++++++++---
 2 files changed, 24 insertions(+), 20 deletions(-)


base-commit: a5f3ca48236a79b0cf78a82dee1cc0241a975eb7
  

Patch

diff --git a/gdb/testsuite/gdb.base/paginate-execution-startup.exp b/gdb/testsuite/gdb.base/paginate-execution-startup.exp
index 0b14db2f922..e1688249017 100644
--- a/gdb/testsuite/gdb.base/paginate-execution-startup.exp
+++ b/gdb/testsuite/gdb.base/paginate-execution-startup.exp
@@ -84,37 +84,25 @@  proc test_fg_execution_pagination_return {} {
     append GDBFLAGS " --args \"$file_arg\""
 
     with_test_prefix "return" {
-	set test "run to pagination"
-
 	gdb_exit
 	set res [gdb_spawn]
 	if { $res != 0} {
 	    fail $test
 	    return $res
 	}
-	gdb_test_multiple "" $test {
-	    -re "$pagination_prompt$" {
-		pass $test
-	    }
-	    -re "$gdb_prompt $" {
-		fail $test
-	    }
-	}
 
-	send_gdb "\n"
-
-	set saw_pagination_prompt 0
-	set test "send \\n to GDB"
-	gdb_test_multiple "" $test {
+	set nr_pagination_prompts 0
+	gdb_test_multiple "" "get initial prompt" {
 	    -re "$pagination_prompt$" {
-		set saw_pagination_prompt 1
+		incr nr_pagination_prompts
 		send_gdb "\n"
 		exp_continue
 	    }
 	    -re "$gdb_prompt $" {
-		gdb_assert $saw_pagination_prompt $test
+		pass $gdb_test_name
 	    }
 	}
+	gdb_assert { $nr_pagination_prompts == 1 }
 
 	gdb_test "p 1" " = 1" "GDB accepts further input"
 
diff --git a/gdb/utils.c b/gdb/utils.c
index 6ec1cc0d48d..12f49cc05e1 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -1259,6 +1259,16 @@  static void
 set_height_command (const char *args, int from_tty, struct cmd_list_element *c)
 {
   set_screen_size ();
+
+  if (lines_per_page == UINT_MAX)
+    lines_printed = 0;
+}
+
+static void
+set_pagination_command (const char *args, int from_tty, struct cmd_list_element *c)
+{
+  if (!pagination_enabled)
+    lines_printed = 0;
 }
 
 /* See utils.h.  */
@@ -1609,7 +1619,10 @@  pager_file::puts (const char *linebuffer)
 	      bool did_paginate = false;
 
 	      chars_printed = 0;
-	      lines_printed++;
+	      if (pagination_enabled
+		  && !pagination_disabled_for_command
+		  && lines_per_page != UINT_MAX)
+		lines_printed++;
 	      if (m_wrap_column)
 		{
 		  /* We are about to insert a newline at an historic
@@ -1670,7 +1683,10 @@  pager_file::puts (const char *linebuffer)
 	{
 	  chars_printed = 0;
 	  wrap_here (0); /* Spit out chars, cancel further wraps.  */
-	  lines_printed++;
+	  if (pagination_enabled
+	      && !pagination_disabled_for_command
+	      && lines_per_page != UINT_MAX)
+	    lines_printed++;
 	  m_stream->puts ("\n");
 	  lineptr++;
 	}
@@ -3623,7 +3639,7 @@  Show state of GDB output pagination."), _("\
 When pagination is ON, GDB pauses at end of each screenful of\n\
 its output and asks you whether to continue.\n\
 Turning pagination off is an alternative to \"set height unlimited\"."),
-			   NULL,
+			   set_pagination_command,
 			   show_pagination_enabled,
 			   &setlist, &showlist);