15796c8dcSSimon Schubert /* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
25796c8dcSSimon Schubert
3a45ae5f8SJohn Marino Copyright (C) 2002-2013 Free Software Foundation, Inc.
45796c8dcSSimon Schubert
55796c8dcSSimon Schubert This file is part of GDB.
65796c8dcSSimon Schubert
75796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify
85796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by
95796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or
105796c8dcSSimon Schubert (at your option) any later version.
115796c8dcSSimon Schubert
125796c8dcSSimon Schubert This program is distributed in the hope that it will be useful,
135796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of
145796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
155796c8dcSSimon Schubert GNU General Public License for more details.
165796c8dcSSimon Schubert
175796c8dcSSimon Schubert You should have received a copy of the GNU General Public License
185796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */
195796c8dcSSimon Schubert
205796c8dcSSimon Schubert #include "defs.h"
215796c8dcSSimon Schubert #include "gdb_string.h"
225796c8dcSSimon Schubert #include "interps.h"
235796c8dcSSimon Schubert #include "event-top.h"
245796c8dcSSimon Schubert #include "event-loop.h"
255796c8dcSSimon Schubert #include "inferior.h"
265796c8dcSSimon Schubert #include "ui-out.h"
275796c8dcSSimon Schubert #include "top.h"
285796c8dcSSimon Schubert #include "exceptions.h"
295796c8dcSSimon Schubert #include "mi-main.h"
305796c8dcSSimon Schubert #include "mi-cmds.h"
315796c8dcSSimon Schubert #include "mi-out.h"
325796c8dcSSimon Schubert #include "mi-console.h"
335796c8dcSSimon Schubert #include "mi-common.h"
345796c8dcSSimon Schubert #include "observer.h"
355796c8dcSSimon Schubert #include "gdbthread.h"
365796c8dcSSimon Schubert #include "solist.h"
37a45ae5f8SJohn Marino #include "gdb.h"
385796c8dcSSimon Schubert #include "objfiles.h"
395796c8dcSSimon Schubert #include "tracepoint.h"
405796c8dcSSimon Schubert
415796c8dcSSimon Schubert /* These are the interpreter setup, etc. functions for the MI
425796c8dcSSimon Schubert interpreter. */
435796c8dcSSimon Schubert
445796c8dcSSimon Schubert static void mi_execute_command_wrapper (const char *cmd);
455796c8dcSSimon Schubert static void mi_execute_command_input_handler (char *cmd);
465796c8dcSSimon Schubert static void mi_command_loop (int mi_version);
47cf7f2e2dSJohn Marino
485796c8dcSSimon Schubert /* These are hooks that we put in place while doing interpreter_exec
495796c8dcSSimon Schubert so we can report interesting things that happened "behind the MI's
505796c8dcSSimon Schubert back" in this command. */
515796c8dcSSimon Schubert
525796c8dcSSimon Schubert static int mi_interp_query_hook (const char *ctlstr, va_list ap)
535796c8dcSSimon Schubert ATTRIBUTE_PRINTF (1, 0);
545796c8dcSSimon Schubert
555796c8dcSSimon Schubert static void mi3_command_loop (void);
565796c8dcSSimon Schubert static void mi2_command_loop (void);
575796c8dcSSimon Schubert static void mi1_command_loop (void);
585796c8dcSSimon Schubert
59cf7f2e2dSJohn Marino static void mi_insert_notify_hooks (void);
60cf7f2e2dSJohn Marino static void mi_remove_notify_hooks (void);
61cf7f2e2dSJohn Marino static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
62cf7f2e2dSJohn Marino
635796c8dcSSimon Schubert static void mi_new_thread (struct thread_info *t);
645796c8dcSSimon Schubert static void mi_thread_exit (struct thread_info *t, int silent);
655796c8dcSSimon Schubert static void mi_record_changed (struct inferior*, int);
665796c8dcSSimon Schubert static void mi_inferior_added (struct inferior *inf);
67a45ae5f8SJohn Marino static void mi_inferior_appeared (struct inferior *inf);
68a45ae5f8SJohn Marino static void mi_inferior_exit (struct inferior *inf);
69a45ae5f8SJohn Marino static void mi_inferior_removed (struct inferior *inf);
705796c8dcSSimon Schubert static void mi_on_resume (ptid_t ptid);
71cf7f2e2dSJohn Marino static void mi_solib_loaded (struct so_list *solib);
72cf7f2e2dSJohn Marino static void mi_solib_unloaded (struct so_list *solib);
735796c8dcSSimon Schubert static void mi_about_to_proceed (void);
74a45ae5f8SJohn Marino static void mi_traceframe_changed (int tfnum, int tpnum);
755796c8dcSSimon Schubert static void mi_tsv_created (const struct trace_state_variable *tsv);
765796c8dcSSimon Schubert static void mi_tsv_deleted (const struct trace_state_variable *tsv);
77a45ae5f8SJohn Marino static void mi_tsv_modified (const struct trace_state_variable *tsv);
78a45ae5f8SJohn Marino static void mi_breakpoint_created (struct breakpoint *b);
795796c8dcSSimon Schubert static void mi_breakpoint_deleted (struct breakpoint *b);
805796c8dcSSimon Schubert static void mi_breakpoint_modified (struct breakpoint *b);
815796c8dcSSimon Schubert static void mi_command_param_changed (const char *param, const char *value);
825796c8dcSSimon Schubert static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
835796c8dcSSimon Schubert ssize_t len, const bfd_byte *myaddr);
845796c8dcSSimon Schubert
855796c8dcSSimon Schubert static int report_initial_inferior (struct inferior *inf, void *closure);
865796c8dcSSimon Schubert
875796c8dcSSimon Schubert static void *
mi_interpreter_init(struct interp * interp,int top_level)885796c8dcSSimon Schubert mi_interpreter_init (struct interp *interp, int top_level)
895796c8dcSSimon Schubert {
905796c8dcSSimon Schubert struct mi_interp *mi = XMALLOC (struct mi_interp);
915796c8dcSSimon Schubert const char *name;
925796c8dcSSimon Schubert int mi_version;
935796c8dcSSimon Schubert
94a45ae5f8SJohn Marino /* Assign the output channel created at startup to its own global,
95a45ae5f8SJohn Marino so that we can create a console channel that encapsulates and
96a45ae5f8SJohn Marino prefixes all gdb_output-type bits coming from the rest of the
97a45ae5f8SJohn Marino debugger. */
98a45ae5f8SJohn Marino
99a45ae5f8SJohn Marino raw_stdout = gdb_stdout;
100a45ae5f8SJohn Marino
101a45ae5f8SJohn Marino /* Create MI console channels, each with a different prefix so they
102a45ae5f8SJohn Marino can be distinguished. */
103a45ae5f8SJohn Marino mi->out = mi_console_file_new (raw_stdout, "~", '"');
104a45ae5f8SJohn Marino mi->err = mi_console_file_new (raw_stdout, "&", '"');
105a45ae5f8SJohn Marino mi->log = mi->err;
106a45ae5f8SJohn Marino mi->targ = mi_console_file_new (raw_stdout, "@", '"');
107a45ae5f8SJohn Marino mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
108a45ae5f8SJohn Marino
109a45ae5f8SJohn Marino name = interp_name (interp);
1105796c8dcSSimon Schubert /* INTERP_MI selects the most recent released version. "mi2" was
1115796c8dcSSimon Schubert released as part of GDB 6.0. */
1125796c8dcSSimon Schubert if (strcmp (name, INTERP_MI) == 0)
1135796c8dcSSimon Schubert mi_version = 2;
114cf7f2e2dSJohn Marino else if (strcmp (name, INTERP_MI1) == 0)
115cf7f2e2dSJohn Marino mi_version = 1;
1165796c8dcSSimon Schubert else if (strcmp (name, INTERP_MI2) == 0)
117cf7f2e2dSJohn Marino mi_version = 2;
1185796c8dcSSimon Schubert else if (strcmp (name, INTERP_MI3) == 0)
1195796c8dcSSimon Schubert mi_version = 3;
1205796c8dcSSimon Schubert else
1215796c8dcSSimon Schubert gdb_assert_not_reached ("unhandled MI version");
1225796c8dcSSimon Schubert
123a45ae5f8SJohn Marino mi->uiout = mi_out_new (mi_version);
124a45ae5f8SJohn Marino
125a45ae5f8SJohn Marino if (top_level)
126cf7f2e2dSJohn Marino {
127cf7f2e2dSJohn Marino observer_attach_new_thread (mi_new_thread);
128cf7f2e2dSJohn Marino observer_attach_thread_exit (mi_thread_exit);
129cf7f2e2dSJohn Marino observer_attach_inferior_added (mi_inferior_added);
130cf7f2e2dSJohn Marino observer_attach_inferior_appeared (mi_inferior_appeared);
1315796c8dcSSimon Schubert observer_attach_inferior_exit (mi_inferior_exit);
1325796c8dcSSimon Schubert observer_attach_inferior_removed (mi_inferior_removed);
1335796c8dcSSimon Schubert observer_attach_record_changed (mi_record_changed);
1345796c8dcSSimon Schubert observer_attach_normal_stop (mi_on_normal_stop);
1355796c8dcSSimon Schubert observer_attach_target_resumed (mi_on_resume);
1365796c8dcSSimon Schubert observer_attach_solib_loaded (mi_solib_loaded);
1375796c8dcSSimon Schubert observer_attach_solib_unloaded (mi_solib_unloaded);
1385796c8dcSSimon Schubert observer_attach_about_to_proceed (mi_about_to_proceed);
1395796c8dcSSimon Schubert observer_attach_traceframe_changed (mi_traceframe_changed);
1405796c8dcSSimon Schubert observer_attach_tsv_created (mi_tsv_created);
141cf7f2e2dSJohn Marino observer_attach_tsv_deleted (mi_tsv_deleted);
1425796c8dcSSimon Schubert observer_attach_tsv_modified (mi_tsv_modified);
1435796c8dcSSimon Schubert observer_attach_breakpoint_created (mi_breakpoint_created);
1445796c8dcSSimon Schubert observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
1455796c8dcSSimon Schubert observer_attach_breakpoint_modified (mi_breakpoint_modified);
1465796c8dcSSimon Schubert observer_attach_command_param_changed (mi_command_param_changed);
1475796c8dcSSimon Schubert observer_attach_memory_changed (mi_memory_changed);
1485796c8dcSSimon Schubert
1495796c8dcSSimon Schubert /* The initial inferior is created before this function is
1505796c8dcSSimon Schubert called, so we need to report it explicitly. Use iteration in
1515796c8dcSSimon Schubert case future version of GDB creates more than one inferior
1525796c8dcSSimon Schubert up-front. */
1535796c8dcSSimon Schubert iterate_over_inferiors (report_initial_inferior, mi);
1545796c8dcSSimon Schubert }
1555796c8dcSSimon Schubert
1565796c8dcSSimon Schubert return mi;
1575796c8dcSSimon Schubert }
1585796c8dcSSimon Schubert
1595796c8dcSSimon Schubert static int
mi_interpreter_resume(void * data)1605796c8dcSSimon Schubert mi_interpreter_resume (void *data)
1615796c8dcSSimon Schubert {
1625796c8dcSSimon Schubert struct mi_interp *mi = data;
1635796c8dcSSimon Schubert
1645796c8dcSSimon Schubert /* As per hack note in mi_interpreter_init, swap in the output
1655796c8dcSSimon Schubert channels... */
1665796c8dcSSimon Schubert gdb_setup_readline ();
1675796c8dcSSimon Schubert
1685796c8dcSSimon Schubert /* These overwrite some of the initialization done in
1695796c8dcSSimon Schubert _intialize_event_loop. */
1705796c8dcSSimon Schubert call_readline = gdb_readline2;
1715796c8dcSSimon Schubert input_handler = mi_execute_command_input_handler;
1725796c8dcSSimon Schubert add_file_handler (input_fd, stdin_event_handler, 0);
1735796c8dcSSimon Schubert async_command_editing_p = 0;
1745796c8dcSSimon Schubert /* FIXME: This is a total hack for now. PB's use of the MI
1755796c8dcSSimon Schubert implicitly relies on a bug in the async support which allows
1765796c8dcSSimon Schubert asynchronous commands to leak through the commmand loop. The bug
1775796c8dcSSimon Schubert involves (but is not limited to) the fact that sync_execution was
1785796c8dcSSimon Schubert erroneously initialized to 0. Duplicate by initializing it thus
1795796c8dcSSimon Schubert here... */
1805796c8dcSSimon Schubert sync_execution = 0;
1815796c8dcSSimon Schubert
1825796c8dcSSimon Schubert gdb_stdout = mi->out;
1835796c8dcSSimon Schubert /* Route error and log output through the MI. */
1845796c8dcSSimon Schubert gdb_stderr = mi->err;
1855796c8dcSSimon Schubert gdb_stdlog = mi->log;
1865796c8dcSSimon Schubert /* Route target output through the MI. */
1875796c8dcSSimon Schubert gdb_stdtarg = mi->targ;
1885796c8dcSSimon Schubert /* Route target error through the MI as well. */
1895796c8dcSSimon Schubert gdb_stdtargerr = mi->targ;
1905796c8dcSSimon Schubert
1915796c8dcSSimon Schubert /* Replace all the hooks that we know about. There really needs to
1925796c8dcSSimon Schubert be a better way of doing this... */
1935796c8dcSSimon Schubert clear_interpreter_hooks ();
1945796c8dcSSimon Schubert
1955796c8dcSSimon Schubert deprecated_show_load_progress = mi_load_progress;
1965796c8dcSSimon Schubert
197cf7f2e2dSJohn Marino /* If we're _the_ interpreter, take control. */
1985796c8dcSSimon Schubert if (current_interp_named_p (INTERP_MI1))
1995796c8dcSSimon Schubert deprecated_command_loop_hook = mi1_command_loop;
2005796c8dcSSimon Schubert else if (current_interp_named_p (INTERP_MI2))
2015796c8dcSSimon Schubert deprecated_command_loop_hook = mi2_command_loop;
2025796c8dcSSimon Schubert else if (current_interp_named_p (INTERP_MI3))
2035796c8dcSSimon Schubert deprecated_command_loop_hook = mi3_command_loop;
2045796c8dcSSimon Schubert else
2055796c8dcSSimon Schubert deprecated_command_loop_hook = mi2_command_loop;
2065796c8dcSSimon Schubert
2075796c8dcSSimon Schubert return 1;
2085796c8dcSSimon Schubert }
2095796c8dcSSimon Schubert
2105796c8dcSSimon Schubert static int
mi_interpreter_suspend(void * data)2115796c8dcSSimon Schubert mi_interpreter_suspend (void *data)
2125796c8dcSSimon Schubert {
2135796c8dcSSimon Schubert gdb_disable_readline ();
2145796c8dcSSimon Schubert return 1;
2155796c8dcSSimon Schubert }
2165796c8dcSSimon Schubert
2175796c8dcSSimon Schubert static struct gdb_exception
mi_interpreter_exec(void * data,const char * command)2185796c8dcSSimon Schubert mi_interpreter_exec (void *data, const char *command)
219c50c785cSJohn Marino {
220c50c785cSJohn Marino mi_execute_command_wrapper (command);
2215796c8dcSSimon Schubert return exception_none;
2225796c8dcSSimon Schubert }
2235796c8dcSSimon Schubert
224c50c785cSJohn Marino /* Never display the default GDB prompt in MI case. */
225c50c785cSJohn Marino
2265796c8dcSSimon Schubert static int
mi_interpreter_prompt_p(void * data)2275796c8dcSSimon Schubert mi_interpreter_prompt_p (void *data)
228c50c785cSJohn Marino {
229c50c785cSJohn Marino return 0;
2305796c8dcSSimon Schubert }
2315796c8dcSSimon Schubert
2325796c8dcSSimon Schubert void
mi_cmd_interpreter_exec(char * command,char ** argv,int argc)2335796c8dcSSimon Schubert mi_cmd_interpreter_exec (char *command, char **argv, int argc)
2345796c8dcSSimon Schubert {
2355796c8dcSSimon Schubert struct interp *interp_to_use;
2365796c8dcSSimon Schubert int i;
2375796c8dcSSimon Schubert char *mi_error_message = NULL;
2385796c8dcSSimon Schubert struct cleanup *old_chain;
2395796c8dcSSimon Schubert
2405796c8dcSSimon Schubert if (argc < 2)
2415796c8dcSSimon Schubert error (_("-interpreter-exec: "
2425796c8dcSSimon Schubert "Usage: -interpreter-exec interp command"));
2435796c8dcSSimon Schubert
244cf7f2e2dSJohn Marino interp_to_use = interp_lookup (argv[0]);
2455796c8dcSSimon Schubert if (interp_to_use == NULL)
2465796c8dcSSimon Schubert error (_("-interpreter-exec: could not find interpreter \"%s\""),
2475796c8dcSSimon Schubert argv[0]);
2485796c8dcSSimon Schubert
2495796c8dcSSimon Schubert if (!interp_exec_p (interp_to_use))
2505796c8dcSSimon Schubert error (_("-interpreter-exec: interpreter \"%s\" "
2515796c8dcSSimon Schubert "does not support command execution"),
2525796c8dcSSimon Schubert argv[0]);
2535796c8dcSSimon Schubert
2545796c8dcSSimon Schubert /* Insert the MI out hooks, making sure to also call the
2555796c8dcSSimon Schubert interpreter's hooks if it has any. */
2565796c8dcSSimon Schubert /* KRS: We shouldn't need this... Events should be installed and
2575796c8dcSSimon Schubert they should just ALWAYS fire something out down the MI
2585796c8dcSSimon Schubert channel. */
2595796c8dcSSimon Schubert mi_insert_notify_hooks ();
2605796c8dcSSimon Schubert
261c50c785cSJohn Marino /* Now run the code. */
262c50c785cSJohn Marino
263c50c785cSJohn Marino old_chain = make_cleanup (null_cleanup, 0);
264c50c785cSJohn Marino for (i = 1; i < argc; i++)
265c50c785cSJohn Marino {
266c50c785cSJohn Marino struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
2675796c8dcSSimon Schubert
2685796c8dcSSimon Schubert if (e.reason < 0)
2695796c8dcSSimon Schubert {
2705796c8dcSSimon Schubert mi_error_message = xstrdup (e.message);
2715796c8dcSSimon Schubert make_cleanup (xfree, mi_error_message);
2725796c8dcSSimon Schubert break;
2735796c8dcSSimon Schubert }
2745796c8dcSSimon Schubert }
2755796c8dcSSimon Schubert
2765796c8dcSSimon Schubert mi_remove_notify_hooks ();
2775796c8dcSSimon Schubert
2785796c8dcSSimon Schubert if (mi_error_message != NULL)
2795796c8dcSSimon Schubert error ("%s", mi_error_message);
2805796c8dcSSimon Schubert do_cleanups (old_chain);
2815796c8dcSSimon Schubert }
2825796c8dcSSimon Schubert
2835796c8dcSSimon Schubert /* This inserts a number of hooks that are meant to produce
2845796c8dcSSimon Schubert async-notify ("=") MI messages while running commands in another
2855796c8dcSSimon Schubert interpreter using mi_interpreter_exec. The canonical use for this
2865796c8dcSSimon Schubert is to allow access to the gdb CLI interpreter from within the MI,
2875796c8dcSSimon Schubert while still producing MI style output when actions in the CLI
2885796c8dcSSimon Schubert command change GDB's state. */
2895796c8dcSSimon Schubert
2905796c8dcSSimon Schubert static void
mi_insert_notify_hooks(void)2915796c8dcSSimon Schubert mi_insert_notify_hooks (void)
2925796c8dcSSimon Schubert {
2935796c8dcSSimon Schubert deprecated_query_hook = mi_interp_query_hook;
2945796c8dcSSimon Schubert }
2955796c8dcSSimon Schubert
2965796c8dcSSimon Schubert static void
mi_remove_notify_hooks(void)2975796c8dcSSimon Schubert mi_remove_notify_hooks (void)
2985796c8dcSSimon Schubert {
2995796c8dcSSimon Schubert deprecated_query_hook = NULL;
3005796c8dcSSimon Schubert }
3015796c8dcSSimon Schubert
3025796c8dcSSimon Schubert static int
mi_interp_query_hook(const char * ctlstr,va_list ap)3035796c8dcSSimon Schubert mi_interp_query_hook (const char *ctlstr, va_list ap)
3045796c8dcSSimon Schubert {
3055796c8dcSSimon Schubert return 1;
3065796c8dcSSimon Schubert }
3075796c8dcSSimon Schubert
3085796c8dcSSimon Schubert static void
mi_execute_command_wrapper(const char * cmd)3095796c8dcSSimon Schubert mi_execute_command_wrapper (const char *cmd)
3105796c8dcSSimon Schubert {
3115796c8dcSSimon Schubert mi_execute_command (cmd, stdin == instream);
3125796c8dcSSimon Schubert }
3135796c8dcSSimon Schubert
3145796c8dcSSimon Schubert /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
3155796c8dcSSimon Schubert
3165796c8dcSSimon Schubert static void
mi_execute_command_input_handler(char * cmd)3175796c8dcSSimon Schubert mi_execute_command_input_handler (char *cmd)
3185796c8dcSSimon Schubert {
3195796c8dcSSimon Schubert mi_execute_command_wrapper (cmd);
3205796c8dcSSimon Schubert
3215796c8dcSSimon Schubert fputs_unfiltered ("(gdb) \n", raw_stdout);
3225796c8dcSSimon Schubert gdb_flush (raw_stdout);
3235796c8dcSSimon Schubert }
3245796c8dcSSimon Schubert
3255796c8dcSSimon Schubert static void
mi1_command_loop(void)3265796c8dcSSimon Schubert mi1_command_loop (void)
327cf7f2e2dSJohn Marino {
328cf7f2e2dSJohn Marino mi_command_loop (1);
329cf7f2e2dSJohn Marino }
3305796c8dcSSimon Schubert
3315796c8dcSSimon Schubert static void
mi2_command_loop(void)332cf7f2e2dSJohn Marino mi2_command_loop (void)
333cf7f2e2dSJohn Marino {
3345796c8dcSSimon Schubert mi_command_loop (2);
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert
3375796c8dcSSimon Schubert static void
mi3_command_loop(void)3385796c8dcSSimon Schubert mi3_command_loop (void)
3395796c8dcSSimon Schubert {
3405796c8dcSSimon Schubert mi_command_loop (3);
341cf7f2e2dSJohn Marino }
3425796c8dcSSimon Schubert
3435796c8dcSSimon Schubert static void
mi_command_loop(int mi_version)3445796c8dcSSimon Schubert mi_command_loop (int mi_version)
3455796c8dcSSimon Schubert {
346cf7f2e2dSJohn Marino /* Turn off 8 bit strings in quoted output. Any character with the
347cf7f2e2dSJohn Marino high bit set is printed using C's octal format. */
3485796c8dcSSimon Schubert sevenbit_strings = 1;
3495796c8dcSSimon Schubert
3505796c8dcSSimon Schubert /* Tell the world that we're alive. */
351cf7f2e2dSJohn Marino fputs_unfiltered ("(gdb) \n", raw_stdout);
352cf7f2e2dSJohn Marino gdb_flush (raw_stdout);
3535796c8dcSSimon Schubert
3545796c8dcSSimon Schubert start_event_loop ();
3555796c8dcSSimon Schubert }
3565796c8dcSSimon Schubert
357cf7f2e2dSJohn Marino static void
mi_new_thread(struct thread_info * t)3585796c8dcSSimon Schubert mi_new_thread (struct thread_info *t)
3595796c8dcSSimon Schubert {
360cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
3615796c8dcSSimon Schubert struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid));
362cf7f2e2dSJohn Marino
363cf7f2e2dSJohn Marino gdb_assert (inf);
364cf7f2e2dSJohn Marino
3655796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
3665796c8dcSSimon Schubert "thread-created,id=\"%d\",group-id=\"i%d\"",
3675796c8dcSSimon Schubert t->num, inf->num);
3685796c8dcSSimon Schubert gdb_flush (mi->event_channel);
369cf7f2e2dSJohn Marino }
3705796c8dcSSimon Schubert
3715796c8dcSSimon Schubert static void
mi_thread_exit(struct thread_info * t,int silent)372cf7f2e2dSJohn Marino mi_thread_exit (struct thread_info *t, int silent)
3735796c8dcSSimon Schubert {
374cf7f2e2dSJohn Marino struct mi_interp *mi;
375cf7f2e2dSJohn Marino struct inferior *inf;
376cf7f2e2dSJohn Marino
377cf7f2e2dSJohn Marino if (silent)
378cf7f2e2dSJohn Marino return;
379cf7f2e2dSJohn Marino
380cf7f2e2dSJohn Marino inf = find_inferior_pid (ptid_get_pid (t->ptid));
381cf7f2e2dSJohn Marino
382cf7f2e2dSJohn Marino mi = top_level_interpreter_data ();
383cf7f2e2dSJohn Marino target_terminal_ours ();
384cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
385cf7f2e2dSJohn Marino "thread-exited,id=\"%d\",group-id=\"i%d\"",
386c50c785cSJohn Marino t->num, inf->num);
387c50c785cSJohn Marino gdb_flush (mi->event_channel);
388c50c785cSJohn Marino }
389c50c785cSJohn Marino
390c50c785cSJohn Marino /* Emit notification on changing the state of record. */
391c50c785cSJohn Marino
392c50c785cSJohn Marino static void
mi_record_changed(struct inferior * inferior,int started)393c50c785cSJohn Marino mi_record_changed (struct inferior *inferior, int started)
394cf7f2e2dSJohn Marino {
395cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
396cf7f2e2dSJohn Marino
397cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel, "record-%s,thread-group=\"i%d\"",
398cf7f2e2dSJohn Marino started ? "started" : "stopped", inferior->num);
399cf7f2e2dSJohn Marino
400cf7f2e2dSJohn Marino gdb_flush (mi->event_channel);
401cf7f2e2dSJohn Marino }
402cf7f2e2dSJohn Marino
403cf7f2e2dSJohn Marino static void
mi_inferior_added(struct inferior * inf)404cf7f2e2dSJohn Marino mi_inferior_added (struct inferior *inf)
405cf7f2e2dSJohn Marino {
4065796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
4075796c8dcSSimon Schubert
4085796c8dcSSimon Schubert target_terminal_ours ();
4095796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
4105796c8dcSSimon Schubert "thread-group-added,id=\"i%d\"",
4115796c8dcSSimon Schubert inf->num);
4125796c8dcSSimon Schubert gdb_flush (mi->event_channel);
4135796c8dcSSimon Schubert }
4145796c8dcSSimon Schubert
4155796c8dcSSimon Schubert static void
mi_inferior_appeared(struct inferior * inf)4165796c8dcSSimon Schubert mi_inferior_appeared (struct inferior *inf)
4175796c8dcSSimon Schubert {
4185796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
419cf7f2e2dSJohn Marino
420cf7f2e2dSJohn Marino target_terminal_ours ();
421a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel,
4225796c8dcSSimon Schubert "thread-group-started,id=\"i%d\",pid=\"%d\"",
4235796c8dcSSimon Schubert inf->num, inf->pid);
4245796c8dcSSimon Schubert gdb_flush (mi->event_channel);
4255796c8dcSSimon Schubert }
4265796c8dcSSimon Schubert
4275796c8dcSSimon Schubert static void
mi_inferior_exit(struct inferior * inf)428a45ae5f8SJohn Marino mi_inferior_exit (struct inferior *inf)
429a45ae5f8SJohn Marino {
430a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
431cf7f2e2dSJohn Marino
432a45ae5f8SJohn Marino target_terminal_ours ();
433a45ae5f8SJohn Marino if (inf->has_exit_code)
434a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel,
435a45ae5f8SJohn Marino "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
436a45ae5f8SJohn Marino inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
4375796c8dcSSimon Schubert else
438a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel,
4395796c8dcSSimon Schubert "thread-group-exited,id=\"i%d\"", inf->num);
4405796c8dcSSimon Schubert
4415796c8dcSSimon Schubert gdb_flush (mi->event_channel);
4425796c8dcSSimon Schubert }
4435796c8dcSSimon Schubert
4445796c8dcSSimon Schubert static void
mi_inferior_removed(struct inferior * inf)4455796c8dcSSimon Schubert mi_inferior_removed (struct inferior *inf)
4465796c8dcSSimon Schubert {
447cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
4485796c8dcSSimon Schubert
4495796c8dcSSimon Schubert target_terminal_ours ();
4505796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
4515796c8dcSSimon Schubert "thread-group-removed,id=\"i%d\"",
4525796c8dcSSimon Schubert inf->num);
4535796c8dcSSimon Schubert gdb_flush (mi->event_channel);
454cf7f2e2dSJohn Marino }
455cf7f2e2dSJohn Marino
456cf7f2e2dSJohn Marino static void
mi_on_normal_stop(struct bpstats * bs,int print_frame)457cf7f2e2dSJohn Marino mi_on_normal_stop (struct bpstats *bs, int print_frame)
4585796c8dcSSimon Schubert {
4595796c8dcSSimon Schubert /* Since this can be called when CLI command is executing,
4605796c8dcSSimon Schubert using cli interpreter, be sure to use MI uiout for output,
4615796c8dcSSimon Schubert not the current one. */
4625796c8dcSSimon Schubert struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
4635796c8dcSSimon Schubert
4645796c8dcSSimon Schubert if (print_frame)
4655796c8dcSSimon Schubert {
4665796c8dcSSimon Schubert int core;
4675796c8dcSSimon Schubert
4685796c8dcSSimon Schubert if (current_uiout != mi_uiout)
4695796c8dcSSimon Schubert {
4705796c8dcSSimon Schubert /* The normal_stop function has printed frame information
4715796c8dcSSimon Schubert into CLI uiout, or some other non-MI uiout. There's no
4725796c8dcSSimon Schubert way we can extract proper fields from random uiout
4735796c8dcSSimon Schubert object, so we print the frame again. In practice, this
4745796c8dcSSimon Schubert can only happen when running a CLI command in MI. */
4755796c8dcSSimon Schubert struct ui_out *saved_uiout = current_uiout;
476cf7f2e2dSJohn Marino struct target_waitstatus last;
477c50c785cSJohn Marino ptid_t last_ptid;
4785796c8dcSSimon Schubert
4795796c8dcSSimon Schubert current_uiout = mi_uiout;
4805796c8dcSSimon Schubert
4815796c8dcSSimon Schubert get_last_target_status (&last_ptid, &last);
4825796c8dcSSimon Schubert bpstat_print (bs, last.kind);
4835796c8dcSSimon Schubert
484a45ae5f8SJohn Marino print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC);
485a45ae5f8SJohn Marino current_uiout = saved_uiout;
486a45ae5f8SJohn Marino }
487a45ae5f8SJohn Marino
488a45ae5f8SJohn Marino ui_out_field_int (mi_uiout, "thread-id",
489a45ae5f8SJohn Marino pid_to_thread_id (inferior_ptid));
490a45ae5f8SJohn Marino if (non_stop)
491a45ae5f8SJohn Marino {
492a45ae5f8SJohn Marino struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
493a45ae5f8SJohn Marino (mi_uiout, "stopped-threads");
494a45ae5f8SJohn Marino
495a45ae5f8SJohn Marino ui_out_field_int (mi_uiout, NULL,
496a45ae5f8SJohn Marino pid_to_thread_id (inferior_ptid));
497a45ae5f8SJohn Marino do_cleanups (back_to);
498a45ae5f8SJohn Marino }
499a45ae5f8SJohn Marino else
500a45ae5f8SJohn Marino ui_out_field_string (mi_uiout, "stopped-threads", "all");
501a45ae5f8SJohn Marino
502a45ae5f8SJohn Marino core = target_core_of_thread (inferior_ptid);
503a45ae5f8SJohn Marino if (core != -1)
504a45ae5f8SJohn Marino ui_out_field_int (mi_uiout, "core", core);
505a45ae5f8SJohn Marino }
506a45ae5f8SJohn Marino
507a45ae5f8SJohn Marino fputs_unfiltered ("*stopped", raw_stdout);
508a45ae5f8SJohn Marino mi_out_put (mi_uiout, raw_stdout);
509a45ae5f8SJohn Marino mi_out_rewind (mi_uiout);
510a45ae5f8SJohn Marino mi_print_timing_maybe ();
511a45ae5f8SJohn Marino fputs_unfiltered ("\n", raw_stdout);
512a45ae5f8SJohn Marino gdb_flush (raw_stdout);
513a45ae5f8SJohn Marino }
514a45ae5f8SJohn Marino
515a45ae5f8SJohn Marino static void
mi_about_to_proceed(void)516a45ae5f8SJohn Marino mi_about_to_proceed (void)
517a45ae5f8SJohn Marino {
518a45ae5f8SJohn Marino /* Suppress output while calling an inferior function. */
519a45ae5f8SJohn Marino
520a45ae5f8SJohn Marino if (!ptid_equal (inferior_ptid, null_ptid))
521a45ae5f8SJohn Marino {
522a45ae5f8SJohn Marino struct thread_info *tp = inferior_thread ();
523a45ae5f8SJohn Marino
524a45ae5f8SJohn Marino if (tp->control.in_infcall)
525a45ae5f8SJohn Marino return;
526a45ae5f8SJohn Marino }
527a45ae5f8SJohn Marino
528a45ae5f8SJohn Marino mi_proceeded = 1;
529a45ae5f8SJohn Marino }
530a45ae5f8SJohn Marino
531a45ae5f8SJohn Marino /* When the element is non-zero, no MI notifications will be emitted in
532a45ae5f8SJohn Marino response to the corresponding observers. */
533a45ae5f8SJohn Marino
534a45ae5f8SJohn Marino struct mi_suppress_notification mi_suppress_notification =
535a45ae5f8SJohn Marino {
536a45ae5f8SJohn Marino 0,
537a45ae5f8SJohn Marino 0,
538a45ae5f8SJohn Marino 0,
539a45ae5f8SJohn Marino };
540a45ae5f8SJohn Marino
541a45ae5f8SJohn Marino /* Emit notification on changing a traceframe. */
542a45ae5f8SJohn Marino
543a45ae5f8SJohn Marino static void
mi_traceframe_changed(int tfnum,int tpnum)544a45ae5f8SJohn Marino mi_traceframe_changed (int tfnum, int tpnum)
545a45ae5f8SJohn Marino {
546a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
547a45ae5f8SJohn Marino
548a45ae5f8SJohn Marino if (mi_suppress_notification.traceframe)
549a45ae5f8SJohn Marino return;
550a45ae5f8SJohn Marino
551a45ae5f8SJohn Marino target_terminal_ours ();
552a45ae5f8SJohn Marino
553a45ae5f8SJohn Marino if (tfnum >= 0)
554a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
555a45ae5f8SJohn Marino "num=\"%d\",tracepoint=\"%d\"\n",
556a45ae5f8SJohn Marino tfnum, tpnum);
557a45ae5f8SJohn Marino else
558a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
559a45ae5f8SJohn Marino
560a45ae5f8SJohn Marino gdb_flush (mi->event_channel);
561a45ae5f8SJohn Marino }
562a45ae5f8SJohn Marino
563a45ae5f8SJohn Marino /* Emit notification on creating a trace state variable. */
564a45ae5f8SJohn Marino
565a45ae5f8SJohn Marino static void
mi_tsv_created(const struct trace_state_variable * tsv)566a45ae5f8SJohn Marino mi_tsv_created (const struct trace_state_variable *tsv)
567a45ae5f8SJohn Marino {
568a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
569a45ae5f8SJohn Marino
570a45ae5f8SJohn Marino target_terminal_ours ();
571a45ae5f8SJohn Marino
572a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel, "tsv-created,"
5735796c8dcSSimon Schubert "name=\"%s\",initial=\"%s\"\n",
5745796c8dcSSimon Schubert tsv->name, plongest (tsv->initial_value));
5755796c8dcSSimon Schubert
5765796c8dcSSimon Schubert gdb_flush (mi->event_channel);
5775796c8dcSSimon Schubert }
5785796c8dcSSimon Schubert
5795796c8dcSSimon Schubert /* Emit notification on deleting a trace state variable. */
5805796c8dcSSimon Schubert
5815796c8dcSSimon Schubert static void
mi_tsv_deleted(const struct trace_state_variable * tsv)5825796c8dcSSimon Schubert mi_tsv_deleted (const struct trace_state_variable *tsv)
5835796c8dcSSimon Schubert {
5845796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
5855796c8dcSSimon Schubert
5865796c8dcSSimon Schubert target_terminal_ours ();
5875796c8dcSSimon Schubert
5885796c8dcSSimon Schubert if (tsv != NULL)
589*74a8b0f5SJohn Marino fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
5905796c8dcSSimon Schubert "name=\"%s\"\n", tsv->name);
5915796c8dcSSimon Schubert else
5925796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
5935796c8dcSSimon Schubert
5945796c8dcSSimon Schubert gdb_flush (mi->event_channel);
5955796c8dcSSimon Schubert }
5965796c8dcSSimon Schubert
5975796c8dcSSimon Schubert /* Emit notification on modifying a trace state variable. */
5985796c8dcSSimon Schubert
5995796c8dcSSimon Schubert static void
mi_tsv_modified(const struct trace_state_variable * tsv)6005796c8dcSSimon Schubert mi_tsv_modified (const struct trace_state_variable *tsv)
6015796c8dcSSimon Schubert {
6025796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
6035796c8dcSSimon Schubert struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
6045796c8dcSSimon Schubert
6055796c8dcSSimon Schubert target_terminal_ours ();
6065796c8dcSSimon Schubert
6075796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
6085796c8dcSSimon Schubert "tsv-modified");
609c50c785cSJohn Marino
6105796c8dcSSimon Schubert ui_out_redirect (mi_uiout, mi->event_channel);
6115796c8dcSSimon Schubert
6125796c8dcSSimon Schubert ui_out_field_string (mi_uiout, "name", tsv->name);
6135796c8dcSSimon Schubert ui_out_field_string (mi_uiout, "initial",
6145796c8dcSSimon Schubert plongest (tsv->initial_value));
6155796c8dcSSimon Schubert if (tsv->value_known)
6165796c8dcSSimon Schubert ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
6175796c8dcSSimon Schubert
6185796c8dcSSimon Schubert ui_out_redirect (mi_uiout, NULL);
6195796c8dcSSimon Schubert
6205796c8dcSSimon Schubert gdb_flush (mi->event_channel);
6215796c8dcSSimon Schubert }
622cf7f2e2dSJohn Marino
623cf7f2e2dSJohn Marino /* Emit notification about a created breakpoint. */
6245796c8dcSSimon Schubert
6255796c8dcSSimon Schubert static void
mi_breakpoint_created(struct breakpoint * b)6265796c8dcSSimon Schubert mi_breakpoint_created (struct breakpoint *b)
6275796c8dcSSimon Schubert {
6285796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
6295796c8dcSSimon Schubert struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
6305796c8dcSSimon Schubert volatile struct gdb_exception e;
6315796c8dcSSimon Schubert
6325796c8dcSSimon Schubert if (mi_suppress_notification.breakpoint)
6335796c8dcSSimon Schubert return;
6345796c8dcSSimon Schubert
6355796c8dcSSimon Schubert if (b->number <= 0)
6365796c8dcSSimon Schubert return;
6375796c8dcSSimon Schubert
6385796c8dcSSimon Schubert target_terminal_ours ();
6395796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
6405796c8dcSSimon Schubert "breakpoint-created");
6415796c8dcSSimon Schubert /* We want the output from gdb_breakpoint_query to go to
6425796c8dcSSimon Schubert mi->event_channel. One approach would be to just call
6435796c8dcSSimon Schubert gdb_breakpoint_query, and then use mi_out_put to send the current
6445796c8dcSSimon Schubert content of mi_outout into mi->event_channel. However, that will
645cf7f2e2dSJohn Marino break if anything is output to mi_uiout prior to calling the
6465796c8dcSSimon Schubert breakpoint_created notifications. So, we use
6475796c8dcSSimon Schubert ui_out_redirect. */
6485796c8dcSSimon Schubert ui_out_redirect (mi_uiout, mi->event_channel);
6495796c8dcSSimon Schubert TRY_CATCH (e, RETURN_MASK_ERROR)
6505796c8dcSSimon Schubert gdb_breakpoint_query (mi_uiout, b->number, NULL);
6515796c8dcSSimon Schubert ui_out_redirect (mi_uiout, NULL);
6525796c8dcSSimon Schubert
6535796c8dcSSimon Schubert gdb_flush (mi->event_channel);
6545796c8dcSSimon Schubert }
6555796c8dcSSimon Schubert
6565796c8dcSSimon Schubert /* Emit notification about deleted breakpoint. */
6575796c8dcSSimon Schubert
6585796c8dcSSimon Schubert static void
mi_breakpoint_deleted(struct breakpoint * b)6595796c8dcSSimon Schubert mi_breakpoint_deleted (struct breakpoint *b)
6605796c8dcSSimon Schubert {
6615796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
6625796c8dcSSimon Schubert
6635796c8dcSSimon Schubert if (mi_suppress_notification.breakpoint)
6645796c8dcSSimon Schubert return;
6655796c8dcSSimon Schubert
6665796c8dcSSimon Schubert if (b->number <= 0)
6675796c8dcSSimon Schubert return;
668cf7f2e2dSJohn Marino
6695796c8dcSSimon Schubert target_terminal_ours ();
670cf7f2e2dSJohn Marino
6715796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
672cf7f2e2dSJohn Marino b->number);
673cf7f2e2dSJohn Marino
6745796c8dcSSimon Schubert gdb_flush (mi->event_channel);
6755796c8dcSSimon Schubert }
676cf7f2e2dSJohn Marino
677cf7f2e2dSJohn Marino /* Emit notification about modified breakpoint. */
678cf7f2e2dSJohn Marino
679cf7f2e2dSJohn Marino static void
mi_breakpoint_modified(struct breakpoint * b)680cf7f2e2dSJohn Marino mi_breakpoint_modified (struct breakpoint *b)
681cf7f2e2dSJohn Marino {
682cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
683cf7f2e2dSJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
684cf7f2e2dSJohn Marino volatile struct gdb_exception e;
6855796c8dcSSimon Schubert
6865796c8dcSSimon Schubert if (mi_suppress_notification.breakpoint)
6875796c8dcSSimon Schubert return;
6885796c8dcSSimon Schubert
6895796c8dcSSimon Schubert if (b->number <= 0)
6905796c8dcSSimon Schubert return;
6915796c8dcSSimon Schubert
692cf7f2e2dSJohn Marino target_terminal_ours ();
6935796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
694cf7f2e2dSJohn Marino "breakpoint-modified");
6955796c8dcSSimon Schubert /* We want the output from gdb_breakpoint_query to go to
696cf7f2e2dSJohn Marino mi->event_channel. One approach would be to just call
697cf7f2e2dSJohn Marino gdb_breakpoint_query, and then use mi_out_put to send the current
6985796c8dcSSimon Schubert content of mi_outout into mi->event_channel. However, that will
6995796c8dcSSimon Schubert break if anything is output to mi_uiout prior to calling the
700cf7f2e2dSJohn Marino breakpoint_created notifications. So, we use
701cf7f2e2dSJohn Marino ui_out_redirect. */
702cf7f2e2dSJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
703cf7f2e2dSJohn Marino TRY_CATCH (e, RETURN_MASK_ERROR)
704cf7f2e2dSJohn Marino gdb_breakpoint_query (mi_uiout, b->number, NULL);
705cf7f2e2dSJohn Marino ui_out_redirect (mi_uiout, NULL);
706cf7f2e2dSJohn Marino
7075796c8dcSSimon Schubert gdb_flush (mi->event_channel);
7085796c8dcSSimon Schubert }
7095796c8dcSSimon Schubert
710cf7f2e2dSJohn Marino static int
mi_output_running_pid(struct thread_info * info,void * arg)711cf7f2e2dSJohn Marino mi_output_running_pid (struct thread_info *info, void *arg)
712cf7f2e2dSJohn Marino {
713cf7f2e2dSJohn Marino ptid_t *ptid = arg;
714cf7f2e2dSJohn Marino
715cf7f2e2dSJohn Marino if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
716cf7f2e2dSJohn Marino fprintf_unfiltered (raw_stdout,
717cf7f2e2dSJohn Marino "*running,thread-id=\"%d\"\n",
718cf7f2e2dSJohn Marino info->num);
719cf7f2e2dSJohn Marino
720cf7f2e2dSJohn Marino return 0;
721cf7f2e2dSJohn Marino }
722cf7f2e2dSJohn Marino
723cf7f2e2dSJohn Marino static int
mi_inferior_count(struct inferior * inf,void * arg)724cf7f2e2dSJohn Marino mi_inferior_count (struct inferior *inf, void *arg)
725cf7f2e2dSJohn Marino {
7265796c8dcSSimon Schubert if (inf->pid != 0)
727a45ae5f8SJohn Marino {
728a45ae5f8SJohn Marino int *count_p = arg;
729a45ae5f8SJohn Marino (*count_p)++;
730a45ae5f8SJohn Marino }
731a45ae5f8SJohn Marino
732a45ae5f8SJohn Marino return 0;
733a45ae5f8SJohn Marino }
734a45ae5f8SJohn Marino
7355796c8dcSSimon Schubert static void
mi_on_resume(ptid_t ptid)7365796c8dcSSimon Schubert mi_on_resume (ptid_t ptid)
7375796c8dcSSimon Schubert {
7385796c8dcSSimon Schubert struct thread_info *tp = NULL;
7395796c8dcSSimon Schubert
7405796c8dcSSimon Schubert if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
7415796c8dcSSimon Schubert tp = inferior_thread ();
7425796c8dcSSimon Schubert else
7435796c8dcSSimon Schubert tp = find_thread_ptid (ptid);
7445796c8dcSSimon Schubert
7455796c8dcSSimon Schubert /* Suppress output while calling an inferior function. */
746a45ae5f8SJohn Marino if (tp->control.in_infcall)
747a45ae5f8SJohn Marino return;
7485796c8dcSSimon Schubert
7495796c8dcSSimon Schubert /* To cater for older frontends, emit ^running, but do it only once
7505796c8dcSSimon Schubert per each command. We do it here, since at this point we know
751a45ae5f8SJohn Marino that the target was successfully resumed, and in non-async mode,
752a45ae5f8SJohn Marino we won't return back to MI interpreter code until the target
753a45ae5f8SJohn Marino is done running, so delaying the output of "^running" until then
754a45ae5f8SJohn Marino will make it impossible for frontend to know what's going on.
7555796c8dcSSimon Schubert
756 In future (MI3), we'll be outputting "^done" here. */
757 if (!running_result_record_printed && mi_proceeded)
758 {
759 fprintf_unfiltered (raw_stdout, "%s^running\n",
760 current_token ? current_token : "");
761 }
762
763 if (PIDGET (ptid) == -1)
764 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
765 else if (ptid_is_pid (ptid))
766 {
767 int count = 0;
768
769 /* Backwards compatibility. If there's only one inferior,
770 output "all", otherwise, output each resumed thread
771 individually. */
772 iterate_over_inferiors (mi_inferior_count, &count);
773
774 if (count == 1)
775 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
776 else
777 iterate_over_threads (mi_output_running_pid, &ptid);
778 }
779 else
780 {
781 struct thread_info *ti = find_thread_ptid (ptid);
782
783 gdb_assert (ti);
784 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
785 }
786
787 if (!running_result_record_printed && mi_proceeded)
788 {
789 running_result_record_printed = 1;
790 /* This is what gdb used to do historically -- printing prompt even if
791 it cannot actually accept any input. This will be surely removed
792 for MI3, and may be removed even earler. */
793 /* FIXME: review the use of target_is_async_p here -- is that
794 what we want? */
795 if (!target_is_async_p ())
796 fputs_unfiltered ("(gdb) \n", raw_stdout);
797 }
798 gdb_flush (raw_stdout);
799 }
800
801 static void
mi_solib_loaded(struct so_list * solib)802 mi_solib_loaded (struct so_list *solib)
803 {
804 struct mi_interp *mi = top_level_interpreter_data ();
805
806 target_terminal_ours ();
807 if (gdbarch_has_global_solist (target_gdbarch ()))
808 fprintf_unfiltered (mi->event_channel,
809 "library-loaded,id=\"%s\",target-name=\"%s\","
810 "host-name=\"%s\",symbols-loaded=\"%d\"",
811 solib->so_original_name, solib->so_original_name,
812 solib->so_name, solib->symbols_loaded);
813 else
814 fprintf_unfiltered (mi->event_channel,
815 "library-loaded,id=\"%s\",target-name=\"%s\","
816 "host-name=\"%s\",symbols-loaded=\"%d\","
817 "thread-group=\"i%d\"",
818 solib->so_original_name, solib->so_original_name,
819 solib->so_name, solib->symbols_loaded,
820 current_inferior ()->num);
821
822 gdb_flush (mi->event_channel);
823 }
824
825 static void
mi_solib_unloaded(struct so_list * solib)826 mi_solib_unloaded (struct so_list *solib)
827 {
828 struct mi_interp *mi = top_level_interpreter_data ();
829
830 target_terminal_ours ();
831 if (gdbarch_has_global_solist (target_gdbarch ()))
832 fprintf_unfiltered (mi->event_channel,
833 "library-unloaded,id=\"%s\",target-name=\"%s\","
834 "host-name=\"%s\"",
835 solib->so_original_name, solib->so_original_name,
836 solib->so_name);
837 else
838 fprintf_unfiltered (mi->event_channel,
839 "library-unloaded,id=\"%s\",target-name=\"%s\","
840 "host-name=\"%s\",thread-group=\"i%d\"",
841 solib->so_original_name, solib->so_original_name,
842 solib->so_name, current_inferior ()->num);
843
844 gdb_flush (mi->event_channel);
845 }
846
847 /* Emit notification about the command parameter change. */
848
849 static void
mi_command_param_changed(const char * param,const char * value)850 mi_command_param_changed (const char *param, const char *value)
851 {
852 struct mi_interp *mi = top_level_interpreter_data ();
853 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
854
855 if (mi_suppress_notification.cmd_param_changed)
856 return;
857
858 target_terminal_ours ();
859
860 fprintf_unfiltered (mi->event_channel,
861 "cmd-param-changed");
862
863 ui_out_redirect (mi_uiout, mi->event_channel);
864
865 ui_out_field_string (mi_uiout, "param", param);
866 ui_out_field_string (mi_uiout, "value", value);
867
868 ui_out_redirect (mi_uiout, NULL);
869
870 gdb_flush (mi->event_channel);
871 }
872
873 /* Emit notification about the target memory change. */
874
875 static void
mi_memory_changed(struct inferior * inferior,CORE_ADDR memaddr,ssize_t len,const bfd_byte * myaddr)876 mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
877 ssize_t len, const bfd_byte *myaddr)
878 {
879 struct mi_interp *mi = top_level_interpreter_data ();
880 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
881 struct obj_section *sec;
882
883 if (mi_suppress_notification.memory)
884 return;
885
886 target_terminal_ours ();
887
888 fprintf_unfiltered (mi->event_channel,
889 "memory-changed");
890
891 ui_out_redirect (mi_uiout, mi->event_channel);
892
893 ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
894 ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
895 ui_out_field_fmt (mi_uiout, "len", "0x%zx", len);
896
897 /* Append 'type=code' into notification if MEMADDR falls in the range of
898 sections contain code. */
899 sec = find_pc_section (memaddr);
900 if (sec != NULL && sec->objfile != NULL)
901 {
902 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
903 sec->the_bfd_section);
904
905 if (flags & SEC_CODE)
906 ui_out_field_string (mi_uiout, "type", "code");
907 }
908
909 ui_out_redirect (mi_uiout, NULL);
910
911 gdb_flush (mi->event_channel);
912 }
913
914 static int
report_initial_inferior(struct inferior * inf,void * closure)915 report_initial_inferior (struct inferior *inf, void *closure)
916 {
917 /* This function is called from mi_intepreter_init, and since
918 mi_inferior_added assumes that inferior is fully initialized
919 and top_level_interpreter_data is set, we cannot call
920 it here. */
921 struct mi_interp *mi = closure;
922
923 target_terminal_ours ();
924 fprintf_unfiltered (mi->event_channel,
925 "thread-group-added,id=\"i%d\"",
926 inf->num);
927 gdb_flush (mi->event_channel);
928 return 0;
929 }
930
931 static struct ui_out *
mi_ui_out(struct interp * interp)932 mi_ui_out (struct interp *interp)
933 {
934 struct mi_interp *mi = interp_data (interp);
935
936 return mi->uiout;
937 }
938
939 /* Save the original value of raw_stdout here when logging, so we can
940 restore correctly when done. */
941
942 static struct ui_file *saved_raw_stdout;
943
944 /* Do MI-specific logging actions; save raw_stdout, and change all
945 the consoles to use the supplied ui-file(s). */
946
947 static int
mi_set_logging(struct interp * interp,int start_log,struct ui_file * out,struct ui_file * logfile)948 mi_set_logging (struct interp *interp, int start_log,
949 struct ui_file *out, struct ui_file *logfile)
950 {
951 struct mi_interp *mi = interp_data (interp);
952
953 if (!mi)
954 return 0;
955
956 if (start_log)
957 {
958 /* The tee created already is based on gdb_stdout, which for MI
959 is a console and so we end up in an infinite loop of console
960 writing to ui_file writing to console etc. So discard the
961 existing tee (it hasn't been used yet, and MI won't ever use
962 it), and create one based on raw_stdout instead. */
963 if (logfile)
964 {
965 ui_file_delete (out);
966 out = tee_file_new (raw_stdout, 0, logfile, 0);
967 }
968
969 saved_raw_stdout = raw_stdout;
970 raw_stdout = out;
971 }
972 else
973 {
974 raw_stdout = saved_raw_stdout;
975 saved_raw_stdout = NULL;
976 }
977
978 mi_console_set_raw (mi->out, raw_stdout);
979 mi_console_set_raw (mi->err, raw_stdout);
980 mi_console_set_raw (mi->log, raw_stdout);
981 mi_console_set_raw (mi->targ, raw_stdout);
982 mi_console_set_raw (mi->event_channel, raw_stdout);
983
984 return 1;
985 }
986
987 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
988
989 void
_initialize_mi_interp(void)990 _initialize_mi_interp (void)
991 {
992 static const struct interp_procs procs =
993 {
994 mi_interpreter_init, /* init_proc */
995 mi_interpreter_resume, /* resume_proc */
996 mi_interpreter_suspend, /* suspend_proc */
997 mi_interpreter_exec, /* exec_proc */
998 mi_interpreter_prompt_p, /* prompt_proc_p */
999 mi_ui_out, /* ui_out_proc */
1000 mi_set_logging /* set_logging_proc */
1001 };
1002
1003 /* The various interpreter levels. */
1004 interp_add (interp_new (INTERP_MI1, &procs));
1005 interp_add (interp_new (INTERP_MI2, &procs));
1006 interp_add (interp_new (INTERP_MI3, &procs));
1007 interp_add (interp_new (INTERP_MI, &procs));
1008 }
1009