Fix logging redirection bug with pager

I noticed yesterday that if gdb output is redirected to a file, the
pager will still be active.  This is irritating, because the output
isn't actually visible -- just the pager prompt.  Looking in bugzilla,
I found that this had been filed 17 years ago, as PR cli/8798.

This patch fixes the bug.  It changes the pagination code to query the
particular ui-file to see if paging is allowable.  The ui-file
implementations are changed so that only the stdout implementation and
a tee (where one sub-file is stdout) can page.

Regression tested on x86-64 Fedora 34.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=8798
This commit is contained in:
Tom Tromey
2021-12-27 10:53:16 -07:00
parent ba0084966c
commit 84b334970b
3 changed files with 72 additions and 1 deletions

View File

@ -0,0 +1,51 @@
# Copyright (C) 2021 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/>.
# Do not run if gdb debug is enabled as it will interfere with log redirect.
if [gdb_debug_enabled] {
untested "debug is enabled"
return 0
}
gdb_start
gdb_test_no_output "set width 100"
gdb_test_no_output "set height 5"
gdb_test_no_output "set pagination on"
# Test that logging redirect disables the pager.
set log_name [standard_output_file log.txt]
gdb_test_no_output "set logging file $log_name" \
"set logging filename"
gdb_test_no_output "set logging redirect on"
gdb_test "set logging enabled on" "Copying debug output to .*"
set ok 1
set str "1\\n2\\n3\\n4\\n5\\n"
gdb_test_multiple "printf \"$str\"" "printf without paging" {
-re "$pagination_prompt" {
set ok 0
send_gdb "c\n"
exp_continue
}
-re "\r\n$gdb_prompt $" {
# Ok.
}
}
if {$ok} {
pass "printf without paging"
} else {
fail "printf without paging"
}
gdb_test "set logging enabled off" "Done logging to .*"

View File

@ -88,6 +88,14 @@ public:
Otherwise, return -1. */
virtual int fd () const
{ return -1; }
/* Return true if this object supports paging, false otherwise. */
virtual bool can_page () const
{
/* Almost no file supports paging, which is why this is the
default. */
return false;
}
};
typedef std::unique_ptr<ui_file> ui_file_up;
@ -204,6 +212,11 @@ public:
int fd () const override
{ return m_fd; }
virtual bool can_page () const override
{
return m_file == stdout;
}
private:
/* Sets the internal stream to FILE, and saves the FILE's file
descriptor in M_FD. */
@ -278,6 +291,13 @@ public:
bool can_emit_style_escape () override;
void flush () override;
virtual bool can_page () const override
{
/* If one of the underlying files can page, then we allow it
here. */
return m_one->can_page () || m_two->can_page ();
}
private:
/* The two underlying ui_files. */
ui_file *m_one;

View File

@ -1749,7 +1749,7 @@ fputs_maybe_filtered (const char *linebuffer, struct ui_file *stream,
return;
/* Don't do any filtering if it is disabled. */
if (stream != gdb_stdout
if (!stream->can_page ()
|| !pagination_enabled
|| pagination_disabled_for_command
|| batch_flag