/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
- Copyright (C) 2002-2018 Free Software Foundation, Inc.
+ Copyright (C) 2002-2019 Free Software Foundation, Inc.
This file is part of GDB.
interpreter. */
static void mi_execute_command_wrapper (const char *cmd);
-static void mi_execute_command_input_handler (char *cmd);
+static void mi_execute_command_input_handler
+ (gdb::unique_xmalloc_ptr<char> &&cmd);
/* These are hooks that we put in place while doing interpreter_exec
so we can report interesting things that happened "behind the MI's
mi_interp::init (bool top_level)
{
mi_interp *mi = this;
- const char *name;
int mi_version;
/* Store the current output channel, so that we can create a console
mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
- name = interp_name (this);
/* INTERP_MI selects the most recent released version. "mi2" was
released as part of GDB 6.0. */
- if (strcmp (name, INTERP_MI) == 0)
+ if (strcmp (name (), INTERP_MI) == 0)
mi_version = 2;
- else if (strcmp (name, INTERP_MI1) == 0)
+ else if (strcmp (name (), INTERP_MI1) == 0)
mi_version = 1;
- else if (strcmp (name, INTERP_MI2) == 0)
+ else if (strcmp (name (), INTERP_MI2) == 0)
mi_version = 2;
- else if (strcmp (name, INTERP_MI3) == 0)
+ else if (strcmp (name (), INTERP_MI3) == 0)
mi_version = 3;
else
gdb_assert_not_reached ("unhandled MI version");
/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
static void
-mi_execute_command_input_handler (char *cmd)
+mi_execute_command_input_handler (gdb::unique_xmalloc_ptr<char> &&cmd)
{
struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
struct ui *ui = current_ui;
ui->prompt_state = PROMPT_NEEDED;
- mi_execute_command_wrapper (cmd);
+ mi_execute_command_wrapper (cmd.get ());
/* Print a prompt, indicating we're ready for further input, unless
we just started a synchronous command. In that case, we're about
static void
mi_new_thread (struct thread_info *t)
{
- struct inferior *inf = find_inferior_ptid (t->ptid);
-
- gdb_assert (inf);
-
SWITCH_THRU_ALL_UIS ()
{
struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
fprintf_unfiltered (mi->event_channel,
"thread-created,id=\"%d\",group-id=\"i%d\"",
- t->global_num, inf->num);
+ t->global_num, t->inf->num);
gdb_flush (mi->event_channel);
}
}
/* Since this can be called when CLI command is executing,
using cli interpreter, be sure to use MI uiout for output,
not the current one. */
- struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
+ struct ui_out *mi_uiout = top_level_interpreter ()->interp_ui_out ();
struct mi_interp *mi = (struct mi_interp *) top_level_interpreter ();
if (print_frame)
else
mi_uiout->field_string ("stopped-threads", "all");
- core = target_core_of_thread (inferior_ptid);
+ core = target_core_of_thread (tp->ptid);
if (core != -1)
mi_uiout->field_int ("core", core);
}
{
/* Suppress output while calling an inferior function. */
- if (!ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid != null_ptid)
{
struct thread_info *tp = inferior_thread ();
if (mi == NULL)
continue;
- mi_uiout = interp_ui_out (top_level_interpreter ());
+ mi_uiout = top_level_interpreter ()->interp_ui_out ();
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
static void
mi_print_breakpoint_for_event (struct mi_interp *mi, breakpoint *bp)
{
- ui_out *mi_uiout = interp_ui_out (mi);
+ ui_out *mi_uiout = mi->interp_ui_out ();
/* We want the output from print_breakpoint to go to
mi->event_channel. One approach would be to just call
}
}
-static int
-mi_output_running_pid (struct thread_info *info, void *arg)
+static void
+mi_output_running (struct thread_info *thread)
{
- ptid_t *ptid = (ptid_t *) arg;
-
SWITCH_THRU_ALL_UIS ()
{
struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
if (mi == NULL)
continue;
- if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
- fprintf_unfiltered (mi->raw_stdout,
- "*running,thread-id=\"%d\"\n",
- info->global_num);
+ fprintf_unfiltered (mi->raw_stdout,
+ "*running,thread-id=\"%d\"\n",
+ thread->global_num);
}
-
- return 0;
}
-static int
-mi_inferior_count (struct inferior *inf, void *arg)
+/* Return true if there are multiple inferiors loaded. This is used
+ for backwards compatibility -- if there's only one inferior, output
+ "all", otherwise, output each resumed thread individually. */
+
+static bool
+multiple_inferiors_p ()
{
- if (inf->pid != 0)
+ int count = 0;
+ for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
{
- int *count_p = (int *) arg;
- (*count_p)++;
+ count++;
+ if (count > 1)
+ return true;
}
- return 0;
+ return false;
}
static void
current_token ? current_token : "");
}
- if (ptid_get_pid (ptid) == -1)
+ /* Backwards compatibility. If doing a wildcard resume and there's
+ only one inferior, output "all", otherwise, output each resumed
+ thread individually. */
+ if ((ptid == minus_one_ptid || ptid.is_pid ())
+ && !multiple_inferiors_p ())
fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
- else if (ptid_is_pid (ptid))
- {
- int count = 0;
-
- /* Backwards compatibility. If there's only one inferior,
- output "all", otherwise, output each resumed thread
- individually. */
- iterate_over_inferiors (mi_inferior_count, &count);
-
- if (count == 1)
- fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
- else
- iterate_over_threads (mi_output_running_pid, &ptid);
- }
else
- {
- struct thread_info *ti = find_thread_ptid (ptid);
-
- gdb_assert (ti);
- fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n",
- ti->global_num);
- }
+ for (thread_info *tp : all_non_exited_threads (ptid))
+ mi_output_running (tp);
if (!running_result_record_printed && mi_proceeded)
{
{
struct thread_info *tp = NULL;
- if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
+ if (ptid == minus_one_ptid || ptid.is_pid ())
tp = inferior_thread ();
else
tp = find_thread_ptid (ptid);
if (mi == NULL)
continue;
- uiout = interp_ui_out (top_level_interpreter ());
+ uiout = top_level_interpreter ()->interp_ui_out ();
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
if (mi == NULL)
continue;
- uiout = interp_ui_out (top_level_interpreter ());
+ uiout = top_level_interpreter ()->interp_ui_out ();
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
if (mi == NULL)
continue;
- mi_uiout = interp_ui_out (top_level_interpreter ());
+ mi_uiout = top_level_interpreter ()->interp_ui_out ();
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
if (mi == NULL)
continue;
- mi_uiout = interp_ui_out (top_level_interpreter ());
+ mi_uiout = top_level_interpreter ()->interp_ui_out ();
target_terminal::scoped_restore_terminal_state term_state;
target_terminal::ours_for_output ();
if (mi_suppress_notification.user_selected_context)
return;
- tp = find_thread_ptid (inferior_ptid);
+ if (inferior_ptid != null_ptid)
+ tp = inferior_thread ();
+ else
+ tp = NULL;
SWITCH_THRU_ALL_UIS ()
{
if (mi == NULL)
continue;
- mi_uiout = interp_ui_out (top_level_interpreter ());
+ mi_uiout = top_level_interpreter ()->interp_ui_out ();
mi_uiout->redirect (mi->event_channel);
ui_out_redirect_pop redirect_popper (mi_uiout);