15796c8dcSSimon Schubert /* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
25796c8dcSSimon Schubert
3*ef5ccd6cSJohn 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"
38*ef5ccd6cSJohn Marino #include "objfiles.h"
39*ef5ccd6cSJohn Marino #include "tracepoint.h"
405796c8dcSSimon Schubert
41*ef5ccd6cSJohn Marino /* These are the interpreter setup, etc. functions for the MI
42*ef5ccd6cSJohn Marino interpreter. */
43*ef5ccd6cSJohn Marino
44*ef5ccd6cSJohn Marino static void mi_execute_command_wrapper (const char *cmd);
45*ef5ccd6cSJohn Marino static void mi_execute_command_input_handler (char *cmd);
465796c8dcSSimon Schubert static void mi_command_loop (int mi_version);
475796c8dcSSimon Schubert
485796c8dcSSimon Schubert /* These are hooks that we put in place while doing interpreter_exec
49*ef5ccd6cSJohn Marino so we can report interesting things that happened "behind the MI's
50*ef5ccd6cSJohn Marino back" in this command. */
51*ef5ccd6cSJohn Marino
525796c8dcSSimon Schubert static int mi_interp_query_hook (const char *ctlstr, va_list ap)
53cf7f2e2dSJohn Marino 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
595796c8dcSSimon Schubert static void mi_insert_notify_hooks (void);
605796c8dcSSimon Schubert static void mi_remove_notify_hooks (void);
615796c8dcSSimon Schubert static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
625796c8dcSSimon Schubert
635796c8dcSSimon Schubert static void mi_new_thread (struct thread_info *t);
645796c8dcSSimon Schubert static void mi_thread_exit (struct thread_info *t, int silent);
65*ef5ccd6cSJohn Marino static void mi_record_changed (struct inferior*, int);
66cf7f2e2dSJohn Marino static void mi_inferior_added (struct inferior *inf);
67cf7f2e2dSJohn Marino static void mi_inferior_appeared (struct inferior *inf);
68cf7f2e2dSJohn Marino static void mi_inferior_exit (struct inferior *inf);
69cf7f2e2dSJohn Marino static void mi_inferior_removed (struct inferior *inf);
705796c8dcSSimon Schubert static void mi_on_resume (ptid_t ptid);
715796c8dcSSimon Schubert static void mi_solib_loaded (struct so_list *solib);
725796c8dcSSimon Schubert static void mi_solib_unloaded (struct so_list *solib);
735796c8dcSSimon Schubert static void mi_about_to_proceed (void);
74*ef5ccd6cSJohn Marino static void mi_traceframe_changed (int tfnum, int tpnum);
75*ef5ccd6cSJohn Marino static void mi_tsv_created (const struct trace_state_variable *tsv);
76*ef5ccd6cSJohn Marino static void mi_tsv_deleted (const struct trace_state_variable *tsv);
77*ef5ccd6cSJohn Marino static void mi_tsv_modified (const struct trace_state_variable *tsv);
78a45ae5f8SJohn Marino static void mi_breakpoint_created (struct breakpoint *b);
79a45ae5f8SJohn Marino static void mi_breakpoint_deleted (struct breakpoint *b);
80a45ae5f8SJohn Marino static void mi_breakpoint_modified (struct breakpoint *b);
81*ef5ccd6cSJohn Marino static void mi_command_param_changed (const char *param, const char *value);
82*ef5ccd6cSJohn Marino static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
83*ef5ccd6cSJohn Marino ssize_t len, const bfd_byte *myaddr);
845796c8dcSSimon Schubert
85cf7f2e2dSJohn Marino static int report_initial_inferior (struct inferior *inf, void *closure);
86cf7f2e2dSJohn Marino
875796c8dcSSimon Schubert static void *
mi_interpreter_init(struct interp * interp,int top_level)88a45ae5f8SJohn Marino mi_interpreter_init (struct interp *interp, int top_level)
895796c8dcSSimon Schubert {
905796c8dcSSimon Schubert struct mi_interp *mi = XMALLOC (struct mi_interp);
91a45ae5f8SJohn Marino const char *name;
92a45ae5f8SJohn Marino int mi_version;
935796c8dcSSimon Schubert
94*ef5ccd6cSJohn Marino /* Assign the output channel created at startup to its own global,
95*ef5ccd6cSJohn Marino so that we can create a console channel that encapsulates and
96*ef5ccd6cSJohn Marino prefixes all gdb_output-type bits coming from the rest of the
97*ef5ccd6cSJohn Marino debugger. */
985796c8dcSSimon Schubert
99*ef5ccd6cSJohn Marino raw_stdout = gdb_stdout;
1005796c8dcSSimon Schubert
101*ef5ccd6cSJohn Marino /* Create MI console channels, each with a different prefix so they
102*ef5ccd6cSJohn Marino can be distinguished. */
1035796c8dcSSimon Schubert mi->out = mi_console_file_new (raw_stdout, "~", '"');
1045796c8dcSSimon Schubert mi->err = mi_console_file_new (raw_stdout, "&", '"');
1055796c8dcSSimon Schubert mi->log = mi->err;
1065796c8dcSSimon Schubert mi->targ = mi_console_file_new (raw_stdout, "@", '"');
1075796c8dcSSimon Schubert mi->event_channel = mi_console_file_new (raw_stdout, "=", 0);
1085796c8dcSSimon Schubert
109a45ae5f8SJohn Marino name = interp_name (interp);
110a45ae5f8SJohn Marino /* INTERP_MI selects the most recent released version. "mi2" was
111a45ae5f8SJohn Marino released as part of GDB 6.0. */
112a45ae5f8SJohn Marino if (strcmp (name, INTERP_MI) == 0)
113a45ae5f8SJohn Marino mi_version = 2;
114a45ae5f8SJohn Marino else if (strcmp (name, INTERP_MI1) == 0)
115a45ae5f8SJohn Marino mi_version = 1;
116a45ae5f8SJohn Marino else if (strcmp (name, INTERP_MI2) == 0)
117a45ae5f8SJohn Marino mi_version = 2;
118a45ae5f8SJohn Marino else if (strcmp (name, INTERP_MI3) == 0)
119a45ae5f8SJohn Marino mi_version = 3;
120a45ae5f8SJohn Marino else
121a45ae5f8SJohn Marino gdb_assert_not_reached ("unhandled MI version");
122a45ae5f8SJohn Marino
123a45ae5f8SJohn Marino mi->uiout = mi_out_new (mi_version);
124a45ae5f8SJohn Marino
1255796c8dcSSimon Schubert if (top_level)
1265796c8dcSSimon Schubert {
1275796c8dcSSimon Schubert observer_attach_new_thread (mi_new_thread);
1285796c8dcSSimon Schubert 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);
132cf7f2e2dSJohn Marino observer_attach_inferior_removed (mi_inferior_removed);
133*ef5ccd6cSJohn Marino 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);
139*ef5ccd6cSJohn Marino observer_attach_traceframe_changed (mi_traceframe_changed);
140*ef5ccd6cSJohn Marino observer_attach_tsv_created (mi_tsv_created);
141*ef5ccd6cSJohn Marino observer_attach_tsv_deleted (mi_tsv_deleted);
142*ef5ccd6cSJohn Marino observer_attach_tsv_modified (mi_tsv_modified);
143a45ae5f8SJohn Marino observer_attach_breakpoint_created (mi_breakpoint_created);
144a45ae5f8SJohn Marino observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
145a45ae5f8SJohn Marino observer_attach_breakpoint_modified (mi_breakpoint_modified);
146*ef5ccd6cSJohn Marino observer_attach_command_param_changed (mi_command_param_changed);
147*ef5ccd6cSJohn Marino observer_attach_memory_changed (mi_memory_changed);
148cf7f2e2dSJohn Marino
149*ef5ccd6cSJohn Marino /* The initial inferior is created before this function is
150*ef5ccd6cSJohn Marino called, so we need to report it explicitly. Use iteration in
151*ef5ccd6cSJohn Marino case future version of GDB creates more than one inferior
152*ef5ccd6cSJohn Marino up-front. */
153cf7f2e2dSJohn Marino 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
164*ef5ccd6cSJohn Marino /* As per hack note in mi_interpreter_init, swap in the output
165*ef5ccd6cSJohn Marino 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;
171*ef5ccd6cSJohn Marino 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;
183*ef5ccd6cSJohn Marino /* 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
1975796c8dcSSimon Schubert /* 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)
2195796c8dcSSimon Schubert {
220*ef5ccd6cSJohn Marino mi_execute_command_wrapper (command);
2215796c8dcSSimon Schubert return exception_none;
2225796c8dcSSimon Schubert }
2235796c8dcSSimon Schubert
224*ef5ccd6cSJohn Marino /* Never display the default GDB prompt in MI case. */
225*ef5ccd6cSJohn Marino
2265796c8dcSSimon Schubert static int
mi_interpreter_prompt_p(void * data)2275796c8dcSSimon Schubert mi_interpreter_prompt_p (void *data)
2285796c8dcSSimon Schubert {
2295796c8dcSSimon Schubert 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)
241c50c785cSJohn Marino error (_("-interpreter-exec: "
242c50c785cSJohn Marino "Usage: -interpreter-exec interp command"));
2435796c8dcSSimon Schubert
2445796c8dcSSimon Schubert interp_to_use = interp_lookup (argv[0]);
2455796c8dcSSimon Schubert if (interp_to_use == NULL)
246c50c785cSJohn Marino error (_("-interpreter-exec: could not find interpreter \"%s\""),
247c50c785cSJohn Marino argv[0]);
2485796c8dcSSimon Schubert
2495796c8dcSSimon Schubert if (!interp_exec_p (interp_to_use))
250c50c785cSJohn Marino error (_("-interpreter-exec: interpreter \"%s\" "
251c50c785cSJohn Marino "does not support command execution"),
2525796c8dcSSimon Schubert argv[0]);
2535796c8dcSSimon Schubert
254*ef5ccd6cSJohn Marino /* Insert the MI out hooks, making sure to also call the
255*ef5ccd6cSJohn Marino interpreter's hooks if it has any. */
256*ef5ccd6cSJohn Marino /* KRS: We shouldn't need this... Events should be installed and
257*ef5ccd6cSJohn Marino they should just ALWAYS fire something out down the MI
258*ef5ccd6cSJohn Marino channel. */
2595796c8dcSSimon Schubert mi_insert_notify_hooks ();
2605796c8dcSSimon Schubert
261*ef5ccd6cSJohn Marino /* Now run the code. */
2625796c8dcSSimon Schubert
2635796c8dcSSimon Schubert old_chain = make_cleanup (null_cleanup, 0);
2645796c8dcSSimon Schubert for (i = 1; i < argc; i++)
2655796c8dcSSimon Schubert {
2665796c8dcSSimon Schubert struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
267cf7f2e2dSJohn Marino
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
283*ef5ccd6cSJohn Marino /* This inserts a number of hooks that are meant to produce
284*ef5ccd6cSJohn Marino async-notify ("=") MI messages while running commands in another
285*ef5ccd6cSJohn Marino interpreter using mi_interpreter_exec. The canonical use for this
286*ef5ccd6cSJohn Marino is to allow access to the gdb CLI interpreter from within the MI,
287*ef5ccd6cSJohn Marino while still producing MI style output when actions in the CLI
288*ef5ccd6cSJohn Marino 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)309*ef5ccd6cSJohn Marino mi_execute_command_wrapper (const char *cmd)
3105796c8dcSSimon Schubert {
3115796c8dcSSimon Schubert mi_execute_command (cmd, stdin == instream);
3125796c8dcSSimon Schubert }
3135796c8dcSSimon Schubert
314*ef5ccd6cSJohn Marino /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
315*ef5ccd6cSJohn Marino
316*ef5ccd6cSJohn Marino static void
mi_execute_command_input_handler(char * cmd)317*ef5ccd6cSJohn Marino mi_execute_command_input_handler (char *cmd)
318*ef5ccd6cSJohn Marino {
319*ef5ccd6cSJohn Marino mi_execute_command_wrapper (cmd);
320*ef5ccd6cSJohn Marino
321*ef5ccd6cSJohn Marino fputs_unfiltered ("(gdb) \n", raw_stdout);
322*ef5ccd6cSJohn Marino gdb_flush (raw_stdout);
323*ef5ccd6cSJohn Marino }
324*ef5ccd6cSJohn Marino
3255796c8dcSSimon Schubert static void
mi1_command_loop(void)3265796c8dcSSimon Schubert mi1_command_loop (void)
3275796c8dcSSimon Schubert {
3285796c8dcSSimon Schubert mi_command_loop (1);
3295796c8dcSSimon Schubert }
3305796c8dcSSimon Schubert
3315796c8dcSSimon Schubert static void
mi2_command_loop(void)3325796c8dcSSimon Schubert mi2_command_loop (void)
3335796c8dcSSimon Schubert {
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);
3415796c8dcSSimon Schubert }
3425796c8dcSSimon Schubert
3435796c8dcSSimon Schubert static void
mi_command_loop(int mi_version)3445796c8dcSSimon Schubert mi_command_loop (int mi_version)
3455796c8dcSSimon Schubert {
3465796c8dcSSimon Schubert /* Turn off 8 bit strings in quoted output. Any character with the
3475796c8dcSSimon Schubert high bit set is printed using C's octal format. */
3485796c8dcSSimon Schubert sevenbit_strings = 1;
349*ef5ccd6cSJohn Marino
350*ef5ccd6cSJohn Marino /* Tell the world that we're alive. */
3515796c8dcSSimon Schubert fputs_unfiltered ("(gdb) \n", raw_stdout);
3525796c8dcSSimon Schubert gdb_flush (raw_stdout);
353*ef5ccd6cSJohn Marino
3545796c8dcSSimon Schubert start_event_loop ();
3555796c8dcSSimon Schubert }
3565796c8dcSSimon Schubert
3575796c8dcSSimon Schubert static void
mi_new_thread(struct thread_info * t)3585796c8dcSSimon Schubert mi_new_thread (struct thread_info *t)
3595796c8dcSSimon Schubert {
3605796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
361cf7f2e2dSJohn Marino struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid));
362cf7f2e2dSJohn Marino
363cf7f2e2dSJohn Marino gdb_assert (inf);
3645796c8dcSSimon Schubert
3655796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
366cf7f2e2dSJohn Marino "thread-created,id=\"%d\",group-id=\"i%d\"",
367cf7f2e2dSJohn Marino t->num, inf->num);
3685796c8dcSSimon Schubert gdb_flush (mi->event_channel);
3695796c8dcSSimon Schubert }
3705796c8dcSSimon Schubert
3715796c8dcSSimon Schubert static void
mi_thread_exit(struct thread_info * t,int silent)3725796c8dcSSimon Schubert mi_thread_exit (struct thread_info *t, int silent)
3735796c8dcSSimon Schubert {
3745796c8dcSSimon Schubert struct mi_interp *mi;
375cf7f2e2dSJohn Marino struct inferior *inf;
3765796c8dcSSimon Schubert
3775796c8dcSSimon Schubert if (silent)
3785796c8dcSSimon Schubert return;
3795796c8dcSSimon Schubert
380cf7f2e2dSJohn Marino inf = find_inferior_pid (ptid_get_pid (t->ptid));
381cf7f2e2dSJohn Marino
3825796c8dcSSimon Schubert mi = top_level_interpreter_data ();
3835796c8dcSSimon Schubert target_terminal_ours ();
3845796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
385cf7f2e2dSJohn Marino "thread-exited,id=\"%d\",group-id=\"i%d\"",
386cf7f2e2dSJohn Marino t->num, inf->num);
3875796c8dcSSimon Schubert gdb_flush (mi->event_channel);
3885796c8dcSSimon Schubert }
3895796c8dcSSimon Schubert
390*ef5ccd6cSJohn Marino /* Emit notification on changing the state of record. */
391*ef5ccd6cSJohn Marino
392*ef5ccd6cSJohn Marino static void
mi_record_changed(struct inferior * inferior,int started)393*ef5ccd6cSJohn Marino mi_record_changed (struct inferior *inferior, int started)
394*ef5ccd6cSJohn Marino {
395*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
396*ef5ccd6cSJohn Marino
397*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "record-%s,thread-group=\"i%d\"",
398*ef5ccd6cSJohn Marino started ? "started" : "stopped", inferior->num);
399*ef5ccd6cSJohn Marino
400*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
401*ef5ccd6cSJohn Marino }
402*ef5ccd6cSJohn Marino
4035796c8dcSSimon Schubert static void
mi_inferior_added(struct inferior * inf)404cf7f2e2dSJohn Marino mi_inferior_added (struct inferior *inf)
4055796c8dcSSimon Schubert {
4065796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
407cf7f2e2dSJohn Marino
4085796c8dcSSimon Schubert target_terminal_ours ();
409cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
410cf7f2e2dSJohn Marino "thread-group-added,id=\"i%d\"",
411cf7f2e2dSJohn Marino inf->num);
4125796c8dcSSimon Schubert gdb_flush (mi->event_channel);
4135796c8dcSSimon Schubert }
4145796c8dcSSimon Schubert
4155796c8dcSSimon Schubert static void
mi_inferior_appeared(struct inferior * inf)416cf7f2e2dSJohn Marino mi_inferior_appeared (struct inferior *inf)
4175796c8dcSSimon Schubert {
4185796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
419cf7f2e2dSJohn Marino
4205796c8dcSSimon Schubert target_terminal_ours ();
421cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
422cf7f2e2dSJohn Marino "thread-group-started,id=\"i%d\",pid=\"%d\"",
423cf7f2e2dSJohn Marino inf->num, inf->pid);
424cf7f2e2dSJohn Marino gdb_flush (mi->event_channel);
425cf7f2e2dSJohn Marino }
426cf7f2e2dSJohn Marino
427cf7f2e2dSJohn Marino static void
mi_inferior_exit(struct inferior * inf)428cf7f2e2dSJohn Marino mi_inferior_exit (struct inferior *inf)
429cf7f2e2dSJohn Marino {
430cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
431cf7f2e2dSJohn Marino
432cf7f2e2dSJohn Marino target_terminal_ours ();
433c50c785cSJohn Marino if (inf->has_exit_code)
434c50c785cSJohn Marino fprintf_unfiltered (mi->event_channel,
435c50c785cSJohn Marino "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
436c50c785cSJohn Marino inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
437c50c785cSJohn Marino else
438c50c785cSJohn Marino fprintf_unfiltered (mi->event_channel,
439c50c785cSJohn Marino "thread-group-exited,id=\"i%d\"", inf->num);
440c50c785cSJohn Marino
441cf7f2e2dSJohn Marino gdb_flush (mi->event_channel);
442cf7f2e2dSJohn Marino }
443cf7f2e2dSJohn Marino
444cf7f2e2dSJohn Marino static void
mi_inferior_removed(struct inferior * inf)445cf7f2e2dSJohn Marino mi_inferior_removed (struct inferior *inf)
446cf7f2e2dSJohn Marino {
447cf7f2e2dSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
448cf7f2e2dSJohn Marino
449cf7f2e2dSJohn Marino target_terminal_ours ();
450cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
451cf7f2e2dSJohn Marino "thread-group-removed,id=\"i%d\"",
452cf7f2e2dSJohn Marino inf->num);
4535796c8dcSSimon Schubert gdb_flush (mi->event_channel);
4545796c8dcSSimon Schubert }
4555796c8dcSSimon Schubert
4565796c8dcSSimon Schubert static void
mi_on_normal_stop(struct bpstats * bs,int print_frame)4575796c8dcSSimon Schubert 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 {
466cf7f2e2dSJohn Marino int core;
467cf7f2e2dSJohn Marino
468a45ae5f8SJohn Marino if (current_uiout != mi_uiout)
4695796c8dcSSimon Schubert {
470*ef5ccd6cSJohn Marino /* The normal_stop function has printed frame information
471*ef5ccd6cSJohn Marino into CLI uiout, or some other non-MI uiout. There's no
472*ef5ccd6cSJohn Marino way we can extract proper fields from random uiout
473*ef5ccd6cSJohn Marino object, so we print the frame again. In practice, this
474*ef5ccd6cSJohn Marino can only happen when running a CLI command in MI. */
475a45ae5f8SJohn Marino struct ui_out *saved_uiout = current_uiout;
476a45ae5f8SJohn Marino struct target_waitstatus last;
477a45ae5f8SJohn Marino ptid_t last_ptid;
478cf7f2e2dSJohn Marino
479a45ae5f8SJohn Marino current_uiout = mi_uiout;
480a45ae5f8SJohn Marino
481a45ae5f8SJohn Marino get_last_target_status (&last_ptid, &last);
482a45ae5f8SJohn Marino bpstat_print (bs, last.kind);
483a45ae5f8SJohn Marino
4845796c8dcSSimon Schubert print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC);
485a45ae5f8SJohn Marino current_uiout = saved_uiout;
4865796c8dcSSimon Schubert }
4875796c8dcSSimon Schubert
4885796c8dcSSimon Schubert ui_out_field_int (mi_uiout, "thread-id",
4895796c8dcSSimon Schubert pid_to_thread_id (inferior_ptid));
4905796c8dcSSimon Schubert if (non_stop)
4915796c8dcSSimon Schubert {
4925796c8dcSSimon Schubert struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
4935796c8dcSSimon Schubert (mi_uiout, "stopped-threads");
494cf7f2e2dSJohn Marino
4955796c8dcSSimon Schubert ui_out_field_int (mi_uiout, NULL,
4965796c8dcSSimon Schubert pid_to_thread_id (inferior_ptid));
4975796c8dcSSimon Schubert do_cleanups (back_to);
4985796c8dcSSimon Schubert }
4995796c8dcSSimon Schubert else
5005796c8dcSSimon Schubert ui_out_field_string (mi_uiout, "stopped-threads", "all");
501cf7f2e2dSJohn Marino
502cf7f2e2dSJohn Marino core = target_core_of_thread (inferior_ptid);
503cf7f2e2dSJohn Marino if (core != -1)
504cf7f2e2dSJohn Marino ui_out_field_int (mi_uiout, "core", core);
5055796c8dcSSimon Schubert }
5065796c8dcSSimon Schubert
5075796c8dcSSimon Schubert fputs_unfiltered ("*stopped", raw_stdout);
5085796c8dcSSimon Schubert mi_out_put (mi_uiout, raw_stdout);
5095796c8dcSSimon Schubert mi_out_rewind (mi_uiout);
5105796c8dcSSimon Schubert mi_print_timing_maybe ();
5115796c8dcSSimon Schubert fputs_unfiltered ("\n", raw_stdout);
5125796c8dcSSimon Schubert gdb_flush (raw_stdout);
5135796c8dcSSimon Schubert }
5145796c8dcSSimon Schubert
5155796c8dcSSimon Schubert static void
mi_about_to_proceed(void)5165796c8dcSSimon Schubert mi_about_to_proceed (void)
5175796c8dcSSimon Schubert {
5185796c8dcSSimon Schubert /* Suppress output while calling an inferior function. */
5195796c8dcSSimon Schubert
5205796c8dcSSimon Schubert if (!ptid_equal (inferior_ptid, null_ptid))
5215796c8dcSSimon Schubert {
5225796c8dcSSimon Schubert struct thread_info *tp = inferior_thread ();
523cf7f2e2dSJohn Marino
524c50c785cSJohn Marino if (tp->control.in_infcall)
5255796c8dcSSimon Schubert return;
5265796c8dcSSimon Schubert }
5275796c8dcSSimon Schubert
5285796c8dcSSimon Schubert mi_proceeded = 1;
5295796c8dcSSimon Schubert }
5305796c8dcSSimon Schubert
531*ef5ccd6cSJohn Marino /* When the element is non-zero, no MI notifications will be emitted in
532*ef5ccd6cSJohn Marino response to the corresponding observers. */
533*ef5ccd6cSJohn Marino
534*ef5ccd6cSJohn Marino struct mi_suppress_notification mi_suppress_notification =
535*ef5ccd6cSJohn Marino {
536*ef5ccd6cSJohn Marino 0,
537*ef5ccd6cSJohn Marino 0,
538*ef5ccd6cSJohn Marino 0,
539*ef5ccd6cSJohn Marino };
540*ef5ccd6cSJohn Marino
541*ef5ccd6cSJohn Marino /* Emit notification on changing a traceframe. */
542*ef5ccd6cSJohn Marino
543*ef5ccd6cSJohn Marino static void
mi_traceframe_changed(int tfnum,int tpnum)544*ef5ccd6cSJohn Marino mi_traceframe_changed (int tfnum, int tpnum)
545*ef5ccd6cSJohn Marino {
546*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
547*ef5ccd6cSJohn Marino
548*ef5ccd6cSJohn Marino if (mi_suppress_notification.traceframe)
549*ef5ccd6cSJohn Marino return;
550*ef5ccd6cSJohn Marino
551*ef5ccd6cSJohn Marino target_terminal_ours ();
552*ef5ccd6cSJohn Marino
553*ef5ccd6cSJohn Marino if (tfnum >= 0)
554*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
555*ef5ccd6cSJohn Marino "num=\"%d\",tracepoint=\"%d\"\n",
556*ef5ccd6cSJohn Marino tfnum, tpnum);
557*ef5ccd6cSJohn Marino else
558*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
559*ef5ccd6cSJohn Marino
560*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
561*ef5ccd6cSJohn Marino }
562*ef5ccd6cSJohn Marino
563*ef5ccd6cSJohn Marino /* Emit notification on creating a trace state variable. */
564*ef5ccd6cSJohn Marino
565*ef5ccd6cSJohn Marino static void
mi_tsv_created(const struct trace_state_variable * tsv)566*ef5ccd6cSJohn Marino mi_tsv_created (const struct trace_state_variable *tsv)
567*ef5ccd6cSJohn Marino {
568*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
569*ef5ccd6cSJohn Marino
570*ef5ccd6cSJohn Marino target_terminal_ours ();
571*ef5ccd6cSJohn Marino
572*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "tsv-created,"
573*ef5ccd6cSJohn Marino "name=\"%s\",initial=\"%s\"\n",
574*ef5ccd6cSJohn Marino tsv->name, plongest (tsv->initial_value));
575*ef5ccd6cSJohn Marino
576*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
577*ef5ccd6cSJohn Marino }
578*ef5ccd6cSJohn Marino
579*ef5ccd6cSJohn Marino /* Emit notification on deleting a trace state variable. */
580*ef5ccd6cSJohn Marino
581*ef5ccd6cSJohn Marino static void
mi_tsv_deleted(const struct trace_state_variable * tsv)582*ef5ccd6cSJohn Marino mi_tsv_deleted (const struct trace_state_variable *tsv)
583*ef5ccd6cSJohn Marino {
584*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
585*ef5ccd6cSJohn Marino
586*ef5ccd6cSJohn Marino target_terminal_ours ();
587*ef5ccd6cSJohn Marino
588*ef5ccd6cSJohn Marino if (tsv != NULL)
589*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
590*ef5ccd6cSJohn Marino "name=\"%s\"\n", tsv->name);
591*ef5ccd6cSJohn Marino else
592*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
593*ef5ccd6cSJohn Marino
594*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
595*ef5ccd6cSJohn Marino }
596*ef5ccd6cSJohn Marino
597*ef5ccd6cSJohn Marino /* Emit notification on modifying a trace state variable. */
598*ef5ccd6cSJohn Marino
599*ef5ccd6cSJohn Marino static void
mi_tsv_modified(const struct trace_state_variable * tsv)600*ef5ccd6cSJohn Marino mi_tsv_modified (const struct trace_state_variable *tsv)
601*ef5ccd6cSJohn Marino {
602*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
603*ef5ccd6cSJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
604*ef5ccd6cSJohn Marino
605*ef5ccd6cSJohn Marino target_terminal_ours ();
606*ef5ccd6cSJohn Marino
607*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel,
608*ef5ccd6cSJohn Marino "tsv-modified");
609*ef5ccd6cSJohn Marino
610*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
611*ef5ccd6cSJohn Marino
612*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "name", tsv->name);
613*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "initial",
614*ef5ccd6cSJohn Marino plongest (tsv->initial_value));
615*ef5ccd6cSJohn Marino if (tsv->value_known)
616*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
617*ef5ccd6cSJohn Marino
618*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, NULL);
619*ef5ccd6cSJohn Marino
620*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
621*ef5ccd6cSJohn Marino }
622a45ae5f8SJohn Marino
623a45ae5f8SJohn Marino /* Emit notification about a created breakpoint. */
624*ef5ccd6cSJohn Marino
625a45ae5f8SJohn Marino static void
mi_breakpoint_created(struct breakpoint * b)626a45ae5f8SJohn Marino mi_breakpoint_created (struct breakpoint *b)
627a45ae5f8SJohn Marino {
628a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
629a45ae5f8SJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
630*ef5ccd6cSJohn Marino volatile struct gdb_exception e;
631a45ae5f8SJohn Marino
632*ef5ccd6cSJohn Marino if (mi_suppress_notification.breakpoint)
633a45ae5f8SJohn Marino return;
634a45ae5f8SJohn Marino
635a45ae5f8SJohn Marino if (b->number <= 0)
636a45ae5f8SJohn Marino return;
637a45ae5f8SJohn Marino
638a45ae5f8SJohn Marino target_terminal_ours ();
639a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel,
640a45ae5f8SJohn Marino "breakpoint-created");
641a45ae5f8SJohn Marino /* We want the output from gdb_breakpoint_query to go to
642*ef5ccd6cSJohn Marino mi->event_channel. One approach would be to just call
643*ef5ccd6cSJohn Marino gdb_breakpoint_query, and then use mi_out_put to send the current
644*ef5ccd6cSJohn Marino content of mi_outout into mi->event_channel. However, that will
645*ef5ccd6cSJohn Marino break if anything is output to mi_uiout prior to calling the
646*ef5ccd6cSJohn Marino breakpoint_created notifications. So, we use
647*ef5ccd6cSJohn Marino ui_out_redirect. */
648a45ae5f8SJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
649a45ae5f8SJohn Marino TRY_CATCH (e, RETURN_MASK_ERROR)
650a45ae5f8SJohn Marino gdb_breakpoint_query (mi_uiout, b->number, NULL);
651a45ae5f8SJohn Marino ui_out_redirect (mi_uiout, NULL);
652a45ae5f8SJohn Marino
653a45ae5f8SJohn Marino gdb_flush (mi->event_channel);
654a45ae5f8SJohn Marino }
655a45ae5f8SJohn Marino
656a45ae5f8SJohn Marino /* Emit notification about deleted breakpoint. */
657*ef5ccd6cSJohn Marino
658a45ae5f8SJohn Marino static void
mi_breakpoint_deleted(struct breakpoint * b)659a45ae5f8SJohn Marino mi_breakpoint_deleted (struct breakpoint *b)
660a45ae5f8SJohn Marino {
661a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
662a45ae5f8SJohn Marino
663*ef5ccd6cSJohn Marino if (mi_suppress_notification.breakpoint)
664a45ae5f8SJohn Marino return;
665a45ae5f8SJohn Marino
666a45ae5f8SJohn Marino if (b->number <= 0)
667a45ae5f8SJohn Marino return;
668a45ae5f8SJohn Marino
669a45ae5f8SJohn Marino target_terminal_ours ();
670a45ae5f8SJohn Marino
671a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
672a45ae5f8SJohn Marino b->number);
673a45ae5f8SJohn Marino
674a45ae5f8SJohn Marino gdb_flush (mi->event_channel);
675a45ae5f8SJohn Marino }
676a45ae5f8SJohn Marino
677a45ae5f8SJohn Marino /* Emit notification about modified breakpoint. */
678*ef5ccd6cSJohn Marino
679a45ae5f8SJohn Marino static void
mi_breakpoint_modified(struct breakpoint * b)680a45ae5f8SJohn Marino mi_breakpoint_modified (struct breakpoint *b)
681a45ae5f8SJohn Marino {
682a45ae5f8SJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
683a45ae5f8SJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
684*ef5ccd6cSJohn Marino volatile struct gdb_exception e;
685a45ae5f8SJohn Marino
686*ef5ccd6cSJohn Marino if (mi_suppress_notification.breakpoint)
687a45ae5f8SJohn Marino return;
688a45ae5f8SJohn Marino
689a45ae5f8SJohn Marino if (b->number <= 0)
690a45ae5f8SJohn Marino return;
691a45ae5f8SJohn Marino
692a45ae5f8SJohn Marino target_terminal_ours ();
693a45ae5f8SJohn Marino fprintf_unfiltered (mi->event_channel,
694a45ae5f8SJohn Marino "breakpoint-modified");
695a45ae5f8SJohn Marino /* We want the output from gdb_breakpoint_query to go to
696*ef5ccd6cSJohn Marino mi->event_channel. One approach would be to just call
697*ef5ccd6cSJohn Marino gdb_breakpoint_query, and then use mi_out_put to send the current
698*ef5ccd6cSJohn Marino content of mi_outout into mi->event_channel. However, that will
699*ef5ccd6cSJohn Marino break if anything is output to mi_uiout prior to calling the
700*ef5ccd6cSJohn Marino breakpoint_created notifications. So, we use
701*ef5ccd6cSJohn Marino ui_out_redirect. */
702a45ae5f8SJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
703a45ae5f8SJohn Marino TRY_CATCH (e, RETURN_MASK_ERROR)
704a45ae5f8SJohn Marino gdb_breakpoint_query (mi_uiout, b->number, NULL);
705a45ae5f8SJohn Marino ui_out_redirect (mi_uiout, NULL);
706a45ae5f8SJohn Marino
707a45ae5f8SJohn Marino gdb_flush (mi->event_channel);
708a45ae5f8SJohn Marino }
709a45ae5f8SJohn Marino
7105796c8dcSSimon Schubert static int
mi_output_running_pid(struct thread_info * info,void * arg)7115796c8dcSSimon Schubert mi_output_running_pid (struct thread_info *info, void *arg)
7125796c8dcSSimon Schubert {
7135796c8dcSSimon Schubert ptid_t *ptid = arg;
7145796c8dcSSimon Schubert
7155796c8dcSSimon Schubert if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
7165796c8dcSSimon Schubert fprintf_unfiltered (raw_stdout,
7175796c8dcSSimon Schubert "*running,thread-id=\"%d\"\n",
7185796c8dcSSimon Schubert info->num);
7195796c8dcSSimon Schubert
7205796c8dcSSimon Schubert return 0;
7215796c8dcSSimon Schubert }
7225796c8dcSSimon Schubert
7235796c8dcSSimon Schubert static int
mi_inferior_count(struct inferior * inf,void * arg)7245796c8dcSSimon Schubert mi_inferior_count (struct inferior *inf, void *arg)
7255796c8dcSSimon Schubert {
7265796c8dcSSimon Schubert if (inf->pid != 0)
7275796c8dcSSimon Schubert {
7285796c8dcSSimon Schubert int *count_p = arg;
7295796c8dcSSimon Schubert (*count_p)++;
7305796c8dcSSimon Schubert }
7315796c8dcSSimon Schubert
7325796c8dcSSimon Schubert return 0;
7335796c8dcSSimon Schubert }
7345796c8dcSSimon Schubert
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. */
746c50c785cSJohn Marino if (tp->control.in_infcall)
7475796c8dcSSimon Schubert 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
7515796c8dcSSimon Schubert that the target was successfully resumed, and in non-async mode,
7525796c8dcSSimon Schubert we won't return back to MI interpreter code until the target
7535796c8dcSSimon Schubert is done running, so delaying the output of "^running" until then
7545796c8dcSSimon Schubert will make it impossible for frontend to know what's going on.
7555796c8dcSSimon Schubert
7565796c8dcSSimon Schubert In future (MI3), we'll be outputting "^done" here. */
7575796c8dcSSimon Schubert if (!running_result_record_printed && mi_proceeded)
7585796c8dcSSimon Schubert {
759cf7f2e2dSJohn Marino fprintf_unfiltered (raw_stdout, "%s^running\n",
760cf7f2e2dSJohn Marino current_token ? current_token : "");
7615796c8dcSSimon Schubert }
7625796c8dcSSimon Schubert
7635796c8dcSSimon Schubert if (PIDGET (ptid) == -1)
7645796c8dcSSimon Schubert fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
7655796c8dcSSimon Schubert else if (ptid_is_pid (ptid))
7665796c8dcSSimon Schubert {
7675796c8dcSSimon Schubert int count = 0;
7685796c8dcSSimon Schubert
7695796c8dcSSimon Schubert /* Backwards compatibility. If there's only one inferior,
7705796c8dcSSimon Schubert output "all", otherwise, output each resumed thread
7715796c8dcSSimon Schubert individually. */
7725796c8dcSSimon Schubert iterate_over_inferiors (mi_inferior_count, &count);
7735796c8dcSSimon Schubert
7745796c8dcSSimon Schubert if (count == 1)
7755796c8dcSSimon Schubert fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n");
7765796c8dcSSimon Schubert else
7775796c8dcSSimon Schubert iterate_over_threads (mi_output_running_pid, &ptid);
7785796c8dcSSimon Schubert }
7795796c8dcSSimon Schubert else
7805796c8dcSSimon Schubert {
7815796c8dcSSimon Schubert struct thread_info *ti = find_thread_ptid (ptid);
782cf7f2e2dSJohn Marino
7835796c8dcSSimon Schubert gdb_assert (ti);
7845796c8dcSSimon Schubert fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num);
7855796c8dcSSimon Schubert }
7865796c8dcSSimon Schubert
7875796c8dcSSimon Schubert if (!running_result_record_printed && mi_proceeded)
7885796c8dcSSimon Schubert {
7895796c8dcSSimon Schubert running_result_record_printed = 1;
7905796c8dcSSimon Schubert /* This is what gdb used to do historically -- printing prompt even if
7915796c8dcSSimon Schubert it cannot actually accept any input. This will be surely removed
7925796c8dcSSimon Schubert for MI3, and may be removed even earler. */
7935796c8dcSSimon Schubert /* FIXME: review the use of target_is_async_p here -- is that
7945796c8dcSSimon Schubert what we want? */
7955796c8dcSSimon Schubert if (!target_is_async_p ())
7965796c8dcSSimon Schubert fputs_unfiltered ("(gdb) \n", raw_stdout);
7975796c8dcSSimon Schubert }
7985796c8dcSSimon Schubert gdb_flush (raw_stdout);
7995796c8dcSSimon Schubert }
8005796c8dcSSimon Schubert
8015796c8dcSSimon Schubert static void
mi_solib_loaded(struct so_list * solib)8025796c8dcSSimon Schubert mi_solib_loaded (struct so_list *solib)
8035796c8dcSSimon Schubert {
8045796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
805cf7f2e2dSJohn Marino
8065796c8dcSSimon Schubert target_terminal_ours ();
807*ef5ccd6cSJohn Marino if (gdbarch_has_global_solist (target_gdbarch ()))
8085796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
809cf7f2e2dSJohn Marino "library-loaded,id=\"%s\",target-name=\"%s\","
810cf7f2e2dSJohn Marino "host-name=\"%s\",symbols-loaded=\"%d\"",
8115796c8dcSSimon Schubert solib->so_original_name, solib->so_original_name,
8125796c8dcSSimon Schubert solib->so_name, solib->symbols_loaded);
813cf7f2e2dSJohn Marino else
814cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
815cf7f2e2dSJohn Marino "library-loaded,id=\"%s\",target-name=\"%s\","
816cf7f2e2dSJohn Marino "host-name=\"%s\",symbols-loaded=\"%d\","
817cf7f2e2dSJohn Marino "thread-group=\"i%d\"",
818cf7f2e2dSJohn Marino solib->so_original_name, solib->so_original_name,
819cf7f2e2dSJohn Marino solib->so_name, solib->symbols_loaded,
820cf7f2e2dSJohn Marino current_inferior ()->num);
821cf7f2e2dSJohn Marino
8225796c8dcSSimon Schubert gdb_flush (mi->event_channel);
8235796c8dcSSimon Schubert }
8245796c8dcSSimon Schubert
8255796c8dcSSimon Schubert static void
mi_solib_unloaded(struct so_list * solib)8265796c8dcSSimon Schubert mi_solib_unloaded (struct so_list *solib)
8275796c8dcSSimon Schubert {
8285796c8dcSSimon Schubert struct mi_interp *mi = top_level_interpreter_data ();
829cf7f2e2dSJohn Marino
8305796c8dcSSimon Schubert target_terminal_ours ();
831*ef5ccd6cSJohn Marino if (gdbarch_has_global_solist (target_gdbarch ()))
8325796c8dcSSimon Schubert fprintf_unfiltered (mi->event_channel,
833cf7f2e2dSJohn Marino "library-unloaded,id=\"%s\",target-name=\"%s\","
834cf7f2e2dSJohn Marino "host-name=\"%s\"",
8355796c8dcSSimon Schubert solib->so_original_name, solib->so_original_name,
8365796c8dcSSimon Schubert solib->so_name);
837cf7f2e2dSJohn Marino else
838cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
839cf7f2e2dSJohn Marino "library-unloaded,id=\"%s\",target-name=\"%s\","
840cf7f2e2dSJohn Marino "host-name=\"%s\",thread-group=\"i%d\"",
841cf7f2e2dSJohn Marino solib->so_original_name, solib->so_original_name,
842cf7f2e2dSJohn Marino solib->so_name, current_inferior ()->num);
843cf7f2e2dSJohn Marino
8445796c8dcSSimon Schubert gdb_flush (mi->event_channel);
8455796c8dcSSimon Schubert }
8465796c8dcSSimon Schubert
847*ef5ccd6cSJohn Marino /* Emit notification about the command parameter change. */
848*ef5ccd6cSJohn Marino
849*ef5ccd6cSJohn Marino static void
mi_command_param_changed(const char * param,const char * value)850*ef5ccd6cSJohn Marino mi_command_param_changed (const char *param, const char *value)
851*ef5ccd6cSJohn Marino {
852*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
853*ef5ccd6cSJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
854*ef5ccd6cSJohn Marino
855*ef5ccd6cSJohn Marino if (mi_suppress_notification.cmd_param_changed)
856*ef5ccd6cSJohn Marino return;
857*ef5ccd6cSJohn Marino
858*ef5ccd6cSJohn Marino target_terminal_ours ();
859*ef5ccd6cSJohn Marino
860*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel,
861*ef5ccd6cSJohn Marino "cmd-param-changed");
862*ef5ccd6cSJohn Marino
863*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
864*ef5ccd6cSJohn Marino
865*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "param", param);
866*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "value", value);
867*ef5ccd6cSJohn Marino
868*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, NULL);
869*ef5ccd6cSJohn Marino
870*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
871*ef5ccd6cSJohn Marino }
872*ef5ccd6cSJohn Marino
873*ef5ccd6cSJohn Marino /* Emit notification about the target memory change. */
874*ef5ccd6cSJohn Marino
875*ef5ccd6cSJohn Marino static void
mi_memory_changed(struct inferior * inferior,CORE_ADDR memaddr,ssize_t len,const bfd_byte * myaddr)876*ef5ccd6cSJohn Marino mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
877*ef5ccd6cSJohn Marino ssize_t len, const bfd_byte *myaddr)
878*ef5ccd6cSJohn Marino {
879*ef5ccd6cSJohn Marino struct mi_interp *mi = top_level_interpreter_data ();
880*ef5ccd6cSJohn Marino struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
881*ef5ccd6cSJohn Marino struct obj_section *sec;
882*ef5ccd6cSJohn Marino
883*ef5ccd6cSJohn Marino if (mi_suppress_notification.memory)
884*ef5ccd6cSJohn Marino return;
885*ef5ccd6cSJohn Marino
886*ef5ccd6cSJohn Marino target_terminal_ours ();
887*ef5ccd6cSJohn Marino
888*ef5ccd6cSJohn Marino fprintf_unfiltered (mi->event_channel,
889*ef5ccd6cSJohn Marino "memory-changed");
890*ef5ccd6cSJohn Marino
891*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, mi->event_channel);
892*ef5ccd6cSJohn Marino
893*ef5ccd6cSJohn Marino ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
894*ef5ccd6cSJohn Marino ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
895*ef5ccd6cSJohn Marino ui_out_field_fmt (mi_uiout, "len", "0x%zx", len);
896*ef5ccd6cSJohn Marino
897*ef5ccd6cSJohn Marino /* Append 'type=code' into notification if MEMADDR falls in the range of
898*ef5ccd6cSJohn Marino sections contain code. */
899*ef5ccd6cSJohn Marino sec = find_pc_section (memaddr);
900*ef5ccd6cSJohn Marino if (sec != NULL && sec->objfile != NULL)
901*ef5ccd6cSJohn Marino {
902*ef5ccd6cSJohn Marino flagword flags = bfd_get_section_flags (sec->objfile->obfd,
903*ef5ccd6cSJohn Marino sec->the_bfd_section);
904*ef5ccd6cSJohn Marino
905*ef5ccd6cSJohn Marino if (flags & SEC_CODE)
906*ef5ccd6cSJohn Marino ui_out_field_string (mi_uiout, "type", "code");
907*ef5ccd6cSJohn Marino }
908*ef5ccd6cSJohn Marino
909*ef5ccd6cSJohn Marino ui_out_redirect (mi_uiout, NULL);
910*ef5ccd6cSJohn Marino
911*ef5ccd6cSJohn Marino gdb_flush (mi->event_channel);
912*ef5ccd6cSJohn Marino }
913*ef5ccd6cSJohn Marino
914cf7f2e2dSJohn Marino static int
report_initial_inferior(struct inferior * inf,void * closure)915cf7f2e2dSJohn Marino report_initial_inferior (struct inferior *inf, void *closure)
916cf7f2e2dSJohn Marino {
917cf7f2e2dSJohn Marino /* This function is called from mi_intepreter_init, and since
918cf7f2e2dSJohn Marino mi_inferior_added assumes that inferior is fully initialized
919cf7f2e2dSJohn Marino and top_level_interpreter_data is set, we cannot call
920cf7f2e2dSJohn Marino it here. */
921cf7f2e2dSJohn Marino struct mi_interp *mi = closure;
922cf7f2e2dSJohn Marino
923cf7f2e2dSJohn Marino target_terminal_ours ();
924cf7f2e2dSJohn Marino fprintf_unfiltered (mi->event_channel,
925cf7f2e2dSJohn Marino "thread-group-added,id=\"i%d\"",
926cf7f2e2dSJohn Marino inf->num);
927cf7f2e2dSJohn Marino gdb_flush (mi->event_channel);
928cf7f2e2dSJohn Marino return 0;
929cf7f2e2dSJohn Marino }
9305796c8dcSSimon Schubert
931a45ae5f8SJohn Marino static struct ui_out *
mi_ui_out(struct interp * interp)932a45ae5f8SJohn Marino mi_ui_out (struct interp *interp)
933a45ae5f8SJohn Marino {
934a45ae5f8SJohn Marino struct mi_interp *mi = interp_data (interp);
935a45ae5f8SJohn Marino
936a45ae5f8SJohn Marino return mi->uiout;
937a45ae5f8SJohn Marino }
938a45ae5f8SJohn Marino
939*ef5ccd6cSJohn Marino /* Save the original value of raw_stdout here when logging, so we can
940*ef5ccd6cSJohn Marino restore correctly when done. */
941*ef5ccd6cSJohn Marino
942*ef5ccd6cSJohn Marino static struct ui_file *saved_raw_stdout;
943*ef5ccd6cSJohn Marino
944*ef5ccd6cSJohn Marino /* Do MI-specific logging actions; save raw_stdout, and change all
945*ef5ccd6cSJohn Marino the consoles to use the supplied ui-file(s). */
946*ef5ccd6cSJohn Marino
947*ef5ccd6cSJohn Marino static int
mi_set_logging(struct interp * interp,int start_log,struct ui_file * out,struct ui_file * logfile)948*ef5ccd6cSJohn Marino mi_set_logging (struct interp *interp, int start_log,
949*ef5ccd6cSJohn Marino struct ui_file *out, struct ui_file *logfile)
950*ef5ccd6cSJohn Marino {
951*ef5ccd6cSJohn Marino struct mi_interp *mi = interp_data (interp);
952*ef5ccd6cSJohn Marino
953*ef5ccd6cSJohn Marino if (!mi)
954*ef5ccd6cSJohn Marino return 0;
955*ef5ccd6cSJohn Marino
956*ef5ccd6cSJohn Marino if (start_log)
957*ef5ccd6cSJohn Marino {
958*ef5ccd6cSJohn Marino /* The tee created already is based on gdb_stdout, which for MI
959*ef5ccd6cSJohn Marino is a console and so we end up in an infinite loop of console
960*ef5ccd6cSJohn Marino writing to ui_file writing to console etc. So discard the
961*ef5ccd6cSJohn Marino existing tee (it hasn't been used yet, and MI won't ever use
962*ef5ccd6cSJohn Marino it), and create one based on raw_stdout instead. */
963*ef5ccd6cSJohn Marino if (logfile)
964*ef5ccd6cSJohn Marino {
965*ef5ccd6cSJohn Marino ui_file_delete (out);
966*ef5ccd6cSJohn Marino out = tee_file_new (raw_stdout, 0, logfile, 0);
967*ef5ccd6cSJohn Marino }
968*ef5ccd6cSJohn Marino
969*ef5ccd6cSJohn Marino saved_raw_stdout = raw_stdout;
970*ef5ccd6cSJohn Marino raw_stdout = out;
971*ef5ccd6cSJohn Marino }
972*ef5ccd6cSJohn Marino else
973*ef5ccd6cSJohn Marino {
974*ef5ccd6cSJohn Marino raw_stdout = saved_raw_stdout;
975*ef5ccd6cSJohn Marino saved_raw_stdout = NULL;
976*ef5ccd6cSJohn Marino }
977*ef5ccd6cSJohn Marino
978*ef5ccd6cSJohn Marino mi_console_set_raw (mi->out, raw_stdout);
979*ef5ccd6cSJohn Marino mi_console_set_raw (mi->err, raw_stdout);
980*ef5ccd6cSJohn Marino mi_console_set_raw (mi->log, raw_stdout);
981*ef5ccd6cSJohn Marino mi_console_set_raw (mi->targ, raw_stdout);
982*ef5ccd6cSJohn Marino mi_console_set_raw (mi->event_channel, raw_stdout);
983*ef5ccd6cSJohn Marino
984*ef5ccd6cSJohn Marino return 1;
985*ef5ccd6cSJohn Marino }
986*ef5ccd6cSJohn Marino
9875796c8dcSSimon Schubert extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
9885796c8dcSSimon Schubert
9895796c8dcSSimon Schubert void
_initialize_mi_interp(void)9905796c8dcSSimon Schubert _initialize_mi_interp (void)
9915796c8dcSSimon Schubert {
9925796c8dcSSimon Schubert static const struct interp_procs procs =
9935796c8dcSSimon Schubert {
9945796c8dcSSimon Schubert mi_interpreter_init, /* init_proc */
9955796c8dcSSimon Schubert mi_interpreter_resume, /* resume_proc */
9965796c8dcSSimon Schubert mi_interpreter_suspend, /* suspend_proc */
9975796c8dcSSimon Schubert mi_interpreter_exec, /* exec_proc */
998a45ae5f8SJohn Marino mi_interpreter_prompt_p, /* prompt_proc_p */
999*ef5ccd6cSJohn Marino mi_ui_out, /* ui_out_proc */
1000*ef5ccd6cSJohn Marino mi_set_logging /* set_logging_proc */
10015796c8dcSSimon Schubert };
10025796c8dcSSimon Schubert
10035796c8dcSSimon Schubert /* The various interpreter levels. */
1004a45ae5f8SJohn Marino interp_add (interp_new (INTERP_MI1, &procs));
1005a45ae5f8SJohn Marino interp_add (interp_new (INTERP_MI2, &procs));
1006a45ae5f8SJohn Marino interp_add (interp_new (INTERP_MI3, &procs));
1007a45ae5f8SJohn Marino interp_add (interp_new (INTERP_MI, &procs));
10085796c8dcSSimon Schubert }
1009