This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[patch] Fix python gdb.execute to not paginate
- From: Jan Kratochvil <jan dot kratochvil at redhat dot com>
- To: gdb-patches at sourceware dot org
- Cc: David Malcolm <dmalcolm at redhat dot com>
- Date: Thu, 5 Aug 2010 23:20:08 +0200
- Subject: [patch] Fix python gdb.execute to not paginate
Hi,
downstream Bug: https://bugzilla.redhat.com/show_bug.cgi?id=620930
(gdb) python for i in range(100): a = gdb.execute('info registers', to_string=True)
---Type <return> to continue, or q <return> to quit---
When at it I have merged it with making --batch more batch, as the output IMO
should not depend on the momentarily terminal - wrapping and indenting the
output on its width.
The patch makes python gdb.execute running in the --batch mode. I understand
it may not be universally right but so far I believe it is. What do you
think?
(--batch should be IMO somehow merged now with `set interactive-mode'. That
is not a part of this patch.)
Regards,
Jan
gdb/
2010-08-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* defs.h (make_cleanup_restore_uinteger)
(make_cleanup_restore_page_info): New declarations.
* python/python.c: Include main.h.
(execute_gdb_command) <to_string>: Temporarily set BATCH_FLAG and call
init_page_info.
* utils.c (make_cleanup_restore_uinteger)
(init_page_info) <batch_flag>
(do_restore_page_info_cleanup, make_cleanup_restore_page_info): New.
gdb/testsuite/
2010-08-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.python/python.exp (show height, set height 10)
(verify pagination beforehand, verify pagination beforehand: q)
(gdb.execute does not page, verify pagination afterwards)
(verify pagination afterwards: q): New.
gdb/doc/
2010-08-05 Jan Kratochvil <jan.kratochvil@redhat.com>
* gdb.texinfo (Mode Options) <-batch>
(Basic Python) <gdb.execute>: Describe setting width and height.
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -351,6 +351,7 @@ struct obstack;
extern struct cleanup *make_cleanup_obstack_free (struct obstack *obstack);
extern struct cleanup *make_cleanup_restore_integer (int *variable);
+extern struct cleanup *make_cleanup_restore_uinteger (unsigned int *variable);
struct target_ops;
extern struct cleanup *make_cleanup_unpush_target (struct target_ops *ops);
@@ -385,6 +386,7 @@ extern int nquery (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
extern int yquery (const char *, ...) ATTRIBUTE_PRINTF (1, 2);
extern void init_page_info (void);
+extern struct cleanup *make_cleanup_restore_page_info (void);
extern char *gdb_realpath (const char *);
extern char *xfullpath (const char *);
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -46,6 +46,7 @@ static int gdbpy_should_print_stack = 1;
#include "version.h"
#include "target.h"
#include "gdbthread.h"
+#include "main.h"
static PyMethodDef GdbMethods[];
@@ -380,6 +381,13 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
if (to_string)
{
+ /* GDB_STDOUT should be better already restored during these
+ restoration callbacks. */
+ make_cleanup_restore_page_info ();
+ make_cleanup_restore_integer (&batch_flag);
+ batch_flag = 1;
+ init_page_info ();
+
str_file = mem_fileopen ();
make_cleanup_restore_ui_file (&gdb_stdout);
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -352,6 +352,14 @@ make_cleanup_restore_integer (int *variable)
xfree);
}
+/* Remember the current value of *VARIABLE and make it restored when the cleanup
+ is run. */
+struct cleanup *
+make_cleanup_restore_uinteger (unsigned int *variable)
+{
+ return make_cleanup_restore_integer ((int *) variable);
+}
+
/* Helper for make_cleanup_unpush_target. */
static void
@@ -2052,6 +2060,12 @@ static int wrap_column;
void
init_page_info (void)
{
+ if (batch_flag)
+ {
+ lines_per_page = UINT_MAX;
+ chars_per_line = UINT_MAX;
+ }
+ else
#if defined(TUI)
if (!tui_get_command_dimension (&chars_per_line, &lines_per_page))
#endif
@@ -2096,6 +2110,25 @@ init_page_info (void)
set_width ();
}
+static void
+do_restore_page_info_cleanup (void *arg)
+{
+ set_screen_size ();
+ set_width ();
+}
+
+struct cleanup *
+make_cleanup_restore_page_info (void)
+{
+ struct cleanup *back_to;
+
+ back_to = make_cleanup (do_restore_page_info_cleanup, NULL);
+ make_cleanup_restore_uinteger (&lines_per_page);
+ make_cleanup_restore_uinteger (&chars_per_line);
+
+ return back_to;
+}
+
/* Set the screen size based on LINES_PER_PAGE and CHARS_PER_LINE. */
static void
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -87,3 +87,26 @@ gdb_test "python import itertools; print 'IMPOR'+'TED'" "IMPORTED" "pythonX.Y/li
gdb_test_no_output \
"python x = gdb.execute('printf \"%d\", 23', to_string = True)"
gdb_test "python print x" "23"
+
+# Test (no) pagination of the executed command.
+gdb_test "show height" {Number of lines gdb thinks are in a page is unlimited\.}
+set lines 10
+gdb_test_no_output "set height $lines"
+
+set test "verify pagination beforehand"
+gdb_test_multiple "python print \"\\n\" * $lines" $test {
+ -re "---Type <return> to continue, or q <return> to quit---$" {
+ pass $test
+ }
+}
+gdb_test "q" "Quit" "verify pagination beforehand: q"
+
+gdb_test "python if gdb.execute('python print \"\\\\n\" * $lines', to_string=True) == \"\\n\" * [expr $lines + 1]: print \"yes\"" "yes" "gdb.execute does not page"
+
+set test "verify pagination afterwards"
+gdb_test_multiple "python print \"\\n\" * $lines" $test {
+ -re "---Type <return> to continue, or q <return> to quit---$" {
+ pass $test
+ }
+}
+gdb_test "q" "Quit" "verify pagination afterwards: q"
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -1031,9 +1031,9 @@ Run in batch mode. Exit with status @code{0} after processing all the
command files specified with @samp{-x} (and all commands from
initialization files, if not inhibited with @samp{-n}). Exit with
nonzero status if an error occurs in executing the @value{GDBN} commands
-in the command files. Batch mode also disables pagination;
-@pxref{Screen Size} and acts as if @kbd{set confirm off} were in
-effect (@pxref{Messages/Warnings}).
+in the command files. Batch mode also disables pagination, sets unlimited
+terminal width and height; @pxref{Screen Size} and acts as if @kbd{set confirm
+off} were in effect (@pxref{Messages/Warnings}).
Batch mode may be useful for running @value{GDBN} as a filter, for
example to download and run a program on another computer; in order to
@@ -20484,7 +20484,9 @@ By default, any output produced by @var{command} is sent to
@value{GDBN}'s standard output. If the @var{to_string} parameter is
@code{True}, then output will be collected by @code{gdb.execute} and
returned as a string. The default is @code{False}, in which case the
-return value is @code{None}.
+return value is @code{None}. With @code{True} @var{to_string} the
+@value{GDBN} virtual terminal has temporarily set unlimited width and height
+with disabled pagination; @pxref{Screen Size}.
@end defun
@findex gdb.breakpoints