aboutsummaryrefslogtreecommitdiff
path: root/gdb/cli/cli-script.c
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2018-09-17 08:26:24 -0400
committerSimon Marchi <simon.marchi@ericsson.com>2018-09-17 08:26:24 -0400
commit8588b356927dabd582d1d67f87a161027cb2aed1 (patch)
tree2a2f8d2519cb33f2efd5c40fa9d72a40187b584e /gdb/cli/cli-script.c
parenta0a8a9340dc79116297627a0884c6a01543e4b34 (diff)
downloadgdb-8588b356927dabd582d1d67f87a161027cb2aed1.zip
gdb-8588b356927dabd582d1d67f87a161027cb2aed1.tar.gz
gdb-8588b356927dabd582d1d67f87a161027cb2aed1.tar.bz2
python: Make gdb.execute("show commands") work (PR 23669)
Since commit 56bcdbea2bed ("Let gdb.execute handle multi-line commands") trying to use a command like gdb.execute("show commands") in Python fails. GDB ends up trying to run the "commands" command. The reason is that GDB gets confused with the special "commands" command. In process_next_line, the lookup_cmd_1 function returns the cmd_list_element representing the "commands" sub-command of "show". Lower, we check the cmd_list_element to see if it matches various control commands by name, including the "commands" command. This is where we wrongfully conclude that the executed command must be "commands", when in reality it was "show commands". The fix proposed in this patch removes the comparisons by name, instead comparing the cmd_list_element object by pointer with the objects created at initialization time. Tested on the buildbot, though on a single builder (Fedora-x86_64-m64). gdb/ChangeLog: PR python/23669 * breakpoint.c (commands_cmd_element): New. (_initialize_breakpoint): Assign commands_cmd_element. * breakpoint.h (commands_cmd_element): New. * cli/cli-script.c (while_cmd_element, if_command, define_cmd_element): New. (command_name_equals): Remove. (process_next_line): Compare commands by pointer, not by name. (_initialize_cli_script): Assign the various cmd_list_element variables. * compile/compile.c (compile_cmd_element): New. (_initialize_compile): Assign compile_cmd_element. * compile/compile.h (compile_cmd_element): New. * guile/guile.c (guile_cmd_element): New. (install_gdb_commands): Assign guile_cmd_element. * guile/guile.h (guile_cmd_element): New. * python/python.c (python_cmd_element): New. (_initialize_python): Assign python_cmd_element. * python/python.h (python_cmd_element): New. * tracepoint.c (while_stepping_cmd_element): New. (_initialize_tracepoint): Assign while_stepping_cmd_element. * tracepoint.h (while_stepping_cmd_element): New. gdb/testsuite/ChangeLog: PR python/23669 * gdb.python/python.exp: Test gdb.execute("show commands").
Diffstat (limited to 'gdb/cli/cli-script.c')
-rw-r--r--gdb/cli/cli-script.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 8496fb8..e5b0f40 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -25,6 +25,7 @@
#include "ui-out.h"
#include "top.h"
#include "breakpoint.h"
+#include "tracepoint.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-script.h"
@@ -33,6 +34,8 @@
#include "interps.h"
#include "compile/compile.h"
#include "common/gdb_string_view.h"
+#include "python/python.h"
+#include "guile/guile.h"
#include <vector>
@@ -58,6 +61,15 @@ static int command_nest_depth = 1;
/* This is to prevent certain commands being printed twice. */
static int suppress_next_print_command_trace = 0;
+/* Command element for the 'while' command. */
+static cmd_list_element *while_cmd_element = nullptr;
+
+/* Command element for the 'if' command. */
+static cmd_list_element *if_cmd_element = nullptr;
+
+/* Command element for the 'define' command. */
+static cmd_list_element *define_cmd_element = nullptr;
+
/* Structure for arguments to user defined functions. */
class user_args
@@ -906,16 +918,6 @@ read_next_line (void)
return command_line_input (prompt_ptr, "commands");
}
-/* Return true if CMD's name is NAME. */
-
-static bool
-command_name_equals (struct cmd_list_element *cmd, const char *name)
-{
- return (cmd != NULL
- && cmd != CMD_LIST_AMBIGUOUS
- && strcmp (cmd->name, name) == 0);
-}
-
/* Given an input line P, skip the command and return a pointer to the
first argument. */
@@ -990,7 +992,7 @@ process_next_line (const char *p, struct command_line **command,
/* Check for while, if, break, continue, etc and build a new
command line structure for them. */
- if (command_name_equals (cmd, "while-stepping"))
+ if (cmd == while_stepping_cmd_element)
{
/* Because validate_actionline and encode_action lookup
command's line as command, we need the line to
@@ -1005,34 +1007,28 @@ process_next_line (const char *p, struct command_line **command,
not. */
*command = build_command_line (while_stepping_control, p);
}
- else if (command_name_equals (cmd, "while"))
- {
- *command = build_command_line (while_control, line_first_arg (p));
- }
- else if (command_name_equals (cmd, "if"))
- {
- *command = build_command_line (if_control, line_first_arg (p));
- }
- else if (command_name_equals (cmd, "commands"))
- {
- *command = build_command_line (commands_control, line_first_arg (p));
- }
- else if (command_name_equals (cmd, "define"))
+ else if (cmd == while_cmd_element)
+ *command = build_command_line (while_control, line_first_arg (p));
+ else if (cmd == if_cmd_element)
+ *command = build_command_line (if_control, line_first_arg (p));
+ else if (cmd == commands_cmd_element)
+ *command = build_command_line (commands_control, line_first_arg (p));
+ else if (cmd == define_cmd_element)
*command = build_command_line (define_control, line_first_arg (p));
- else if (command_name_equals (cmd, "python") && !inline_cmd)
+ else if (cmd == python_cmd_element && !inline_cmd)
{
/* Note that we ignore the inline "python command" form
here. */
*command = build_command_line (python_control, "");
}
- else if (command_name_equals (cmd, "compile") && !inline_cmd)
+ else if (cmd == compile_cmd_element && !inline_cmd)
{
/* Note that we ignore the inline "compile command" form
here. */
*command = build_command_line (compile_control, "");
(*command)->control_u.compile.scope = COMPILE_I_INVALID_SCOPE;
}
- else if (command_name_equals (cmd, "guile") && !inline_cmd)
+ else if (cmd == guile_cmd_element && !inline_cmd)
{
/* Note that we ignore the inline "guile command" form here. */
*command = build_command_line (guile_control, "");
@@ -1597,7 +1593,7 @@ _initialize_cli_script (void)
Document a user-defined command.\n\
Give command name as argument. Give documentation on following lines.\n\
End with a line of just \"end\"."));
- add_com ("define", class_support, define_command, _("\
+ define_cmd_element = add_com ("define", class_support, define_command, _("\
Define a new command name. Command name is argument.\n\
Definition appears on following lines, one command per line.\n\
End with a line of just \"end\".\n\
@@ -1606,13 +1602,13 @@ Commands defined in this way may accept an unlimited number of arguments\n\
accessed via $arg0 .. $argN. $argc tells how many arguments have\n\
been passed."));
- add_com ("while", class_support, while_command, _("\
+ while_cmd_element = add_com ("while", class_support, while_command, _("\
Execute nested commands WHILE the conditional expression is non zero.\n\
The conditional expression must follow the word `while' and must in turn be\n\
followed by a new line. The nested commands must be entered one per line,\n\
and should be terminated by the word `end'."));
- add_com ("if", class_support, if_command, _("\
+ if_cmd_element = add_com ("if", class_support, if_command, _("\
Execute nested commands once IF the conditional expression is non zero.\n\
The conditional expression must follow the word `if' and must in turn be\n\
followed by a new line. The nested commands must be entered one per line,\n\