This removes new_ui and delete_ui in favor of ordinary 'new' and
'delete', and then removes make_delete_ui_cleanup in favor of
std::unique_ptr.
2017-10-03 Tom Tromey <tom@tromey.com>
* event-top.c (stdin_event_handler): Update.
* main.c (captured_main_1): Update.
* top.h (make_delete_ui_cleanup): Remove.
(struct ui): Add constructor and destructor.
(new_ui, delete_ui): Remove.
* top.c (make_delete_ui_cleanup): Remove.
(new_ui_command): Use std::unique_ptr.
(delete_ui_cleanup): Remove.
(ui::ui): Rename from new_ui. Update.
(free_ui): Remove.
(ui::~ui): Rename from delete_ui. Update.
Currently we have "current_directory" and "gdb_dirbuf" globals, which
means that we basically have two possible places to consult when we
want to know GDB's current working directory.
This is not ideal and can lead to confusion. Moreover, the way we're
using "gdb_difbuf" along with "getcwd" is problematic because we
declare the buffer with "1024" elements hardcoded, which does not take
into account longer pathnames that are possible in many filesystems.
Using "PATH_MAX" would also not be a solution because of portability
problems. Therefore, the best solution is to rely on the fact that
"getcwd (NULL, 0)" will "do the right thing" and return a
heap-allocated string containing the full path. With the new "getcwd"
module from gnulib, it is now possible to do that without worrying
about breaking some host.
With this patch "current_directory" is now the only place to check for
GDB's cwd.
Reviewed-by: Pedro Alves <palves@redhat.com>
gdb/ChangeLog:
2017-09-22 Sergio Durigan Junior <sergiodj@redhat.com>
* cli/cli-cmds.c (pwd_command): Use "getcwd (NULL, 0)".
(cd_command): Likewise. Free "current_directory" before
assigning to it.
* main.c (captured_main_1): Use "getcwd (NULL, 0)".
* mi/mi-cmd-env.c (mi_cmd_env_pwd): Likewise.
* top.c (gdb_dirbuf): Remove global declaration.
* top.h (gdb_dirbuf): Likewise.
This changes the users of do_restore_instream_cleanup to use a
scoped_restore instead. This patch is broken out because it warrants
some additional attention: in particular it's unclear to me whether
current_ui can change in the body of these functions -- but if it can,
then the cleanup would have modified a different UI's instream member.
ChangeLog
2017-08-03 Tom Tromey <tom@tromey.com>
* top.h (do_restore_instream_cleanup): Remove.
* top.c (do_restore_instream_cleanup): Remove.
(read_command_file): Use scoped_restore.
* cli/cli-script.c (execute_user_command): Use scoped_restore.
While working on the next patch in this series, I found that the
global in_user_command is not used. This patch removes it. (I didn't
think to check Insight until submitting this series; and it's not very
convenient to do so, so if someone has it checked out and could look
at it, that would be nice.)
ChangeLog
2017-08-03 Tom Tromey <tom@tromey.com>
* top.h (in_user_command): Remove.
* top.c (in_user_command): Remove.
* cli/cli-script.c (do_restore_user_call_depth)
(execute_user_command): Update.
This applies the second part of GDB's End of Year Procedure, which
updates the copyright year range in all of GDB's files.
gdb/ChangeLog:
Update copyright year range in all GDB files.
This removes make_cleanup_restore_current_ui by converting the last
use. The last use was in a few functions used to iterate over all
UIs. This patch replaces these functions with a class, and arranges
for the class destructor to do the needed cleanup.
2016-10-21 Tom Tromey <tom@tromey.com>
* tui/tui-interp.c (tui_on_normal_stop, tui_on_signal_received)
(tui_on_end_stepping_range, tui_on_signal_exited, tui_on_exited)
(tui_on_no_history, tui_on_user_selected_context_changed):
Update.
* top.h (switch_thru_all_uis): New class.
(SWITCH_THRU_ALL_UIS): Rewrite.
(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
(switch_thru_all_uis_cond, switch_thru_all_uis_next): Don't
declare.
* mi/mi-interp.c (mi_new_thread, mi_thread_exit)
(mi_record_changed, mi_inferior_added, mi_inferior_appeared)
(mi_inferior_exit, mi_inferior_removed, mi_on_signal_received)
(mi_on_end_stepping_range, mi_on_signal_exited, mi_on_exited)
(mi_on_no_history, mi_on_normal_stop, mi_traceframe_changed)
(mi_tsv_created, mi_tsv_deleted, mi_tsv_modified)
(mi_breakpoint_created, mi_breakpoint_deleted)
(mi_breakpoint_modified, mi_output_running_pid, mi_on_resume)
(mi_solib_loaded, mi_solib_unloaded, mi_command_param_changed)
(mi_memory_changed, mi_user_selected_context_changed): Update.
* infrun.c (all_uis_check_sync_execution_done)
(all_uis_on_sync_execution_starting, normal_stop): Update.
* event-top.c (restore_ui_cleanup)
(make_cleanup_restore_current_ui, switch_thru_all_uis_init)
(switch_thru_all_uis_cond, switch_thru_all_uis_next): Remove.
* cli/cli-interp.c (cli_on_normal_stop, cli_on_signal_received)
(cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited)
(cli_on_no_history, cli_on_user_selected_context_changed):
Update.
* breakpoint.c (watchpoint_check): Update.
This fixes PR gdb/20604. The bug here is that passing an invalid
expression to "quit" -- e.g., "quit()" -- causes gdb to enter a
non-functioning state.
The immediate problem is that quit_force resets the terminal before
evaluating the expression. However, it seemed to me that it doesn't
really make sense to pass the quit_force argument to kill_or_detach
(which passes it to to_detach), first because conflating the exit
status for "quit" and the signal to pass when detaching doesn't make
sense, and second because to_detach implementations generally only
accept a constant here, while "quit" accepts an expression. So, I
removed that.
As an aside, I think the "detach SIGNO" functionality is not
documented.
Built and regtested on x86-64 Fedora 24.
2016-09-21 Tom Tromey <tom@tromey.com>
PR gdb/20604:
* top.h (quit_force): Update.
* top.c (quit_force): Changed type of first argument. Don't
evaluate expression. Pass NULL to kill_or_detach.
* cli/cli-cmds.c (quit_command): Evaluate "args".
2016-09-21 Tom Tromey <tom@tromey.com>
PR gdb/20604:
* gdb.base/quit.exp: New file.
Just a tidy, no functional changes.
gdb/ChangeLog:
2016-09-06 Pedro Alves <palves@redhat.com>
* event-top.c (restore_ui_cleanup): Now static.
(make_cleanup_restore_current_ui): New function.
(switch_thru_all_uis_init): Use it.
* infcall.c (call_thread_fsm_should_stop): Use it.
* infrun.c (fetch_inferior_event): Use it.
* top.c (new_ui_command): Use it.
* top.h (restore_ui_cleanup): Delete declaration.
(make_cleanup_restore_current_ui): New declaration.
When executing commands on a secondary UI running the MI interpreter,
some commands that should be synchronous are not. MI incorrectly
continues processing input right after the synchronous command is
sent, before the target stops.
The problem happens when we emit MI async events (=library-loaded,
etc.), and we go about restoring the previous terminal state, we end
up calling target_terminal_ours, which incorrectly always installs the
current UI's input_fd in the event loop... That is, code like this:
old_chain = make_cleanup_restore_target_terminal ();
target_terminal_ours_for_output ();
fprintf_unfiltered (mi->event_channel, "library-loaded");
...
do_cleanups (old_chain);
The fix is to move the add_file_handler/delete_file_handler calls out
of target_terminal_$foo, making these completely no-ops unless called
with the main UI as current UI.
gdb/ChangeLog:
2016-08-09 Pedro Alves <palves@redhat.com>
PR gdb/20418
* event-top.c (ui_register_input_event_handler)
(ui_unregister_input_event_handler): New functions.
(async_enable_stdin): Register input in the event loop.
(async_disable_stdin): Unregister input from the event loop.
(gdb_setup_readline): Register input in the event loop.
* infrun.c (check_curr_ui_sync_execution_done): Register input in
the event loop.
* target.c (target_terminal_inferior): Don't unregister input from
the event loop.
(target_terminal_ours): Don't register input in the event loop.
* target.h (target_terminal_inferior)
(target_terminal_ours_for_output, target_terminal_ours): Update
comments.
* top.h (ui_register_input_event_handler)
(ui_unregister_input_event_handler): New declarations.
* utils.c (ui_unregister_input_event_handler_cleanup)
(prepare_to_handle_input): New functions.
(defaulted_query, prompt_for_continue): Use
prepare_to_handle_input.
gdb/testsuite/ChangeLog:
2016-08-09 Pedro Alves <palves@redhat.com>
Simon Marchi <simon.marchi@ericsson.com>
PR gdb/20418
* gdb.mi/new-ui-mi-sync.c, gdb.mi/new-ui-mi-sync.exp: New files.
* lib/mi-support.exp (mi_expect_interrupt): Remove anchors.
When a bad interpreter name is passed to new-ui, such as:
(gdb) new-ui bloop /dev/pts/10
A partially created UI is left in the UI list, with interp set to NULL.
Trying to do anything that will print on this UI (such as "start") will
cause a segmentation fault.
Changes in v2:
- Use with_test_prefix to namespace test procedures
- Give an explicit stable test name
- Add a "bad terminal path" test
- Remove useless runto_main
- Add missing intro comments
I did not factor out the pty spawn, as there is some magic involved I
don't quite understand. But it wouldn't bring that much anyway.
gdb/ChangeLog:
* top.h (make_delete_ui_cleanup): New declaration.
* top.c (delete_ui_cleanup): New function.
(make_delete_ui_cleanup): New function.
(new_ui_command): Create restore_ui cleanup earlier, create a
delete_ui cleanup and discard it on success.
gdb/testsuite/ChangeLog:
* gdb.base/new-ui.exp (do_test_invalid_args): New
procedure.
This commit makes each UI have its own "stdin" stream pointer. This
is used to determine whether the "from_tty" argument to
execute_command, etc. should be true.
Related, this commit makes input_from_terminal_p take an UI parameter,
and then avoids the gdb_has_a_terminal in it. gdb_has_a_terminal only
returns info on gdb's own main/primary terminal (the real stdin).
However, the places that call input_from_terminal_p really want to
know is whether the command came from an interactive tty. This patch
thus renames input_from_terminal_p to input_interactive_p for clarity,
and then makes input_interactive_p check for "set interactive" itself,
along with ISATTY, instead of calling gdb_has_a_terminal. Actually,
quit_force wants to call input_interactive_p _after_ stdin is closed,
we can't call ISATTY that late. So instead we save the result of
ISATTY in a field of the UI.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* cli/cli-script.c (read_next_line): Adjust to per-UI stdin.
(read_command_lines): Use input_interactive_p instead of
input_from_terminal_p.
* defs.h (struct ui): Forward declare.
(input_from_terminal_p): Rename to ...
(input_interactive_p): ... this.
* event-top.c (stdin_event_handler): Pass 0 as from_tty argument
to quit_command.
(command_handler): Adjust to per-UI stdin.
(handle_line_of_input): Adjust to per-UI stdin and use
input_interactive_p instead of ISATTY and input_from_terminal_p.
(gdb_readline_no_editing_callback): Adjust to per-UI stdin.
(command_line_handler): Always pass true as "from_tty" parameter
of handle_line_of_input and execute_command.
(async_sigterm_handler): Pass 0 as from_tty argument to
quit_command.
* inflow.c (interactive_mode, show_interactive_mode): Moved to ...
(gdb_has_a_terminal): Don't check interactive_mode here.
(_initialize_inflow): Don't install "set interactive-mode" here.
* main.c (captured_command_loop): Adjust to per-UI stdin.
* mi/mi-interp.c (mi_execute_command_wrapper): Adjust to per-UI
stdin.
* top.c (new_ui): Save the stdin stream and whether it's a tty.
(dont_repeat): Adjust to per-UI stdin.
(command_line_input): Adjust to per-UI stdin and to use
input_interactive_p.
(quit_force): Write history if any UI supports interactive input.
(interactive_mode, show_interactive_mode): Move here, from
inflow.c.
(input_from_terminal_p): Rename to ...
(input_interactive_p): ... this, and check the "interactive_mode"
global instead of calling gdb_has_a_terminal.
(_initialize_top): Install "set interactive-mode" here.
* top.h (struct ui) <stdin_stream, input_interactive_p>: New
fields.
* utils.c (quit): Pass 0 as from_tty argument to quit_force.
(defaulted_query): Adjust to per-UI stdin and to use
input_interactive_p.
Without this, GDB exits if a secondary UIs terminal/input stream is
closed:
$ ./gdb -ex "new-ui mi /dev/pts/6"
New UI allocated
<<< close /dev/pts/6
(gdb) Error detected on fd 9
$
We want that for the main UI, but not secondary UIs.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c (stdin_event_handler): Don't quit gdb if it was a
secondary UI's input stream that closed. Instead, just delete the
UI.
This is preparation for being able to create more than one UI object.
The change to gdb_main to stop using catch_errors is necessary because
catch_errors references current_uiout, which expands to
current_ui->m_current_ui, which would crash because current_ui is not
initialized yet at that point. It didn't trigger earlier in the
series because before this patch, main_ui/current_ui always start out
non-NULL.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c (main_ui_): Delete.
(main_ui, current_ui, ui_list): No longer initialize here.
* main.c (captured_main): UI initialization code factored out to
new new_ui function.
(gdb_main): Wrap captured_main with TRY/CATCH instead of
catch_errors.
* top.c (highest_ui_num): New global.
(new_ui): New function.
* top.h (struct ui) <num>: New field.
(new_ui): New declaration.
When sync_execution (a boolean) is true, it means we're running a
foreground command -- we hide the prompt stop listening to input, give
the inferior the terminal, then go to the event loop waiting for the
target to stop.
With multiple independent UIs, we need to track whether each UI is
synchronously blocked waiting for the target. IOW, if you do
"continue" in one console, that console stops accepting commands, but
you should still be free to type other commands in the others
consoles.
Just simply making sync_execution be per-UI alone not sufficient,
because of this in fetch_inferior_event:
/* If the inferior was in sync execution mode, and now isn't,
restore the prompt (a synchronous execution command has finished,
and we're ready for input). */
if (current_ui->async && was_sync && !sync_execution)
observer_notify_sync_execution_done ();
We'd have to record at entry the "was_sync" state for each UI, not
just of the current UI.
This patch instead replaces the sync_execution flag by a per-UI
tristate flag indicating the command line prompt state:
enum prompt_state
{
/* The command line is blocked simulating synchronous execution.
This is used to implement the foreground execution commands
('run', 'continue', etc.). We won't display the prompt and
accept further commands until the execution is actually over. */
PROMPT_BLOCKED,
/* The command finished; display the prompt before returning back to
the top level. */
PROMPT_NEEDED,
/* We've displayed the prompt already, ready for input. */
PROMPTED,
;
I think the end result is _much_ clearer than the current code, and,
it addresses the original motivation too.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* annotate.c: Include top.h.
(async_background_execution_p): Delete.
(print_value_flags): Check the UI's prompt state rather then
async_background_execution_p.
* event-loop.c (start_event_loop): Set the prompt state to
PROMPT_NEEDED.
* event-top.c (display_gdb_prompt, async_enable_stdin)
(async_disable_stdin): Check the current UI's prompt state instead
of the sync_execution global.
(command_line_handler): Set the prompt state to PROMPT_NEEDED
before running a command, and display the prompt if still needed
afterwards.
* infcall.c (struct call_thread_fsm) <waiting_ui>: New field.
(new_call_thread_fsm): New parameter 'waiting_ui'. Store it.
(call_thread_fsm_should_stop): Set the prompt state to
PROMPT_NEEDED.
(run_inferior_call): Adjust to temporarily set the prompt state to
PROMPT_BLOCKED instead of using the sync_execution global.
(call_function_by_hand_dummy): Pass the current UI to
new_call_thread_fsm.
* infcmd.c: Include top.h.
(continue_1): Check the current UI's prompt state instead of the
sync_execution global.
(continue_command): Validate global execution state before calling
prepare_execution_command.
(step_1): Call all_uis_check_sync_execution_done.
(attach_post_wait): Don't call async_enable_stdin here. Remove
reference to sync_execution.
* infrun.c (sync_execution): Delete global.
(follow_fork_inferior)
(reinstall_readline_callback_handler_cleanup): Check the current
UI's prompt state instead of the sync_execution global.
(check_curr_ui_sync_execution_done)
(all_uis_check_sync_execution_done): New functions.
(fetch_inferior_event): Call all_uis_check_sync_execution_done
instead of trying to determine whether the global sync execution
changed.
(handle_no_resumed): Check the prompt state of all UIs.
(normal_stop): Emit the no unwait-for even to all PROMPT_BLOCKED
UIs. Emit the "Switching to" notification to all UIs. Enable
stdin in all UIs.
* infrun.h (sync_execution): Delete.
(all_uis_check_sync_execution_done): Declare.
* main.c (captured_command_loop): Don't call
interp_pre_command_loop if the prompt is blocked.
(catch_command_errors, catch_command_errors_const): Adjust.
(captured_main): Set the initial prompt state to PROMPT_NEEDED.
* mi/mi-interp.c (display_mi_prompt): Set the prompt state to
PROMPTED.
(mi_interpreter_resume): Don't clear sync_execution. Remove hack
comment.
(mi_execute_command_input_handler): Set the prompt state to
PROMPT_NEEDED before executing the command, and only display the
prompt if the prompt state is PROMPT_NEEDED afterwards.
(mi_on_resume_1): Adjust to check the prompt state.
* target.c (target_terminal_inferior): Adjust to check the prompt
state.
* top.c (wait_sync_command_done, maybe_wait_sync_command_done)
(execute_command): Check the current UI's prompt state instead of
sync_execution.
* top.h (enum prompt_state): New.
(struct ui) <prompt_state>: New field.
(ALL_UIS): New macro.
This makes target events always be always processed with the main UI
as current UI. This way, warnings, debug output, etc. are always
consistently sent to the main console.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c (restore_ui_cleanup): Make extern.
* infrun.c (fetch_inferior_event): Always switch to the main UI.
* top.h (restore_ui_cleanup): Declare.
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.
stderr_fileopen () references stderr directly, which doesn't work when
we have a separate UI with its own stderr-like stream. So this also
adds a "errstream" to "struct ui", and plumbs stderr_fileopen to take
a stream parameter.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c (gdb_setup_readline): Pass the UI's outstream and
errstream to stdout_fileopen and stderr_fileopen.
* exceptions.c: Include top.h.
(print_flush): Open the current UI's outstream file descriptor,
instead of hardcoding file descriptor 1.
* main.c (captured_main): Save the main UI's out and error
streams. Adjust stderr_fileopen call.
* top.h (struct ui) <outstream, errstream>: New fields.
* ui-file.c (stderr_fileopen): Add stream parameter. Use it
instead of stderr.
* ui-file.h (stderr_fileopen): Add stream parameter and update
comment.
And with that, we can switch the current UI to the UI whose input
descriptor woke up the event loop. IOW, if the user types in UI 2,
the event loop wakes up, switches to UI 2, and processes the input.
Next the user types in UI 3, the event loop wakes up and switches to
UI 3, etc.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c (input_fd): Delete.
(stdin_event_handler): Switch to the UI whose input descriptor got
the event. Adjust to per-UI input_fd.
(gdb_setup_readline): Don't set the input_fd global. Adjust to
per-UI input_fd.
(gdb_disable_readline): Adjust to per-UI input_fd.
* event-top.h (input_fd): Delete declaration.
* linux-nat.c (linux_nat_terminal_inferior): Don't remove input_fd
from the event-loop here.
(linux_nat_terminal_ours): Don't register input_fd in the
event-loop here.
* main.c (captured_main): Adjust to per-UI input_fd.
* remote.c (remote_terminal_inferior): Don't remove input_fd from
the event-loop here.
(remote_terminal_ours): Don't register input_fd in the event-loop
here.
* target.c: Include top.h and event-top.h.
(target_terminal_inferior): Remove input_fd from the event-loop
here.
(target_terminal_ours): Register input_fd in the event-loop.
* top.h (struct ui) <input_fd>: New field.
Async signal handlers have no connection to whichever was the current
UI, and thus always run on the main one.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-loop.c: Include top.h.
(invoke_async_signal_handlers): Switch to the main UI.
* event-top.c (main_ui_): Update comment.
(main_ui): New global.
* top.h (main_ui): Declare.
When we have multiple consoles, MI channels, etc., then we need to
broadcast breakpoint hits, etc. to all UIs. In the past, I've
adjusted most of the run control to communicate events to the
interpreters through observer notifications, so events would be
properly sent to console and MI streams, in sync and async modes.
This patch does the next logical step -- have each interpreter's
observers output interpreter-specific info to _all_ UIs.
Note that when we have multiple instances of active cli/tui
interpreters, then the cli_interp and tui_interp globals no longer
work. This is addressed by this patch.
Also, the interpreters currently register some observers when resumed
and remove them when suspended. If we have multiple instances of the
interpreters, and they can be suspended/resumed at different,
independent times, that no longer works. What we instead do is always
install the observers, and then have the observers themselves know
when to do nothing.
An earlier prototype of this series did the looping over struct UIs in
common code, and then dispatched events to the interpreters through a
matching interp_on_foo method for each observer. That turned out a
lot more complicated than the present solution, as we'd end up with
having to create a new interp method every time some interpreter
wanted to listen to some observer notification, resulting in a lot of
duplicated make-work and more coupling than desirable.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* cli/cli-interp.c (cli_interp): Delete.
(as_cli_interp): New function.
(cli_on_normal_stop, cli_on_signal_received)
(cli_on_end_stepping_range, cli_on_signal_exited, cli_on_exited)
(cli_on_no_history): Send output to all CLI UIs.
(cli_on_sync_execution_done, cli_on_command_error): Skip output if
the top level interpreter is not a CLI.
(cli_interpreter_init): Don't set cli_interp or install observers
here.
(_initialize_cli_interp): Install observers here.
* event-top.c (main_ui_, ui_list): New globals.
(current_ui): Point to main_ui_.
(restore_ui_cleanup, switch_thru_all_uis_init)
(switch_thru_all_uis_cond, switch_thru_all_uis_next): New
functions.
* mi/mi-interp.c (as_mi_interp): New function.
(mi_interpreter_init): Don't install observers here.
(mi_on_sync_execution_done): Skip output if the top level
interpreter is not a MI.
(mi_new_thread, mi_thread_exit, mi_record_changed)
(mi_inferior_added, mi_inferior_appeared, mi_inferior_exit)
(mi_inferior_removed): Send output to all MI UIs.
(find_mi_interpreter, mi_interp_data): Delete.
(find_mi_interp): New function.
(mi_on_signal_received, mi_on_end_stepping_range)
(mi_on_signal_exited, mi_on_exited, mi_on_no_history): Send output
to all MI UIs.
(mi_on_normal_stop): Rename to ...
(mi_on_normal_stop_1): ... this.
(mi_on_normal_stop): Reimplement, sending output to all MI UIs.
(mi_traceframe_changed, mi_tsv_created, mi_tsv_deleted)
(mi_tsv_modified, mi_breakpoint_created, mi_breakpoint_deleted)
(mi_breakpoint_modified, mi_output_running_pid): Send output to
all MI UIs.
(mi_on_resume): Rename to ...
(mi_on_resume_1): ... this. Don't handle infcalls here.
(mi_on_resume): Reimplement, sending output to all MI UIs.
(mi_solib_loaded, mi_solib_unloaded, mi_command_param_changed)
(mi_memory_changed): Send output to all MI UIs.
(report_initial_inferior): Install observers here.
* top.h (struct ui) <next>: New field.
(ui_list): Declare.
(struct switch_thru_all_uis): New.
(switch_thru_all_uis_init, switch_thru_all_uis_cond)
(switch_thru_all_uis_next): Declare.
(SWITCH_THRU_ALL_UIS): New macro.
* tui/tui-interp.c (tui_interp): Delete global.
(as_tui_interp): New function.
(tui_on_normal_stop, tui_on_signal_received)
(tui_on_end_stepping_range, tui_on_signal_exited, tui_on_exited)
(tui_on_no_history): Send output to all TUI UIs.
(tui_on_sync_execution_done, tui_on_command_error): Skip output if
the top level interpreter is not a TUI.
(tui_init): Don't set tui_interp or install observers here.
(_initialize_tui_interp): Install observers here.
Make each UI have its own interpreter list, top level interpreter,
current interpreter, etc. The "interpreter_async" global is not
really specific to an struct interp (it crosses interpreter-exec ...),
so I moved it to "struct ui" directly, while the other globals were
left hidden in interps.c, opaque to the rest of GDB.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* breakpoint.c (bpstat_do_actions_1): Access the current UI's
async field instead of the interpreter_async global.
* cli/cli-script.c (execute_user_command, while_command)
(if_command, script_from_file): Likewise.
* compile/compile.c: Include top.h instead of interps.h.
(compile_file_command, compile_code_command)
(compile_print_command): Access the current UI's async field
instead of the interpreter_async global.
* guile/guile.c: Include top.h instead of interps.h.
(guile_repl_command, guile_command, gdbscm_execute_gdb_command):
Access the current UI's async field instead of the
interpreter_async global.
* guile/scm-ports.c: Include top.h instead of interps.h.
(ioscm_with_output_to_port_worker): Access the current UI's async
field instead of the interpreter_async global.
* inf-loop.c (inferior_event_handler): Likewise.
* infcall.c (run_inferior_call): Likewise.
* infrun.c (reinstall_readline_callback_handler_cleanup)
(fetch_inferior_event): Likewise.
* interps.c (interpreter_async): Delete.
(struct ui_interp_info): New.
(get_current_interp_info): New function.
(interp_list, current_interpreter, top_level_interpreter_ptr):
Delete.
(interp_add, interp_set, interp_lookup, interp_ui_out)
(current_interp_set_logging, interp_set_temp)
(current_interp_named_p): Adjust to per-UI interpreters.
(command_interpreter): Delete.
(command_interp, current_interp_command_loop, interp_quiet_p)
(interp_exec, interpreter_exec_cmd, interpreter_completer)
(top_level_interpreter, top_level_interpreter_data): Adjust to
per-UI interpreters.
* interps.h (interpreter_async): Delete.
* main.c (captured_command_loop): Access the current UI's async
field instead of the interpreter_async global.
* python/python.c (python_interactive_command, python_command)
(execute_gdb_command): Likewise.
* top.c (maybe_wait_sync_command_done, execute_command_to_string):
Access the current UI's async field instead of the
interpreter_async global.
* top.h (struct tl_interp_info): Forward declare.
(struct ui) <interp_info, async>: New fields.
We need to have these send output to the proper UI.
However, this patch still make them look like globals. Kind of like
__thread variables, if you will. Changing everything throughout to
write something like current_ui->gdb_stdout instead would be massive
overkill, IMNSHO.
This leaves gdb_stdtargin/stdtarg/stdtargerr global, but maybe that was a
mistake, I'm not sure -- IIRC, MI formats target I/O differently, so
if we have a separate MI channel, then I guess target output should go
there instead of to gdb's stdout. OTOH, maybe GDB should send that
instead to "set inferior-tty", instead of multiplexing it over MI. We
can always fix those later when it gets clearer where they should go.
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* main.c (gdb_stdout, gdb_stderr, gdb_stdlog, gdb_stdin): Delete
globals.
(gen_ret_current_ui_field_ptr): New macro. Use it to generate
wrappers for gdb_stdout, gdb_stderr, gdb_stdlog and gdb_stdin.
* top.h (struct ui) <m_gdb_stdout, m_gdb_stdin, m_gdb_stderr,
m_gdb_stdlog>: New fields.
(current_ui_gdb_stdout_ptr, current_ui_gdb_stdin_ptr)
(current_ui_gdb_stderr_ptr, current_ui_gdb_stdlog_ptr): Declare.
(gdb_stdout, gdb_stdin, gdb_stderr, gdb_stdlog): Reimplement as
macros.
This is a step towards supporting multiple consoles/MIs, each on its
own stdio streams / terminal.
See intro comment in top.h.
(I've had trouble picking a name for this object. I've started out
with "struct console" originally. But then this is about MI as well,
and there's "interpreter-exec console", which is specifically about
the CLI...
So I changed to "struct terminal", but, then we have a terminal object
that works when the input is not a terminal as well ...
Then I sort of gave up and renamed it to "struct top_level". But it
then gets horribly confusing when we talk about the "top level
interpreter that's running on the current top level".
In the end, I realized we're already sort of calling this "ui", in
struct ui_out, struct ui_file, and a few coments here and there.)
gdb/ChangeLog:
2016-06-21 Pedro Alves <palves@redhat.com>
* event-top.c: Update readline-related comments.
(input_handler, call_readline): Delete globals.
(gdb_rl_callback_handler): Call the current UI's input_handler
method.
(change_line_handler): Adjust to set current UI's properties
instead of globals.
(current_ui_, current_ui): New globals.
(get_command_line_buffer): Rewrite to refer to the current UI.
(stdin_event_handler): Adjust to call the call_readline method of
the current UI.
(gdb_readline_no_editing_callback): Adjust to call the current UI's
input_handler method.
(gdb_setup_readline): Adjust to set current UI's properties
instead of globals.
* event-top.h (call_readline, input_handler): Delete declarations.
* mi/mi-interp.c (mi_interpreter_resume): Adjust to set current
UI's properties instead of globals.
* top.c (gdb_readline_wrapper_cleanup): Adjust to set current UI's
properties instead of globals.
(gdb_readline_wrapper): Adjust to call and set current UI's
methods instead of globals.
* top.h: Include buffer.h and event-loop.h.
(struct ui): New struct.
(current_ui): New declaration.
I didn't manage to usefully split this further into smaller
independent pieces, so:
- Use "struct buffer" more.
- Split out the responsibility of composing a complete command line
from multiple input lines split with backslash
(
E.g.:
(gdb) print \
1 + \
2
$1 = 3
(gdb)
)
to a separate function. Note we don't need the separate
readline_input_state and more_to_come globals at all. They were
just obfuscating the logic.
- Factor out the tricky mostly duplicated code in
command_line_handler and command_line_input.
gdb/ChangeLog
2016-03-09 Pedro Alves <palves@redhat.com>
* event-top.c (more_to_come): Delete.
(struct readline_input_state): Delete.
(readline_input_state): Delete.
(get_command_line_buffer): New function.
(command_handler): Update comments. Don't handle NULL commands
here. Do not execute commented lines.
(command_line_append_input_line): New function.
(handle_line_of_input): New function, partly based on
command_line_handler and command_line_input.
(command_line_handler): Rewrite.
* event-top.h (command_handler): New declaration.
(command_loop): Defer command execution to command_handler.
(command_line_input): Update comments. Simplify, using struct
buffer and handle_line_of_input.
* top.h (struct buffer): New forward declaration.
(handle_line_of_input): New declaration.
There doesn't seem to be much point in trying to reuse this buffer.
Prefer simplicity instead.
(In case you're wondering whether this fixes an off-by-one: linelength
is misnamed; it's really a size including terminating null char.)
gdb/ChangeLog:
2016-03-09 Pedro Alves <palves@redhat.com>
* event-top.c (command_line_handler): Use xfree + xstrdup instead
of xrealloc + strcpy.
* main.c (captured_main): Use xstrdup instead of xmalloc plus
manual clear.
* top.c (saved_command_line): Rewrite comment.
(saved_command_line_size): Delete.
(command_line_input): Use xfree + xstrdup instead of xrealloc +
strcpy.
* top.h (saved_command_line_size): Delete declaration.
This patch makes the execution control code use largely the same
mechanisms in both sync- and async-capable targets. This means using
continuations and use the event loop to react to target events on sync
targets as well. The trick is to immediately mark infrun's event loop
source after resume instead of calling wait_for_inferior. Then
fetch_inferior_event is adjusted to do a blocking wait on sync
targets.
Tested on x86_64 Fedora 20, native and gdbserver, with and without
"maint set target-async off".
gdb/ChangeLog:
2015-09-09 Pedro Alves <palves@redhat.com>
* breakpoint.c (bpstat_do_actions_1, until_break_command): Don't
check whether the target can async.
* inf-loop.c (inferior_event_handler): Only call target_async if
the target can async.
* infcall.c: Include top.h and interps.h.
(run_inferior_call): For the interpreter to sync mode while
running the infcall. Call wait_sync_command_done instead of
wait_for_inferior plus normal_stop.
* infcmd.c (prepare_execution_command): Don't check whether the
target can async when running in the foreground.
(step_1): Delete synchronous case handling.
(step_once): Always install a continuation, even in sync mode.
(until_next_command, finish_forward): Don't check whether the
target can async.
(attach_command_post_wait, notice_new_inferior): Always install a
continuation, even in sync mode.
* infrun.c (mark_infrun_async_event_handler): New function.
(proceed): In sync mode, mark infrun's event source instead of
waiting for events here.
(fetch_inferior_event): If the target can't async, do a blocking
wait.
(prepare_to_wait): In sync mode, mark infrun's event source.
(infrun_async_inferior_event_handler): No longer bail out if the
target can't async.
* infrun.h (mark_infrun_async_event_handler): New declaration.
* linux-nat.c (linux_nat_wait_1): Remove calls to
set_sigint_trap/clear_sigint_trap.
(linux_nat_terminal_inferior): No longer check whether the target
can async.
* mi/mi-interp.c (mi_on_sync_execution_done): Update and simplify
comment.
(mi_execute_command_input_handler): No longer check whether the
target is async. Update and simplify comment.
* target.c (default_target_wait): New function.
* target.h (struct target_ops) <to_wait>: Now defaults to
default_target_wait.
(default_target_wait): Declare.
* top.c (wait_sync_command_done): New function, factored out from
...
(maybe_wait_sync_command_done): ... this.
* top.h (wait_sync_command_done): Declare.
* target-delegates.c: Regenerate.
This patch fixes the following bug in TUI:
(gdb) break foo
No symbol table is loaded. Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) <ENTER>
By submitting an empty command line to a secondary prompt, the line
corresponding to the secondary prompt is undesirably cleared and
overwritten. Outside of a secondary prompt, clearing the prompt line
after submitting an empty command line is intended behavior which
complements GDB's repeat-command shorthand. But inside a secondary
prompt, this behavior is undesired since the shorthand is not applicable
in that case. We should retain the secondary-prompt line even when it's
given no input.
This patch makes sure that a prompt that was given an empty command line
is cleared and overwritten only if it's not a secondary prompt. To
acheive this, a new predicate is defined which informs us whether the
current input handler is a secondary prompt.
gdb/ChangeLog:
* top.h (gdb_in_secondary_prompt_p): Declare.
* top.c (gdb_secondary_prompt_depth): Define.
(gdb_in_secondary_prompt_p): Define.
(gdb_readline_wrapper_cleanup): Decrement
gdb_secondary_prompt_depth.
(gdb_readline_wrapper): Increment gdb_secondary_prompt_depth.
* tui/tui-io.c (tui_getc): Don't clear the prompt line if we
are in a secondary prompt.
This patch makes readline append new history lines to the GDB history
file on exit instead of overwriting the entire history file on exit.
This change allows us to run multiple simultaneous GDB sessions without
having each session overwrite the added history of each other session on
exit.
Care must be taken to ensure that the history file doesn't get corrupted
when multiple GDB processes are trying to simultaneously append to and
then truncate it. Safety is achieved in such a situation by using an
intermediate local history file to mutually exclude multiple processes
from simultaneously performing write operations on the global history
file.
gdb/ChangeLog:
* top.h (gdb_add_history): Declare.
* top.c (command_count): New variable.
(gdb_add_history): New function.
(gdb_safe_append_history): New static function.
(quit_force): Call it.
(command_line_input): Use gdb_add_history instead of
add_history.
* event-top.c (command_line_handler): Likewise.
Doing:
gdb --pid=PID -ex run
Results in GDB getting a SIGTTIN, and thus ending stopped. That's
usually indicative of a missing target_terminal_ours call.
E.g., from the PR:
$ sleep 1h & p=$!; sleep 0.1; gdb -batch sleep $p -ex run
[1] 28263
[1] Killed sleep 1h
[2]+ Stopped gdb -batch sleep $p -ex run
The workaround is doing:
gdb -ex "attach $PID" -ex "run"
instead of
gdb [-p] $PID -ex "run"
With the former, gdb waits for the attach command to complete before
moving on to the "run" command, because the interpreter is in sync
mode at this point, within execute_command. But for the latter,
attach_command is called directly from captured_main, and thus misses
that waiting. IOW, "run" is running before the attach continuation
has run, before the program stops and attach completes. The broken
terminal settings are just one symptom of that. Any command that
queries or requires input results in the same.
The fix is to wait in catch_command_errors (which is specific to
main.c nowadays), just like we wait in execute_command.
gdb/ChangeLog:
2014-09-11 Pedro Alves <palves@redhat.com>
PR gdb/17347
* main.c: Include "infrun.h".
(catch_command_errors, catch_command_errors_const): Wait for the
foreground command to complete.
* top.c (maybe_wait_sync_command_done): New function, factored out
from ...
(maybe_wait_sync_command_done): ... here.
* top.h (maybe_wait_sync_command_done): New declaration.
gdb/testsuite/ChangeLog:
2014-09-11 Pedro Alves <palves@redhat.com>
PR gdb/17347
* lib/gdb.exp (gdb_spawn_with_cmdline_opts): New procedure.
* gdb.base/attach.exp (test_command_line_attach_run): New
procedure.
(top level): Call it.
This simplifies the .gdbinit filename selection logic.
We have a GDBINIT_FILENAME define that supposedly configurations would
override, but none do so. Instead, the only configuration that wants
a different file name instead of ".gdbinit", djgpp, does a strcpy over
the gdbinit global array. This means the array needs to be sized, and
the code that does that is doing the usual
'PATH_MAX/FILENAME_MAX/fallback constant/etc.' mess.
Instead of all that, it's much simpler to have configure specificy the
.gdbinit filename. As bonus, we can then make the "gdbinit" global
array const.
gdb/
2013-07-01 Pedro Alves <palves@redhat.com>
* configure.ac (GDBINIT): Define, depending on host.
* go32-nat.c (init_go32_ops): Don't override gdbinit here.
* top.c (PATH_MAX): Delete fallback definition.
(GDBINIT_FILENAME): Delete.
(gdbinit): Reimplement as const char array set to the GDBINIT
string constant.
* top.h (gdbinit): Make const.
* top.c (print_gdb_configuration): New function, displays the
details about GDB configure-time parameters.
(print_gdb_version): Mention "show configuration".
* cli/cli-cmds.c (show_configuration): New function.
(_initialize_cli_cmds): Add the "show configuration" command.
* main.c (captured_main) <print_configuration>: New static var.
<long_options>: Use it.
If --configuration was given, call print_gdb_configuration.
* doc/gdb.texinfo (Mode Options): Document '-configuration'.
(Help): Document "show configuration".
(Bug Reporting): Add requirements to include the configuration
details in bug reports.
Two modifications:
1. The addition of 2013 to the copyright year range for every file;
2. The use of a single year range, instead of potentially multiple
year ranges, as approved by the FSF.
quit_cover, call pop_all_targets. Use TRY_CATCH instead of
catch_errors.
* top.c (quit_cover): Return void and take no arguments.
* top.h (quit_cover): Update prototype.
* event-top.h (MAXPROMPTS, struct prompts): Delete.
(set_async_annotation_level, set_async_prompt, pop_prompt)
(push_prompt, new_async_prompt): Delete declarations.
* top.h (get_prompt, set_prompt): Change prototype.
(get_prefix, set_prefix, get_suffix, set_suffix): Delete
declarations.
* top.c (command_loop):
(top_prompt): New global.
(get_prefix, set_prefix, get_suffix, ): Delete.
(get_prompt, set_prompt): Rewrite.
(show_new_async_prompt): Rename to ...
(show_prompt): ... this.
(init_main): Adjust. Don't handle --annotate=2 here.
* event-top.c (new_async_prompt): Delete.
(the_prompts): Delete.
(more_to_come): Make static.
(display_gdb_prompt): Use top_level_prompt() to compute the top
level prompt, and don't notify the before_prompt observers
directly here. Always trick readline into not trying to display
the prompt if sync_execution and displaying the primary prompt.
If displaying a local/secondary prompt, always show it, even if
sync_execution is set.
(change_annotation_level): Delete.
(top_level_prompt): New, based on change_annotation_level.
(push_prompt, pop_prompt): Delete.
(async_disable_stdin): No longer pushes prompt.
(command_line_handler): No longer pushes or pops prompt. If more
input is expected, call display_gdb_prompt with an explicit empty
prompt.
(async_stop_sig): Adjust.
(set_async_annotation_level, set_async_prompt): Delete.
* python/python.c (before_prompt_hook): Adjust.
* event-top.c (cli_command_loop): Use get_prompt, get_suffix,
get_prefix.
(display_gdb_prompt): Likewise.
(change_annotation_level): Likewise.
(push_prompt): Likewise.
(pop_prompt): Likewise.
(handle_stop_sig): Use get_prompt with a level.
* top.c (command_loop): Use get_prompt with a level.
(set_async_annotation_level): Use set_prompt with a level.
(get_prefix): New function.
(set_prefix): Ditto.
(set_suffix): Ditto.
(get_suffix): Ditto.
(get_prompt): Accept a level argument.
(set_prompt): Accept a level argument. Free old prompts. Set
new_async_prompt if level is 0.
(init_main): Use set_prompt with a level. Do not set
new_async_prompt.
* event-top.h (PROMPT, SUFFIX, PREFIX): Move to top.c
* top.h: Declare set_suffix, get_suffix, set_prefix, get_prefix.
Modify set_prompt, get_prompt to account for levels.
* tui/tui-interp.c (tui_command_loop): Use get_prompt with a
level
* python/python.c (before_prompt_hook): Use set_prompt.