aboutsummaryrefslogtreecommitdiff
path: root/gdb/mi/mi-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/mi/mi-main.c')
-rw-r--r--gdb/mi/mi-main.c77
1 files changed, 55 insertions, 22 deletions
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 1913157..7cd9706 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -53,6 +53,7 @@
#include "linespec.h"
#include "extension.h"
#include "gdbcmd.h"
+#include "observer.h"
#include <ctype.h>
#include "gdb_sys_time.h"
@@ -564,17 +565,29 @@ mi_cmd_thread_select (char *command, char **argv, int argc)
{
enum gdb_rc rc;
char *mi_error_message;
+ ptid_t previous_ptid = inferior_ptid;
if (argc != 1)
error (_("-thread-select: USAGE: threadnum."));
rc = gdb_thread_select (current_uiout, argv[0], &mi_error_message);
+ /* If thread switch did not succeed don't notify or print. */
if (rc == GDB_RC_FAIL)
{
make_cleanup (xfree, mi_error_message);
error ("%s", mi_error_message);
}
+
+ print_selected_thread_frame (current_uiout,
+ USER_SELECTED_THREAD | USER_SELECTED_FRAME);
+
+ /* Notify if the thread has effectively changed. */
+ if (!ptid_equal (inferior_ptid, previous_ptid))
+ {
+ observer_notify_user_selected_context_changed (USER_SELECTED_THREAD
+ | USER_SELECTED_FRAME);
+ }
}
void
@@ -2097,6 +2110,34 @@ mi_print_exception (const char *token, struct gdb_exception exception)
fputs_unfiltered ("\n", mi->raw_stdout);
}
+/* Determine whether the parsed command already notifies the
+ user_selected_context_changed observer. */
+
+static int
+command_notifies_uscc_observer (struct mi_parse *command)
+{
+ if (command->op == CLI_COMMAND)
+ {
+ /* CLI commands "thread" and "inferior" already send it. */
+ return (strncmp (command->command, "thread ", 7) == 0
+ || strncmp (command->command, "inferior ", 9) == 0);
+ }
+ else /* MI_COMMAND */
+ {
+ if (strcmp (command->command, "interpreter-exec") == 0
+ && command->argc > 1)
+ {
+ /* "thread" and "inferior" again, but through -interpreter-exec. */
+ return (strncmp (command->argv[1], "thread ", 7) == 0
+ || strncmp (command->argv[1], "inferior ", 9) == 0);
+ }
+
+ else
+ /* -thread-select already sends it. */
+ return strcmp (command->command, "thread-select") == 0;
+ }
+}
+
void
mi_execute_command (const char *cmd, int from_tty)
{
@@ -2124,9 +2165,16 @@ mi_execute_command (const char *cmd, int from_tty)
if (command != NULL)
{
ptid_t previous_ptid = inferior_ptid;
+ struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
command->token = token;
+ if (command->cmd != NULL && command->cmd->suppress_notification != NULL)
+ {
+ make_cleanup_restore_integer (command->cmd->suppress_notification);
+ *command->cmd->suppress_notification = 1;
+ }
+
if (do_timings)
{
command->cmd_start = XNEW (struct mi_timestamp);
@@ -2161,10 +2209,9 @@ mi_execute_command (const char *cmd, int from_tty)
/* Don't try report anything if there are no threads --
the program is dead. */
&& thread_count () != 0
- /* -thread-select explicitly changes thread. If frontend uses that
- internally, we don't want to emit =thread-selected, since
- =thread-selected is supposed to indicate user's intentions. */
- && strcmp (command->command, "thread-select") != 0)
+ /* If the command already reports the thread change, no need to do it
+ again. */
+ && !command_notifies_uscc_observer (command))
{
struct mi_interp *mi
= (struct mi_interp *) top_level_interpreter_data ();
@@ -2185,22 +2232,14 @@ mi_execute_command (const char *cmd, int from_tty)
if (report_change)
{
- struct thread_info *ti = inferior_thread ();
- struct cleanup *old_chain;
-
- old_chain = make_cleanup_restore_target_terminal ();
- target_terminal_ours_for_output ();
-
- fprintf_unfiltered (mi->event_channel,
- "thread-selected,id=\"%d\"",
- ti->global_num);
- gdb_flush (mi->event_channel);
-
- do_cleanups (old_chain);
+ observer_notify_user_selected_context_changed
+ (USER_SELECTED_THREAD | USER_SELECTED_FRAME);
}
}
mi_parse_free (command);
+
+ do_cleanups (cleanup);
}
}
@@ -2277,12 +2316,6 @@ mi_cmd_execute (struct mi_parse *parse)
current_context = parse;
- if (parse->cmd->suppress_notification != NULL)
- {
- make_cleanup_restore_integer (parse->cmd->suppress_notification);
- *parse->cmd->suppress_notification = 1;
- }
-
if (parse->cmd->argv_func != NULL)
{
parse->cmd->argv_func (parse->command, parse->argv, parse->argc);