[PATCH] gdb: Fix from_tty argument to gdb.execute in Python.

Gareth Rees grees@undo.io
Tue Sep 22 10:23:43 GMT 2020


Prior to commit 56bcdbea2b, the from_tty keyword argument to the
Python function gdb.execute controlled whether the command took input
from the terminal. When from_tty=True, the "starti" command prompted
the user:

    (gdb) python gdb.execute("starti", from_tty=True)
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /bin/true

    Program stopped.

When from_tty=False, it did not prompt the user, and "yes" was assumed:

    (gdb) python gdb.execute('starti', from_tty=False)

    Program stopped.

However, after commit 56bcdbea2b, the from_tty keyword argument no
longer had this effect. For example, as of commit 7ade7fba75:

    (gdb) python gdb.execute('starti', from_tty=True)
    The program being debugged has been started already.
    Start it from the beginning? (y or n) [answered Y; input not from terminal]
    Starting program: /bin/true

    Program stopped.

Note the "[answered Y; input not from terminal]" in the output even
though from_tty=True was requested.

Looking at commit 56bcdbea2b, it seems that the behaviour of the
from_tty argument was changed accidentally. The commit message said:

    Let gdb.execute handle multi-line commands

    This changes the Python API so that gdb.execute can now handle
    multi-line commands, like "commands" or "define".

and there was no mention of changing the effect of the from_tty
argument. It looks as though the code for setting the instream to 0
was accidentally moved from execute_user_command() to
execute_control_commands() along with the code for iterating over a
series of command lines.

Accordingly, the simplest way to fix this is to partially reverse
commit 56bcdbea2b by moving the code for setting the instream to 0
back to execute_user_command() where it was to begin with.

Additionally, add a test case to reduce the risk of similar breakage
in future.

gdb/ChangeLog:

	* cli/cli-script.c (execute_control_commands): don't set
        instream to 0 here as this breaks the from_tty argument to
        gdb.execute in Python.
        (execute_user_command): set instream to 0 here instead.

gdb/testsuite/ChangeLog:

	* gdb.python/python.exp: add test cases for the from_tty
        argument to gdb.execute.
---
 gdb/cli/cli-script.c                | 16 ++++++++--------
 gdb/testsuite/gdb.python/python.exp | 13 +++++++++++++
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index da4a41023a..4adcda85e6 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -392,14 +392,6 @@ execute_cmd_post_hook (struct cmd_list_element *c)
 void
 execute_control_commands (struct command_line *cmdlines, int from_tty)
 {
-  /* Set the instream to 0, indicating execution of a
-     user-defined function.  */
-  scoped_restore restore_instream
-    = make_scoped_restore (&current_ui->instream, nullptr);
-  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
-  scoped_restore save_nesting
-    = make_scoped_restore (&command_nest_depth, command_nest_depth + 1);
-
   while (cmdlines)
     {
       enum command_control_type ret = execute_control_command (cmdlines,
@@ -464,6 +456,14 @@ execute_user_command (struct cmd_list_element *c, const char *args)
   if (user_args_stack.size () > max_user_call_depth)
     error (_("Max user call depth exceeded -- command aborted."));
 
+  /* Set the instream to 0, indicating execution of a
+     user-defined function.  */
+  scoped_restore restore_instream
+    = make_scoped_restore (&current_ui->instream, nullptr);
+  scoped_restore save_async = make_scoped_restore (&current_ui->async, 0);
+  scoped_restore save_nesting
+    = make_scoped_restore (&command_nest_depth, command_nest_depth + 1);
+
   execute_control_commands (cmdlines, 0);
 }
 
diff --git a/gdb/testsuite/gdb.python/python.exp b/gdb/testsuite/gdb.python/python.exp
index a031ea5a18..017f33afe5 100644
--- a/gdb/testsuite/gdb.python/python.exp
+++ b/gdb/testsuite/gdb.python/python.exp
@@ -526,3 +526,16 @@ gdb_test "print \$cvar3" "= void" \
 # Test PR 23669, the following would invoke the "commands" command instead of
 # "show commands".
 gdb_test "python gdb.execute(\"show commands\")" "$decimal  print \\\$cvar3.*"
+
+# Test that the from_tty argument to gdb.execute is effective. If
+# False, the user is not prompted for decisions such as restarting the
+# program, and "yes" is assumed. If True, the user is prompted.
+gdb_test "python gdb.execute('starti', from_tty=False)" \
+    "Program stopped.*" \
+    "starti via gdb.execute, not from tty"
+gdb_test_multiple "python gdb.execute('starti', from_tty=True)" \
+    "starti via gdb.execute, from tty" {
+    -re {The program being debugged has been started already\.\r\nStart it from the beginning\? \(y or n\) $} {
+	gdb_test "y" "Starting program:.*" "starti via interactive input"
+    }
+}
-- 
2.26.0



More information about the Gdb-patches mailing list