diff options
author | Pedro Alves <palves@redhat.com> | 2016-06-21 01:11:48 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-06-21 01:11:48 +0100 |
commit | 3c216924d6ae534ea6c2f6bdcc4b42238af52ab1 (patch) | |
tree | 3c75bdbe8e48f1ae075ca113b8a1b66171d5c780 /gdb/cli | |
parent | b6dcde571e1a230d12fc483ba6d38a1253ab097e (diff) | |
download | gdb-3c216924d6ae534ea6c2f6bdcc4b42238af52ab1.zip gdb-3c216924d6ae534ea6c2f6bdcc4b42238af52ab1.tar.gz gdb-3c216924d6ae534ea6c2f6bdcc4b42238af52ab1.tar.bz2 |
Make command line editing (use of readline) be per UI
Due to the way that readline's API works (based on globals), we can
only have one instance of readline in a process. So the goal of this
patch is to only allow editing in the main UI, and make sure that only
one UI calls into readline. Some MI paths touch readline variables
currently, which is bad as that is changing variables that matter for
the main console UI. This patch fixes those.
This actually fixes a nasty bug -- starting gdb in MI mode ("gdb
-i=mi"), and then doing "set editing on" crashes GDB, because MI is
not prepared to use readline:
set editing on
&"set editing on\n"
=cmd-param-changed,param="editing",value="on"
^done
(gdb)
p 1
readline: readline_callback_read_char() called with no handler!
Aborted (core dumped)
The fix for that was to add an interp_proc method to query the
interpreter whether it actually supports editing. New test included.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
PR mi/20034
* cli/cli-interp.c: Include cli-interp.h and event-top.h.
(cli_interpreter_resume): Pass 1 to gdb_setup_readline. Set the
UI's input_handler here.
(cli_interpreter_supports_command_editing): New function.
(cli_interp_procs): Install it.
* cli/cli-interp.h: New file.
* event-top.c (async_command_editing_p): Rename to ...
(set_editing_cmd_var): ... this.
(change_line_handler): Add parameter 'editing', and use it. Bail
early if the interpreter doesn't support editing. Don't touch
readline state if editing is off.
(gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install)
(gdb_rl_callback_handler_reinstall): Assert the current UI is the
main UI.
(display_gdb_prompt): Don't call gdb_rl_callback_handler_remove if
not using readline. Check whether the current UI is using command
editing instead of checking the async_command_editing_p global.
(set_async_editing_command): Delete.
(gdb_setup_readline): Add 'editing' parameter. Only allow editing
on the main UI. Don't touch readline state if editing is off.
(gdb_disable_readline): Don't touch readline state if editing is
off.
* event-top.h (gdb_setup_readline): Add 'int' parameter.
(set_async_editing_command): Delete declaration.
(change_line_handler, command_line_handler): Declare.
(async_command_editing_p): Rename to ...
(set_editing_cmd_var): ... this.
* infrun.c (reinstall_readline_callback_handler_cleanup): Check
whether the current UI has editing enabled rather than checking
the async_command_editing_p global.
* interps.c (interp_supports_command_editing): New function.
* interps.h (interp_supports_command_editing_ftype): New typedef.
(struct interp_procs) <supports_command_editing_proc>: New field.
(interp_supports_command_editing): Declare.
* mi/mi-interp.c (mi_interpreter_resume): Pass 0 to
gdb_setup_readline. Don't clear the async_command_editing_p
global. Update comments.
* top.c (gdb_readline_wrapper_line, gdb_readline_wrapper): Check
whether the current UI has editing enabled rather than checking
the async_command_editing_p global. Don't touch readline state if
editing is off.
(undo_terminal_modifications_before_exit): Switch to the main UI.
Unconditionally call gdb_disable_readline.
(set_editing): New function.
(show_async_command_editing_p): Rename to ...
(show_editing): ... this. Show the state of the current UI.
(_initialize_top): Adjust.
* top.h (struct ui) <command_editing>: New field.
* tui/tui-interp.c: Include cli/cli-interp.h.
(tui_resume): Pass 1 to gdb_setup_readline. Set the UI's
input_handler.
(tui_interp_procs): Install
cli_interpreter_supports_command_editing.
* tui/tui-io.c (tui_getc): Check whether the current UI has
editing enabled rather than checking the async_command_editing_p
global.
gdb/testsuite/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
PR mi/20034
* gdb.mi/mi-editing.exp: New file.
Diffstat (limited to 'gdb/cli')
-rw-r--r-- | gdb/cli/cli-interp.c | 16 | ||||
-rw-r--r-- | gdb/cli/cli-interp.h | 25 |
2 files changed, 39 insertions, 2 deletions
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c index 2d20073..e5d23b5 100644 --- a/gdb/cli/cli-interp.c +++ b/gdb/cli/cli-interp.c @@ -18,11 +18,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" +#include "cli-interp.h" #include "interps.h" #include "event-top.h" #include "ui-out.h" #include "cli-out.h" #include "top.h" /* for "execute_command" */ +#include "event-top.h" #include "infrun.h" #include "observer.h" @@ -199,6 +201,7 @@ cli_interpreter_init (struct interp *self, int top_level) static int cli_interpreter_resume (void *data) { + struct ui *ui = current_ui; struct cli_interp *cli = (struct cli_interp *) data; struct ui_file *stream; @@ -215,7 +218,9 @@ cli_interpreter_resume (void *data) stream = NULL; } - gdb_setup_readline (); + gdb_setup_readline (1); + + ui->input_handler = command_line_handler; if (stream != NULL) cli_out_set_stream (cli->cli_uiout, gdb_stdout); @@ -255,6 +260,12 @@ cli_interpreter_exec (void *data, const char *command_str) return result; } +int +cli_interpreter_supports_command_editing (struct interp *interp) +{ + return 1; +} + static struct gdb_exception safe_execute_command (struct ui_out *command_uiout, char *command, int from_tty) { @@ -301,7 +312,8 @@ static const struct interp_procs cli_interp_procs = { cli_interpreter_exec, /* exec_proc */ cli_ui_out, /* ui_out_proc */ NULL, /* set_logging_proc */ - cli_command_loop /* command_loop_proc */ + cli_command_loop, /* command_loop_proc */ + cli_interpreter_supports_command_editing, /* supports_command_editing_proc */ }; /* Factory for CLI interpreters. */ diff --git a/gdb/cli/cli-interp.h b/gdb/cli/cli-interp.h new file mode 100644 index 0000000..07b7505 --- /dev/null +++ b/gdb/cli/cli-interp.h @@ -0,0 +1,25 @@ +/* CLI Definitions for GDB, the GNU debugger. + + Copyright (C) 2016 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/>. */ + +#ifndef CLI_INTERP_H +#define CLI_INTERP_H 1 + +struct interp; + +extern int cli_interpreter_supports_command_editing (struct interp *interp); + +#endif |