Emit inferior, thread and frame selection events to all UIs
[deliverable/binutils-gdb.git] / gdb / mi / mi-interp.c
CommitLineData
4a8f6654
AC
1/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
2
618f726f 3 Copyright (C) 2002-2016 Free Software Foundation, Inc.
4a8f6654
AC
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
4a8f6654
AC
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
4a8f6654
AC
19
20#include "defs.h"
4a8f6654
AC
21#include "interps.h"
22#include "event-top.h"
23#include "event-loop.h"
24#include "inferior.h"
45741a9c 25#include "infrun.h"
4a8f6654
AC
26#include "ui-out.h"
27#include "top.h"
4a8f6654
AC
28#include "mi-main.h"
29#include "mi-cmds.h"
30#include "mi-out.h"
31#include "mi-console.h"
66bb093b 32#include "mi-common.h"
683f2885
VP
33#include "observer.h"
34#include "gdbthread.h"
c86cf029 35#include "solist.h"
8d3788bd 36#include "gdb.h"
8de0566d 37#include "objfiles.h"
134a2066 38#include "tracepoint.h"
17b2616c 39#include "cli-out.h"
243a9253 40#include "thread-fsm.h"
26cde2cc 41#include "cli/cli-interp.h"
4a8f6654 42
2b03b41d
SS
43/* These are the interpreter setup, etc. functions for the MI
44 interpreter. */
45
ee047554 46static void mi_execute_command_wrapper (const char *cmd);
e837f12a 47static void mi_execute_command_input_handler (char *cmd);
4a8f6654
AC
48
49/* These are hooks that we put in place while doing interpreter_exec
2b03b41d
SS
50 so we can report interesting things that happened "behind the MI's
51 back" in this command. */
52
bee0189a 53static int mi_interp_query_hook (const char *ctlstr, va_list ap)
2b03b41d 54 ATTRIBUTE_PRINTF (1, 0);
4a8f6654 55
4a8f6654
AC
56static void mi_insert_notify_hooks (void);
57static void mi_remove_notify_hooks (void);
fd664c91
PA
58
59static void mi_on_signal_received (enum gdb_signal siggnal);
60static void mi_on_end_stepping_range (void);
61static void mi_on_signal_exited (enum gdb_signal siggnal);
62static void mi_on_exited (int exitstatus);
1d33d6ba 63static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
fd664c91 64static void mi_on_no_history (void);
4a8f6654 65
683f2885 66static void mi_new_thread (struct thread_info *t);
a07daef3 67static void mi_thread_exit (struct thread_info *t, int silent);
38b022b4
SM
68static void mi_record_changed (struct inferior*, int, const char *,
69 const char *);
a79b8f6e
VP
70static void mi_inferior_added (struct inferior *inf);
71static void mi_inferior_appeared (struct inferior *inf);
72static void mi_inferior_exit (struct inferior *inf);
73static void mi_inferior_removed (struct inferior *inf);
e1ac3328 74static void mi_on_resume (ptid_t ptid);
c86cf029
VP
75static void mi_solib_loaded (struct so_list *solib);
76static void mi_solib_unloaded (struct so_list *solib);
f3b1572e 77static void mi_about_to_proceed (void);
201b4506 78static void mi_traceframe_changed (int tfnum, int tpnum);
134a2066
YQ
79static void mi_tsv_created (const struct trace_state_variable *tsv);
80static void mi_tsv_deleted (const struct trace_state_variable *tsv);
81static void mi_tsv_modified (const struct trace_state_variable *tsv);
8d3788bd
VP
82static void mi_breakpoint_created (struct breakpoint *b);
83static void mi_breakpoint_deleted (struct breakpoint *b);
84static void mi_breakpoint_modified (struct breakpoint *b);
5b9afe8a 85static void mi_command_param_changed (const char *param, const char *value);
8de0566d
YQ
86static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
87 ssize_t len, const bfd_byte *myaddr);
329ea579 88static void mi_on_sync_execution_done (void);
683f2885 89
a79b8f6e
VP
90static int report_initial_inferior (struct inferior *inf, void *closure);
91
05beb275
PA
92/* Display the MI prompt. */
93
94static void
9204d692 95display_mi_prompt (struct mi_interp *mi)
05beb275 96{
3b12939d
PA
97 struct ui *ui = current_ui;
98
9204d692
PA
99 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
100 gdb_flush (mi->raw_stdout);
3b12939d 101 ui->prompt_state = PROMPTED;
05beb275
PA
102}
103
73ab01a0
PA
104/* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
105 returns NULL otherwise. */
106
107static struct mi_interp *
108as_mi_interp (struct interp *interp)
109{
110 if (ui_out_is_mi_like_p (interp_ui_out (interp)))
111 return (struct mi_interp *) interp_data (interp);
112 return NULL;
113}
114
4a8f6654 115static void *
4801a9a3 116mi_interpreter_init (struct interp *interp, int top_level)
4a8f6654 117{
70ba0933 118 struct mi_interp *mi = XNEW (struct mi_interp);
4801a9a3
PA
119 const char *name;
120 int mi_version;
4a8f6654 121
9204d692
PA
122 /* Store the current output channel, so that we can create a console
123 channel that encapsulates and prefixes all gdb_output-type bits
124 coming from the rest of the debugger. */
125 mi->raw_stdout = gdb_stdout;
4a8f6654 126
2b03b41d
SS
127 /* Create MI console channels, each with a different prefix so they
128 can be distinguished. */
9204d692
PA
129 mi->out = mi_console_file_new (mi->raw_stdout, "~", '"');
130 mi->err = mi_console_file_new (mi->raw_stdout, "&", '"');
4a8f6654 131 mi->log = mi->err;
9204d692
PA
132 mi->targ = mi_console_file_new (mi->raw_stdout, "@", '"');
133 mi->event_channel = mi_console_file_new (mi->raw_stdout, "=", 0);
4a8f6654 134
4801a9a3
PA
135 name = interp_name (interp);
136 /* INTERP_MI selects the most recent released version. "mi2" was
137 released as part of GDB 6.0. */
138 if (strcmp (name, INTERP_MI) == 0)
139 mi_version = 2;
140 else if (strcmp (name, INTERP_MI1) == 0)
141 mi_version = 1;
142 else if (strcmp (name, INTERP_MI2) == 0)
143 mi_version = 2;
144 else if (strcmp (name, INTERP_MI3) == 0)
145 mi_version = 3;
146 else
147 gdb_assert_not_reached ("unhandled MI version");
148
fd664c91
PA
149 mi->mi_uiout = mi_out_new (mi_version);
150 mi->cli_uiout = cli_out_new (mi->out);
151
683f2885 152 if (top_level)
063bfe2e 153 {
2b03b41d
SS
154 /* The initial inferior is created before this function is
155 called, so we need to report it explicitly. Use iteration in
156 case future version of GDB creates more than one inferior
157 up-front. */
a79b8f6e 158 iterate_over_inferiors (report_initial_inferior, mi);
063bfe2e 159 }
683f2885 160
4a8f6654
AC
161 return mi;
162}
163
164static int
165mi_interpreter_resume (void *data)
166{
19ba03f4 167 struct mi_interp *mi = (struct mi_interp *) data;
a74e1786 168 struct ui *ui = current_ui;
4a8f6654 169
2b03b41d
SS
170 /* As per hack note in mi_interpreter_init, swap in the output
171 channels... */
3c216924 172 gdb_setup_readline (0);
4a8f6654 173
a74e1786
PA
174 ui->call_readline = gdb_readline_no_editing_callback;
175 ui->input_handler = mi_execute_command_input_handler;
4a8f6654
AC
176
177 gdb_stdout = mi->out;
2b03b41d 178 /* Route error and log output through the MI. */
4a8f6654
AC
179 gdb_stderr = mi->err;
180 gdb_stdlog = mi->log;
2b03b41d 181 /* Route target output through the MI. */
4a8f6654 182 gdb_stdtarg = mi->targ;
2b03b41d 183 /* Route target error through the MI as well. */
1f20321b 184 gdb_stdtargerr = mi->targ;
4a8f6654
AC
185
186 /* Replace all the hooks that we know about. There really needs to
187 be a better way of doing this... */
188 clear_interpreter_hooks ();
189
9a4105ab 190 deprecated_show_load_progress = mi_load_progress;
4a8f6654 191
4a8f6654
AC
192 return 1;
193}
194
195static int
196mi_interpreter_suspend (void *data)
197{
198 gdb_disable_readline ();
199 return 1;
200}
201
71fff37b 202static struct gdb_exception
4a8f6654
AC
203mi_interpreter_exec (void *data, const char *command)
204{
ee047554 205 mi_execute_command_wrapper (command);
c1043fc2 206 return exception_none;
4a8f6654
AC
207}
208
ce8f13f8 209void
4a8f6654
AC
210mi_cmd_interpreter_exec (char *command, char **argv, int argc)
211{
212 struct interp *interp_to_use;
4a8f6654 213 int i;
a13e061a
PA
214 char *mi_error_message = NULL;
215 struct cleanup *old_chain;
4a8f6654
AC
216
217 if (argc < 2)
1b05df00 218 error (_("-interpreter-exec: "
9b20d036 219 "Usage: -interpreter-exec interp command"));
4a8f6654 220
8322445e 221 interp_to_use = interp_lookup (current_ui, argv[0]);
4a8f6654 222 if (interp_to_use == NULL)
1b05df00 223 error (_("-interpreter-exec: could not find interpreter \"%s\""),
9a2b4c1b 224 argv[0]);
4a8f6654 225
17b2616c
PA
226 /* Note that unlike the CLI version of this command, we don't
227 actually set INTERP_TO_USE as the current interpreter, as we
228 still want gdb_stdout, etc. to point at MI streams. */
229
2b03b41d
SS
230 /* Insert the MI out hooks, making sure to also call the
231 interpreter's hooks if it has any. */
232 /* KRS: We shouldn't need this... Events should be installed and
233 they should just ALWAYS fire something out down the MI
234 channel. */
4a8f6654
AC
235 mi_insert_notify_hooks ();
236
2b03b41d 237 /* Now run the code. */
4a8f6654 238
a13e061a 239 old_chain = make_cleanup (null_cleanup, 0);
4a8f6654
AC
240 for (i = 1; i < argc; i++)
241 {
32c1e744 242 struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
102040f0 243
32c1e744
VP
244 if (e.reason < 0)
245 {
246 mi_error_message = xstrdup (e.message);
a13e061a 247 make_cleanup (xfree, mi_error_message);
32c1e744
VP
248 break;
249 }
4a8f6654
AC
250 }
251
252 mi_remove_notify_hooks ();
253
a13e061a
PA
254 if (mi_error_message != NULL)
255 error ("%s", mi_error_message);
256 do_cleanups (old_chain);
4a8f6654
AC
257}
258
2b03b41d
SS
259/* This inserts a number of hooks that are meant to produce
260 async-notify ("=") MI messages while running commands in another
261 interpreter using mi_interpreter_exec. The canonical use for this
262 is to allow access to the gdb CLI interpreter from within the MI,
263 while still producing MI style output when actions in the CLI
264 command change GDB's state. */
4a8f6654
AC
265
266static void
267mi_insert_notify_hooks (void)
268{
9a4105ab 269 deprecated_query_hook = mi_interp_query_hook;
4a8f6654
AC
270}
271
272static void
11308a41 273mi_remove_notify_hooks (void)
4a8f6654 274{
9a4105ab 275 deprecated_query_hook = NULL;
4a8f6654
AC
276}
277
278static int
279mi_interp_query_hook (const char *ctlstr, va_list ap)
280{
281 return 1;
282}
283
4a8f6654 284static void
ee047554 285mi_execute_command_wrapper (const char *cmd)
4a8f6654 286{
f38d3ad1
PA
287 struct ui *ui = current_ui;
288
268a799a 289 mi_execute_command (cmd, ui->instream == ui->stdin_stream);
4a8f6654
AC
290}
291
329ea579
PA
292/* Observer for the synchronous_command_done notification. */
293
294static void
295mi_on_sync_execution_done (void)
296{
73ab01a0
PA
297 struct ui *ui = current_ui;
298 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
299
300 if (mi == NULL)
301 return;
302
0b333c5e
PA
303 /* If MI is sync, then output the MI prompt now, indicating we're
304 ready for further input. */
329ea579 305 if (!mi_async_p ())
9204d692 306 display_mi_prompt (mi);
329ea579
PA
307}
308
e837f12a
JK
309/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
310
311static void
312mi_execute_command_input_handler (char *cmd)
313{
9204d692 314 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
3b12939d
PA
315 struct ui *ui = current_ui;
316
317 ui->prompt_state = PROMPT_NEEDED;
9204d692 318
e837f12a
JK
319 mi_execute_command_wrapper (cmd);
320
0b333c5e
PA
321 /* Print a prompt, indicating we're ready for further input, unless
322 we just started a synchronous command. In that case, we're about
323 to go back to the event loop and will output the prompt in the
324 'synchronous_command_done' observer when the target next
325 stops. */
3b12939d 326 if (ui->prompt_state == PROMPT_NEEDED)
9204d692 327 display_mi_prompt (mi);
e837f12a
JK
328}
329
4a8f6654 330static void
b2d86570 331mi_interpreter_pre_command_loop (struct interp *self)
4a8f6654 332{
b2d86570 333 struct mi_interp *mi = (struct mi_interp *) interp_data (self);
9204d692 334
4a8f6654 335 /* Turn off 8 bit strings in quoted output. Any character with the
2b03b41d 336 high bit set is printed using C's octal format. */
4a8f6654 337 sevenbit_strings = 1;
2b03b41d
SS
338
339 /* Tell the world that we're alive. */
9204d692 340 display_mi_prompt (mi);
4a8f6654
AC
341}
342
683f2885
VP
343static void
344mi_new_thread (struct thread_info *t)
345{
c9657e70 346 struct inferior *inf = find_inferior_ptid (t->ptid);
73ab01a0 347 struct switch_thru_all_uis state;
a79b8f6e
VP
348
349 gdb_assert (inf);
683f2885 350
73ab01a0
PA
351 SWITCH_THRU_ALL_UIS (state)
352 {
353 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
354 struct cleanup *old_chain;
5fe96654 355
73ab01a0
PA
356 if (mi == NULL)
357 continue;
5fe96654 358
73ab01a0
PA
359 old_chain = make_cleanup_restore_target_terminal ();
360 target_terminal_ours_for_output ();
361
362 fprintf_unfiltered (mi->event_channel,
363 "thread-created,id=\"%d\",group-id=\"i%d\"",
364 t->global_num, inf->num);
365 gdb_flush (mi->event_channel);
366
367 do_cleanups (old_chain);
368 }
683f2885
VP
369}
370
063bfe2e 371static void
a07daef3 372mi_thread_exit (struct thread_info *t, int silent)
063bfe2e 373{
73ab01a0 374 struct switch_thru_all_uis state;
a07daef3
PA
375
376 if (silent)
377 return;
378
73ab01a0
PA
379 SWITCH_THRU_ALL_UIS (state)
380 {
381 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
382 struct cleanup *old_chain;
a79b8f6e 383
73ab01a0
PA
384 if (mi == NULL)
385 continue;
5fe96654 386
73ab01a0
PA
387 old_chain = make_cleanup_restore_target_terminal ();
388 target_terminal_ours_for_output ();
389 fprintf_unfiltered (mi->event_channel,
390 "thread-exited,id=\"%d\",group-id=\"i%d\"",
391 t->global_num, t->inf->num);
392 gdb_flush (mi->event_channel);
1abf3a14 393
73ab01a0
PA
394 do_cleanups (old_chain);
395 }
063bfe2e
VP
396}
397
82a90ccf
YQ
398/* Emit notification on changing the state of record. */
399
400static void
38b022b4
SM
401mi_record_changed (struct inferior *inferior, int started, const char *method,
402 const char *format)
82a90ccf 403{
73ab01a0 404 struct switch_thru_all_uis state;
82a90ccf 405
73ab01a0 406 SWITCH_THRU_ALL_UIS (state)
38b022b4 407 {
73ab01a0
PA
408 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
409 struct cleanup *old_chain;
410
411 if (mi == NULL)
412 continue;
413
414 old_chain = make_cleanup_restore_target_terminal ();
415 target_terminal_ours_for_output ();
416
417 if (started)
1aec0b6a 418 {
73ab01a0
PA
419 if (format != NULL)
420 {
421 fprintf_unfiltered (mi->event_channel,
422 "record-started,thread-group=\"i%d\","
423 "method=\"%s\",format=\"%s\"",
424 inferior->num, method, format);
425 }
426 else
427 {
428 fprintf_unfiltered (mi->event_channel,
429 "record-started,thread-group=\"i%d\","
430 "method=\"%s\"",
431 inferior->num, method);
432 }
1aec0b6a 433 }
38b022b4 434 else
1aec0b6a 435 {
73ab01a0
PA
436 fprintf_unfiltered (mi->event_channel,
437 "record-stopped,thread-group=\"i%d\"",
438 inferior->num);
1aec0b6a 439 }
38b022b4 440
73ab01a0 441 gdb_flush (mi->event_channel);
82a90ccf 442
73ab01a0
PA
443 do_cleanups (old_chain);
444 }
82a90ccf
YQ
445}
446
a79b8f6e
VP
447static void
448mi_inferior_added (struct inferior *inf)
449{
73ab01a0 450 struct switch_thru_all_uis state;
5fe96654 451
73ab01a0
PA
452 SWITCH_THRU_ALL_UIS (state)
453 {
454 struct interp *interp;
455 struct mi_interp *mi;
456 struct cleanup *old_chain;
102040f0 457
73ab01a0
PA
458 /* We'll be called once for the initial inferior, before the top
459 level interpreter is set. */
460 interp = top_level_interpreter ();
461 if (interp == NULL)
462 continue;
5fe96654 463
73ab01a0
PA
464 mi = as_mi_interp (interp);
465 if (mi == NULL)
466 continue;
467
468 old_chain = make_cleanup_restore_target_terminal ();
469 target_terminal_ours_for_output ();
470
471 fprintf_unfiltered (mi->event_channel,
472 "thread-group-added,id=\"i%d\"",
473 inf->num);
474 gdb_flush (mi->event_channel);
475
476 do_cleanups (old_chain);
477 }
a79b8f6e
VP
478}
479
480static void
481mi_inferior_appeared (struct inferior *inf)
4a92f99b 482{
73ab01a0 483 struct switch_thru_all_uis state;
5fe96654 484
73ab01a0
PA
485 SWITCH_THRU_ALL_UIS (state)
486 {
487 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
488 struct cleanup *old_chain;
102040f0 489
73ab01a0
PA
490 if (mi == NULL)
491 continue;
5fe96654 492
73ab01a0
PA
493 old_chain = make_cleanup_restore_target_terminal ();
494 target_terminal_ours_for_output ();
495
496 fprintf_unfiltered (mi->event_channel,
497 "thread-group-started,id=\"i%d\",pid=\"%d\"",
498 inf->num, inf->pid);
499 gdb_flush (mi->event_channel);
500 do_cleanups (old_chain);
501 }
4a92f99b
VP
502}
503
504static void
a79b8f6e 505mi_inferior_exit (struct inferior *inf)
4a92f99b 506{
73ab01a0 507 struct switch_thru_all_uis state;
5fe96654 508
73ab01a0
PA
509 SWITCH_THRU_ALL_UIS (state)
510 {
511 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
512 struct cleanup *old_chain;
102040f0 513
73ab01a0
PA
514 if (mi == NULL)
515 continue;
8cf64490 516
73ab01a0
PA
517 old_chain = make_cleanup_restore_target_terminal ();
518 target_terminal_ours_for_output ();
519
520 if (inf->has_exit_code)
521 fprintf_unfiltered (mi->event_channel,
522 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
523 inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
524 else
525 fprintf_unfiltered (mi->event_channel,
526 "thread-group-exited,id=\"i%d\"", inf->num);
527
528 gdb_flush (mi->event_channel);
529 do_cleanups (old_chain);
530 }
4a92f99b
VP
531}
532
a79b8f6e
VP
533static void
534mi_inferior_removed (struct inferior *inf)
535{
73ab01a0 536 struct switch_thru_all_uis state;
5fe96654 537
73ab01a0
PA
538 SWITCH_THRU_ALL_UIS (state)
539 {
540 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
541 struct cleanup *old_chain;
102040f0 542
73ab01a0
PA
543 if (mi == NULL)
544 continue;
5fe96654 545
73ab01a0
PA
546 old_chain = make_cleanup_restore_target_terminal ();
547 target_terminal_ours_for_output ();
548
549 fprintf_unfiltered (mi->event_channel,
550 "thread-group-removed,id=\"i%d\"",
551 inf->num);
552 gdb_flush (mi->event_channel);
553
554 do_cleanups (old_chain);
555 }
a79b8f6e
VP
556}
557
fd664c91
PA
558/* Return the MI interpreter, if it is active -- either because it's
559 the top-level interpreter or the interpreter executing the current
560 command. Returns NULL if the MI interpreter is not being used. */
561
73ab01a0
PA
562static struct mi_interp *
563find_mi_interp (void)
fd664c91 564{
73ab01a0 565 struct mi_interp *mi;
fd664c91 566
73ab01a0
PA
567 mi = as_mi_interp (top_level_interpreter ());
568 if (mi != NULL)
569 return mi;
fd664c91 570
73ab01a0
PA
571 mi = as_mi_interp (command_interp ());
572 if (mi != NULL)
573 return mi;
fd664c91 574
fd664c91
PA
575 return NULL;
576}
577
578/* Observers for several run control events that print why the
579 inferior has stopped to both the the MI event channel and to the MI
580 console. If the MI interpreter is not active, print nothing. */
581
582/* Observer for the signal_received notification. */
583
584static void
585mi_on_signal_received (enum gdb_signal siggnal)
586{
73ab01a0 587 struct switch_thru_all_uis state;
fd664c91 588
73ab01a0
PA
589 SWITCH_THRU_ALL_UIS (state)
590 {
591 struct mi_interp *mi = find_mi_interp ();
592
593 if (mi == NULL)
594 continue;
fd664c91 595
73ab01a0
PA
596 print_signal_received_reason (mi->mi_uiout, siggnal);
597 print_signal_received_reason (mi->cli_uiout, siggnal);
598 }
fd664c91
PA
599}
600
601/* Observer for the end_stepping_range notification. */
602
603static void
604mi_on_end_stepping_range (void)
605{
73ab01a0 606 struct switch_thru_all_uis state;
fd664c91 607
73ab01a0
PA
608 SWITCH_THRU_ALL_UIS (state)
609 {
610 struct mi_interp *mi = find_mi_interp ();
611
612 if (mi == NULL)
613 continue;
fd664c91 614
73ab01a0
PA
615 print_end_stepping_range_reason (mi->mi_uiout);
616 print_end_stepping_range_reason (mi->cli_uiout);
617 }
fd664c91
PA
618}
619
620/* Observer for the signal_exited notification. */
17b2616c
PA
621
622static void
fd664c91 623mi_on_signal_exited (enum gdb_signal siggnal)
17b2616c 624{
73ab01a0 625 struct switch_thru_all_uis state;
17b2616c 626
73ab01a0
PA
627 SWITCH_THRU_ALL_UIS (state)
628 {
629 struct mi_interp *mi = find_mi_interp ();
630
631 if (mi == NULL)
632 continue;
fd664c91 633
73ab01a0
PA
634 print_signal_exited_reason (mi->mi_uiout, siggnal);
635 print_signal_exited_reason (mi->cli_uiout, siggnal);
636 }
fd664c91
PA
637}
638
639/* Observer for the exited notification. */
640
641static void
642mi_on_exited (int exitstatus)
643{
73ab01a0 644 struct switch_thru_all_uis state;
fd664c91 645
73ab01a0
PA
646 SWITCH_THRU_ALL_UIS (state)
647 {
648 struct mi_interp *mi = find_mi_interp ();
649
650 if (mi == NULL)
651 continue;
fd664c91 652
73ab01a0
PA
653 print_exited_reason (mi->mi_uiout, exitstatus);
654 print_exited_reason (mi->cli_uiout, exitstatus);
655 }
fd664c91
PA
656}
657
658/* Observer for the no_history notification. */
659
660static void
661mi_on_no_history (void)
662{
73ab01a0 663 struct switch_thru_all_uis state;
fd664c91 664
73ab01a0
PA
665 SWITCH_THRU_ALL_UIS (state)
666 {
667 struct mi_interp *mi = find_mi_interp ();
fd664c91 668
73ab01a0
PA
669 if (mi == NULL)
670 continue;
671
672 print_no_history_reason (mi->mi_uiout);
673 print_no_history_reason (mi->cli_uiout);
674 }
17b2616c
PA
675}
676
f7f9a841 677static void
73ab01a0 678mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
f7f9a841
VP
679{
680 /* Since this can be called when CLI command is executing,
681 using cli interpreter, be sure to use MI uiout for output,
682 not the current one. */
1d33d6ba 683 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
9204d692 684 struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
f7f9a841 685
1d33d6ba
VP
686 if (print_frame)
687 {
243a9253 688 struct thread_info *tp;
dc146f7c 689 int core;
26cde2cc 690 struct interp *console_interp;
102040f0 691
243a9253 692 tp = inferior_thread ();
36dfb11c 693
243a9253
PA
694 if (tp->thread_fsm != NULL
695 && thread_fsm_finished_p (tp->thread_fsm))
696 {
697 enum async_reply_reason reason;
36dfb11c 698
243a9253
PA
699 reason = thread_fsm_async_reply_reason (tp->thread_fsm);
700 ui_out_field_string (mi_uiout, "reason",
701 async_reason_lookup (reason));
1d33d6ba 702 }
243a9253
PA
703 print_stop_event (mi_uiout);
704
26cde2cc
PA
705 console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
706 if (should_print_stop_to_console (console_interp, tp))
9204d692 707 print_stop_event (mi->cli_uiout);
1d33d6ba 708
5d5658a1 709 ui_out_field_int (mi_uiout, "thread-id", tp->global_num);
1d33d6ba
VP
710 if (non_stop)
711 {
712 struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
713 (mi_uiout, "stopped-threads");
102040f0 714
5d5658a1 715 ui_out_field_int (mi_uiout, NULL, tp->global_num);
1d33d6ba
VP
716 do_cleanups (back_to);
717 }
718 else
719 ui_out_field_string (mi_uiout, "stopped-threads", "all");
dc146f7c
VP
720
721 core = target_core_of_thread (inferior_ptid);
722 if (core != -1)
723 ui_out_field_int (mi_uiout, "core", core);
1d33d6ba
VP
724 }
725
9204d692
PA
726 fputs_unfiltered ("*stopped", mi->raw_stdout);
727 mi_out_put (mi_uiout, mi->raw_stdout);
1d33d6ba 728 mi_out_rewind (mi_uiout);
9204d692
PA
729 mi_print_timing_maybe (mi->raw_stdout);
730 fputs_unfiltered ("\n", mi->raw_stdout);
731 gdb_flush (mi->raw_stdout);
f7f9a841
VP
732}
733
73ab01a0
PA
734static void
735mi_on_normal_stop (struct bpstats *bs, int print_frame)
736{
737 struct switch_thru_all_uis state;
738
739 SWITCH_THRU_ALL_UIS (state)
740 {
741 if (as_mi_interp (top_level_interpreter ()) == NULL)
742 continue;
743
744 mi_on_normal_stop_1 (bs, print_frame);
745 }
746}
747
f3b1572e
PA
748static void
749mi_about_to_proceed (void)
750{
751 /* Suppress output while calling an inferior function. */
752
753 if (!ptid_equal (inferior_ptid, null_ptid))
754 {
755 struct thread_info *tp = inferior_thread ();
102040f0 756
16c381f0 757 if (tp->control.in_infcall)
f3b1572e
PA
758 return;
759 }
760
761 mi_proceeded = 1;
762}
763
5b9afe8a
YQ
764/* When the element is non-zero, no MI notifications will be emitted in
765 response to the corresponding observers. */
2b03b41d 766
5b9afe8a
YQ
767struct mi_suppress_notification mi_suppress_notification =
768 {
769 0,
770 0,
201b4506 771 0,
4034d0ff 772 0,
5b9afe8a 773 };
8d3788bd 774
201b4506
YQ
775/* Emit notification on changing a traceframe. */
776
777static void
778mi_traceframe_changed (int tfnum, int tpnum)
779{
73ab01a0 780 struct switch_thru_all_uis state;
201b4506
YQ
781
782 if (mi_suppress_notification.traceframe)
783 return;
784
73ab01a0
PA
785 SWITCH_THRU_ALL_UIS (state)
786 {
787 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
788 struct cleanup *old_chain;
201b4506 789
73ab01a0
PA
790 if (mi == NULL)
791 continue;
201b4506 792
73ab01a0
PA
793 old_chain = make_cleanup_restore_target_terminal ();
794 target_terminal_ours_for_output ();
5fe96654 795
73ab01a0
PA
796 if (tfnum >= 0)
797 fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
798 "num=\"%d\",tracepoint=\"%d\"\n",
799 tfnum, tpnum);
800 else
801 fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
802
803 gdb_flush (mi->event_channel);
804
805 do_cleanups (old_chain);
806 }
201b4506
YQ
807}
808
bb25a15c
YQ
809/* Emit notification on creating a trace state variable. */
810
811static void
134a2066 812mi_tsv_created (const struct trace_state_variable *tsv)
bb25a15c 813{
73ab01a0 814 struct switch_thru_all_uis state;
bb25a15c 815
73ab01a0
PA
816 SWITCH_THRU_ALL_UIS (state)
817 {
818 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
819 struct cleanup *old_chain;
bb25a15c 820
73ab01a0
PA
821 if (mi == NULL)
822 continue;
bb25a15c 823
73ab01a0
PA
824 old_chain = make_cleanup_restore_target_terminal ();
825 target_terminal_ours_for_output ();
5fe96654 826
73ab01a0
PA
827 fprintf_unfiltered (mi->event_channel, "tsv-created,"
828 "name=\"%s\",initial=\"%s\"\n",
829 tsv->name, plongest (tsv->initial_value));
830
831 gdb_flush (mi->event_channel);
832
833 do_cleanups (old_chain);
834 }
bb25a15c
YQ
835}
836
837/* Emit notification on deleting a trace state variable. */
838
839static void
134a2066 840mi_tsv_deleted (const struct trace_state_variable *tsv)
bb25a15c 841{
73ab01a0 842 struct switch_thru_all_uis state;
bb25a15c 843
73ab01a0
PA
844 SWITCH_THRU_ALL_UIS (state)
845 {
846 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
847 struct cleanup *old_chain;
bb25a15c 848
73ab01a0
PA
849 if (mi == NULL)
850 continue;
bb25a15c 851
73ab01a0
PA
852 old_chain = make_cleanup_restore_target_terminal ();
853 target_terminal_ours_for_output ();
5fe96654 854
73ab01a0
PA
855 if (tsv != NULL)
856 fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
857 "name=\"%s\"\n", tsv->name);
858 else
859 fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
860
861 gdb_flush (mi->event_channel);
862
863 do_cleanups (old_chain);
864 }
bb25a15c
YQ
865}
866
134a2066
YQ
867/* Emit notification on modifying a trace state variable. */
868
869static void
870mi_tsv_modified (const struct trace_state_variable *tsv)
871{
73ab01a0 872 struct switch_thru_all_uis state;
134a2066 873
73ab01a0
PA
874 SWITCH_THRU_ALL_UIS (state)
875 {
876 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
877 struct ui_out *mi_uiout;
878 struct cleanup *old_chain;
134a2066 879
73ab01a0
PA
880 if (mi == NULL)
881 continue;
134a2066 882
73ab01a0 883 mi_uiout = interp_ui_out (top_level_interpreter ());
134a2066 884
73ab01a0
PA
885 old_chain = make_cleanup_restore_target_terminal ();
886 target_terminal_ours_for_output ();
134a2066 887
73ab01a0
PA
888 fprintf_unfiltered (mi->event_channel,
889 "tsv-modified");
134a2066 890
73ab01a0 891 ui_out_redirect (mi_uiout, mi->event_channel);
5fe96654 892
73ab01a0
PA
893 ui_out_field_string (mi_uiout, "name", tsv->name);
894 ui_out_field_string (mi_uiout, "initial",
895 plongest (tsv->initial_value));
896 if (tsv->value_known)
897 ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
898
899 ui_out_redirect (mi_uiout, NULL);
900
901 gdb_flush (mi->event_channel);
902
903 do_cleanups (old_chain);
904 }
134a2066
YQ
905}
906
8d3788bd 907/* Emit notification about a created breakpoint. */
2b03b41d 908
8d3788bd
VP
909static void
910mi_breakpoint_created (struct breakpoint *b)
911{
73ab01a0 912 struct switch_thru_all_uis state;
8d3788bd 913
5b9afe8a 914 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
915 return;
916
917 if (b->number <= 0)
918 return;
919
73ab01a0 920 SWITCH_THRU_ALL_UIS (state)
492d29ea 921 {
73ab01a0
PA
922 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
923 struct ui_out *mi_uiout;
924 struct cleanup *old_chain;
492d29ea 925
73ab01a0
PA
926 if (mi == NULL)
927 continue;
8d3788bd 928
73ab01a0 929 mi_uiout = interp_ui_out (top_level_interpreter ());
5fe96654 930
73ab01a0
PA
931 old_chain = make_cleanup_restore_target_terminal ();
932 target_terminal_ours_for_output ();
933
934 fprintf_unfiltered (mi->event_channel,
935 "breakpoint-created");
936 /* We want the output from gdb_breakpoint_query to go to
937 mi->event_channel. One approach would be to just call
938 gdb_breakpoint_query, and then use mi_out_put to send the current
939 content of mi_outout into mi->event_channel. However, that will
940 break if anything is output to mi_uiout prior to calling the
941 breakpoint_created notifications. So, we use
942 ui_out_redirect. */
943 ui_out_redirect (mi_uiout, mi->event_channel);
944 TRY
945 {
946 gdb_breakpoint_query (mi_uiout, b->number, NULL);
947 }
948 CATCH (e, RETURN_MASK_ERROR)
949 {
950 }
951 END_CATCH
952
953 ui_out_redirect (mi_uiout, NULL);
954
955 gdb_flush (mi->event_channel);
956
957 do_cleanups (old_chain);
958 }
8d3788bd
VP
959}
960
961/* Emit notification about deleted breakpoint. */
2b03b41d 962
8d3788bd
VP
963static void
964mi_breakpoint_deleted (struct breakpoint *b)
965{
73ab01a0 966 struct switch_thru_all_uis state;
8d3788bd 967
5b9afe8a 968 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
969 return;
970
971 if (b->number <= 0)
972 return;
973
73ab01a0
PA
974 SWITCH_THRU_ALL_UIS (state)
975 {
976 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
977 struct cleanup *old_chain;
8d3788bd 978
73ab01a0
PA
979 if (mi == NULL)
980 continue;
8d3788bd 981
73ab01a0
PA
982 old_chain = make_cleanup_restore_target_terminal ();
983 target_terminal_ours_for_output ();
5fe96654 984
73ab01a0
PA
985 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
986 b->number);
987
988 gdb_flush (mi->event_channel);
989
990 do_cleanups (old_chain);
991 }
8d3788bd
VP
992}
993
994/* Emit notification about modified breakpoint. */
2b03b41d 995
8d3788bd
VP
996static void
997mi_breakpoint_modified (struct breakpoint *b)
998{
73ab01a0 999 struct switch_thru_all_uis state;
8d3788bd 1000
5b9afe8a 1001 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
1002 return;
1003
1004 if (b->number <= 0)
1005 return;
1006
73ab01a0 1007 SWITCH_THRU_ALL_UIS (state)
492d29ea 1008 {
73ab01a0
PA
1009 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1010 struct cleanup *old_chain;
492d29ea 1011
73ab01a0
PA
1012 if (mi == NULL)
1013 continue;
8d3788bd 1014
73ab01a0
PA
1015 old_chain = make_cleanup_restore_target_terminal ();
1016 target_terminal_ours_for_output ();
1017 fprintf_unfiltered (mi->event_channel,
1018 "breakpoint-modified");
1019 /* We want the output from gdb_breakpoint_query to go to
1020 mi->event_channel. One approach would be to just call
1021 gdb_breakpoint_query, and then use mi_out_put to send the current
1022 content of mi_outout into mi->event_channel. However, that will
1023 break if anything is output to mi_uiout prior to calling the
1024 breakpoint_created notifications. So, we use
1025 ui_out_redirect. */
1026 ui_out_redirect (mi->mi_uiout, mi->event_channel);
1027 TRY
1028 {
1029 gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
1030 }
1031 CATCH (e, RETURN_MASK_ERROR)
1032 {
1033 }
1034 END_CATCH
5fe96654 1035
73ab01a0
PA
1036 ui_out_redirect (mi->mi_uiout, NULL);
1037
1038 gdb_flush (mi->event_channel);
1039
1040 do_cleanups (old_chain);
1041 }
8d3788bd
VP
1042}
1043
d90e17a7
PA
1044static int
1045mi_output_running_pid (struct thread_info *info, void *arg)
1046{
19ba03f4 1047 ptid_t *ptid = (ptid_t *) arg;
73ab01a0 1048 struct switch_thru_all_uis state;
d90e17a7 1049
73ab01a0
PA
1050 SWITCH_THRU_ALL_UIS (state)
1051 {
1052 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1053
1054 if (mi == NULL)
1055 continue;
1056
1057 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
9204d692 1058 fprintf_unfiltered (mi->raw_stdout,
73ab01a0
PA
1059 "*running,thread-id=\"%d\"\n",
1060 info->global_num);
1061 }
d90e17a7
PA
1062
1063 return 0;
1064}
1065
1066static int
1067mi_inferior_count (struct inferior *inf, void *arg)
1068{
1069 if (inf->pid != 0)
1070 {
19ba03f4 1071 int *count_p = (int *) arg;
d90e17a7
PA
1072 (*count_p)++;
1073 }
1074
1075 return 0;
1076}
1077
e1ac3328 1078static void
9204d692 1079mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
e1ac3328 1080{
a2840c35
VP
1081 /* To cater for older frontends, emit ^running, but do it only once
1082 per each command. We do it here, since at this point we know
1083 that the target was successfully resumed, and in non-async mode,
1084 we won't return back to MI interpreter code until the target
1085 is done running, so delaying the output of "^running" until then
1086 will make it impossible for frontend to know what's going on.
1087
1088 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 1089 if (!running_result_record_printed && mi_proceeded)
a2840c35 1090 {
9204d692 1091 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
c271b6e2 1092 current_token ? current_token : "");
a2840c35
VP
1093 }
1094
dfd4cc63 1095 if (ptid_get_pid (ptid) == -1)
9204d692 1096 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
d90e17a7 1097 else if (ptid_is_pid (ptid))
bb599c81 1098 {
ab730e72 1099 int count = 0;
d90e17a7
PA
1100
1101 /* Backwards compatibility. If there's only one inferior,
1102 output "all", otherwise, output each resumed thread
1103 individually. */
1104 iterate_over_inferiors (mi_inferior_count, &count);
1105
1106 if (count == 1)
9204d692 1107 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
d90e17a7
PA
1108 else
1109 iterate_over_threads (mi_output_running_pid, &ptid);
bb599c81 1110 }
e1ac3328
VP
1111 else
1112 {
e09875d4 1113 struct thread_info *ti = find_thread_ptid (ptid);
102040f0 1114
e1ac3328 1115 gdb_assert (ti);
9204d692 1116 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n",
5d5658a1 1117 ti->global_num);
e1ac3328 1118 }
a2840c35 1119
f3b1572e 1120 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
1121 {
1122 running_result_record_printed = 1;
3b12939d
PA
1123 /* This is what gdb used to do historically -- printing prompt
1124 even if it cannot actually accept any input. This will be
1125 surely removed for MI3, and may be removed even earlier. */
1126 if (current_ui->prompt_state == PROMPT_BLOCKED)
9204d692 1127 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
a2840c35 1128 }
9204d692 1129 gdb_flush (mi->raw_stdout);
e1ac3328
VP
1130}
1131
c86cf029 1132static void
73ab01a0 1133mi_on_resume (ptid_t ptid)
c86cf029 1134{
73ab01a0
PA
1135 struct thread_info *tp = NULL;
1136 struct switch_thru_all_uis state;
6ef284bd 1137
73ab01a0
PA
1138 if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
1139 tp = inferior_thread ();
1140 else
1141 tp = find_thread_ptid (ptid);
6ef284bd 1142
73ab01a0
PA
1143 /* Suppress output while calling an inferior function. */
1144 if (tp->control.in_infcall)
1145 return;
6ef284bd 1146
73ab01a0 1147 SWITCH_THRU_ALL_UIS (state)
6ef284bd 1148 {
73ab01a0
PA
1149 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1150 struct cleanup *old_chain;
1151
1152 if (mi == NULL)
1153 continue;
1154
1155 old_chain = make_cleanup_restore_target_terminal ();
1156 target_terminal_ours_for_output ();
1157
9204d692 1158 mi_on_resume_1 (mi, ptid);
73ab01a0
PA
1159
1160 do_cleanups (old_chain);
6ef284bd 1161 }
73ab01a0 1162}
6ef284bd 1163
73ab01a0
PA
1164static void
1165mi_solib_loaded (struct so_list *solib)
1166{
1167 struct switch_thru_all_uis state;
a79b8f6e 1168
73ab01a0
PA
1169 SWITCH_THRU_ALL_UIS (state)
1170 {
1171 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1172 struct ui_out *uiout;
1173 struct cleanup *old_chain;
5fe96654 1174
73ab01a0
PA
1175 if (mi == NULL)
1176 continue;
1177
1178 uiout = interp_ui_out (top_level_interpreter ());
1179
1180 old_chain = make_cleanup_restore_target_terminal ();
1181 target_terminal_ours_for_output ();
1182
1183 fprintf_unfiltered (mi->event_channel, "library-loaded");
1184
1185 ui_out_redirect (uiout, mi->event_channel);
1186
1187 ui_out_field_string (uiout, "id", solib->so_original_name);
1188 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1189 ui_out_field_string (uiout, "host-name", solib->so_name);
1190 ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded);
1191 if (!gdbarch_has_global_solist (target_gdbarch ()))
1192 {
1193 ui_out_field_fmt (uiout, "thread-group", "i%d",
1194 current_inferior ()->num);
1195 }
1196
1197 ui_out_redirect (uiout, NULL);
1198
1199 gdb_flush (mi->event_channel);
1200
1201 do_cleanups (old_chain);
1202 }
c86cf029
VP
1203}
1204
1205static void
1206mi_solib_unloaded (struct so_list *solib)
1207{
73ab01a0 1208 struct switch_thru_all_uis state;
102040f0 1209
73ab01a0
PA
1210 SWITCH_THRU_ALL_UIS (state)
1211 {
1212 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1213 struct ui_out *uiout;
1214 struct cleanup *old_chain;
6ef284bd 1215
73ab01a0
PA
1216 if (mi == NULL)
1217 continue;
6ef284bd 1218
73ab01a0 1219 uiout = interp_ui_out (top_level_interpreter ());
6ef284bd 1220
73ab01a0
PA
1221 old_chain = make_cleanup_restore_target_terminal ();
1222 target_terminal_ours_for_output ();
6ef284bd 1223
73ab01a0 1224 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1225
73ab01a0 1226 ui_out_redirect (uiout, mi->event_channel);
5fe96654 1227
73ab01a0
PA
1228 ui_out_field_string (uiout, "id", solib->so_original_name);
1229 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1230 ui_out_field_string (uiout, "host-name", solib->so_name);
1231 if (!gdbarch_has_global_solist (target_gdbarch ()))
1232 {
1233 ui_out_field_fmt (uiout, "thread-group", "i%d",
1234 current_inferior ()->num);
1235 }
1236
1237 ui_out_redirect (uiout, NULL);
1238
1239 gdb_flush (mi->event_channel);
1240
1241 do_cleanups (old_chain);
1242 }
c86cf029
VP
1243}
1244
5b9afe8a
YQ
1245/* Emit notification about the command parameter change. */
1246
1247static void
1248mi_command_param_changed (const char *param, const char *value)
1249{
73ab01a0 1250 struct switch_thru_all_uis state;
5b9afe8a
YQ
1251
1252 if (mi_suppress_notification.cmd_param_changed)
1253 return;
1254
73ab01a0
PA
1255 SWITCH_THRU_ALL_UIS (state)
1256 {
1257 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1258 struct ui_out *mi_uiout;
1259 struct cleanup *old_chain;
5b9afe8a 1260
73ab01a0
PA
1261 if (mi == NULL)
1262 continue;
5b9afe8a 1263
73ab01a0 1264 mi_uiout = interp_ui_out (top_level_interpreter ());
5b9afe8a 1265
73ab01a0
PA
1266 old_chain = make_cleanup_restore_target_terminal ();
1267 target_terminal_ours_for_output ();
5b9afe8a 1268
73ab01a0 1269 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1270
73ab01a0 1271 ui_out_redirect (mi_uiout, mi->event_channel);
5fe96654 1272
73ab01a0
PA
1273 ui_out_field_string (mi_uiout, "param", param);
1274 ui_out_field_string (mi_uiout, "value", value);
1275
1276 ui_out_redirect (mi_uiout, NULL);
1277
1278 gdb_flush (mi->event_channel);
1279
1280 do_cleanups (old_chain);
1281 }
5b9afe8a
YQ
1282}
1283
8de0566d
YQ
1284/* Emit notification about the target memory change. */
1285
1286static void
1287mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1288 ssize_t len, const bfd_byte *myaddr)
1289{
73ab01a0 1290 struct switch_thru_all_uis state;
8de0566d
YQ
1291
1292 if (mi_suppress_notification.memory)
1293 return;
1294
73ab01a0
PA
1295 SWITCH_THRU_ALL_UIS (state)
1296 {
1297 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1298 struct ui_out *mi_uiout;
1299 struct obj_section *sec;
1300 struct cleanup *old_chain;
8de0566d 1301
73ab01a0
PA
1302 if (mi == NULL)
1303 continue;
8de0566d 1304
73ab01a0 1305 mi_uiout = interp_ui_out (top_level_interpreter ());
8de0566d 1306
73ab01a0
PA
1307 old_chain = make_cleanup_restore_target_terminal ();
1308 target_terminal_ours_for_output ();
8de0566d 1309
73ab01a0 1310 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1311
73ab01a0 1312 ui_out_redirect (mi_uiout, mi->event_channel);
8de0566d 1313
73ab01a0
PA
1314 ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
1315 ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
1316 ui_out_field_fmt (mi_uiout, "len", "%s", hex_string (len));
8de0566d 1317
73ab01a0
PA
1318 /* Append 'type=code' into notification if MEMADDR falls in the range of
1319 sections contain code. */
1320 sec = find_pc_section (memaddr);
1321 if (sec != NULL && sec->objfile != NULL)
1322 {
1323 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1324 sec->the_bfd_section);
5fe96654 1325
73ab01a0
PA
1326 if (flags & SEC_CODE)
1327 ui_out_field_string (mi_uiout, "type", "code");
1328 }
1329
1330 ui_out_redirect (mi_uiout, NULL);
1331
1332 gdb_flush (mi->event_channel);
1333
1334 do_cleanups (old_chain);
1335 }
8de0566d
YQ
1336}
1337
4034d0ff
AT
1338/* Emit an event when the selection context (inferior, thread, frame)
1339 changed. */
1340
1341static void
1342mi_user_selected_context_changed (user_selected_what selection)
1343{
1344 struct switch_thru_all_uis state;
1345 struct thread_info *tp;
1346
1347 /* Don't send an event if we're responding to an MI command. */
1348 if (mi_suppress_notification.user_selected_context)
1349 return;
1350
1351 tp = find_thread_ptid (inferior_ptid);
1352
1353 SWITCH_THRU_ALL_UIS (state)
1354 {
1355 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1356 struct ui_out *mi_uiout;
1357 struct cleanup *old_chain;
1358
1359 if (mi == NULL)
1360 continue;
1361
1362 mi_uiout = interp_ui_out (top_level_interpreter ());
1363
1364 ui_out_redirect (mi_uiout, mi->event_channel);
1365
1366 old_chain = make_cleanup_ui_out_redirect_pop (mi_uiout);
1367
1368 make_cleanup_restore_target_terminal ();
1369 target_terminal_ours_for_output ();
1370
1371 if (selection & USER_SELECTED_INFERIOR)
1372 print_selected_inferior (mi->cli_uiout);
1373
1374 if (tp != NULL
1375 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1376 {
1377 print_selected_thread_frame (mi->cli_uiout, selection);
1378
1379 fprintf_unfiltered (mi->event_channel,
1380 "thread-selected,id=\"%d\"",
1381 tp->global_num);
1382
1383 if (tp->state != THREAD_RUNNING)
1384 {
1385 if (has_stack_frames ())
1386 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1387 1, SRC_AND_LOC, 1);
1388 }
1389 }
1390
1391 gdb_flush (mi->event_channel);
1392 do_cleanups (old_chain);
1393 }
1394}
1395
a79b8f6e
VP
1396static int
1397report_initial_inferior (struct inferior *inf, void *closure)
1398{
73ab01a0 1399 /* This function is called from mi_interpreter_init, and since
a79b8f6e
VP
1400 mi_inferior_added assumes that inferior is fully initialized
1401 and top_level_interpreter_data is set, we cannot call
1402 it here. */
19ba03f4 1403 struct mi_interp *mi = (struct mi_interp *) closure;
5fe96654
PA
1404 struct cleanup *old_chain;
1405
1406 old_chain = make_cleanup_restore_target_terminal ();
1407 target_terminal_ours_for_output ();
102040f0 1408
a79b8f6e
VP
1409 fprintf_unfiltered (mi->event_channel,
1410 "thread-group-added,id=\"i%d\"",
1411 inf->num);
1412 gdb_flush (mi->event_channel);
5fe96654
PA
1413
1414 do_cleanups (old_chain);
a79b8f6e
VP
1415 return 0;
1416}
c86cf029 1417
4801a9a3
PA
1418static struct ui_out *
1419mi_ui_out (struct interp *interp)
1420{
19ba03f4 1421 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
4801a9a3 1422
fd664c91 1423 return mi->mi_uiout;
4801a9a3
PA
1424}
1425
37ce89eb
SS
1426/* Do MI-specific logging actions; save raw_stdout, and change all
1427 the consoles to use the supplied ui-file(s). */
1428
1429static int
1430mi_set_logging (struct interp *interp, int start_log,
1431 struct ui_file *out, struct ui_file *logfile)
1432{
19ba03f4 1433 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
37ce89eb
SS
1434
1435 if (!mi)
1436 return 0;
1437
1438 if (start_log)
1439 {
1440 /* The tee created already is based on gdb_stdout, which for MI
1441 is a console and so we end up in an infinite loop of console
1442 writing to ui_file writing to console etc. So discard the
1443 existing tee (it hasn't been used yet, and MI won't ever use
1444 it), and create one based on raw_stdout instead. */
1445 if (logfile)
1446 {
1447 ui_file_delete (out);
9204d692 1448 out = tee_file_new (mi->raw_stdout, 0, logfile, 0);
37ce89eb
SS
1449 }
1450
9204d692
PA
1451 mi->saved_raw_stdout = mi->raw_stdout;
1452 mi->raw_stdout = out;
37ce89eb
SS
1453 }
1454 else
1455 {
9204d692
PA
1456 mi->raw_stdout = mi->saved_raw_stdout;
1457 mi->saved_raw_stdout = NULL;
37ce89eb
SS
1458 }
1459
9204d692
PA
1460 mi_console_set_raw (mi->out, mi->raw_stdout);
1461 mi_console_set_raw (mi->err, mi->raw_stdout);
1462 mi_console_set_raw (mi->log, mi->raw_stdout);
1463 mi_console_set_raw (mi->targ, mi->raw_stdout);
1464 mi_console_set_raw (mi->event_channel, mi->raw_stdout);
37ce89eb
SS
1465
1466 return 1;
1467}
1468
8322445e
PA
1469/* The MI interpreter's vtable. */
1470
1471static const struct interp_procs mi_interp_procs =
1472{
1473 mi_interpreter_init, /* init_proc */
1474 mi_interpreter_resume, /* resume_proc */
1475 mi_interpreter_suspend, /* suspend_proc */
1476 mi_interpreter_exec, /* exec_proc */
1477 mi_ui_out, /* ui_out_proc */
1478 mi_set_logging, /* set_logging_proc */
b2d86570 1479 mi_interpreter_pre_command_loop /* pre_command_loop_proc */
8322445e
PA
1480};
1481
1482/* Factory for MI interpreters. */
1483
1484static struct interp *
1485mi_interp_factory (const char *name)
1486{
1487 return interp_new (name, &mi_interp_procs, NULL);
1488}
1489
b9362cc7
AC
1490extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
1491
4a8f6654
AC
1492void
1493_initialize_mi_interp (void)
1494{
2fcf52f0 1495 /* The various interpreter levels. */
8322445e
PA
1496 interp_factory_register (INTERP_MI1, mi_interp_factory);
1497 interp_factory_register (INTERP_MI2, mi_interp_factory);
1498 interp_factory_register (INTERP_MI3, mi_interp_factory);
1499 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0
PA
1500
1501 observer_attach_signal_received (mi_on_signal_received);
1502 observer_attach_end_stepping_range (mi_on_end_stepping_range);
1503 observer_attach_signal_exited (mi_on_signal_exited);
1504 observer_attach_exited (mi_on_exited);
1505 observer_attach_no_history (mi_on_no_history);
1506 observer_attach_new_thread (mi_new_thread);
1507 observer_attach_thread_exit (mi_thread_exit);
1508 observer_attach_inferior_added (mi_inferior_added);
1509 observer_attach_inferior_appeared (mi_inferior_appeared);
1510 observer_attach_inferior_exit (mi_inferior_exit);
1511 observer_attach_inferior_removed (mi_inferior_removed);
1512 observer_attach_record_changed (mi_record_changed);
1513 observer_attach_normal_stop (mi_on_normal_stop);
1514 observer_attach_target_resumed (mi_on_resume);
1515 observer_attach_solib_loaded (mi_solib_loaded);
1516 observer_attach_solib_unloaded (mi_solib_unloaded);
1517 observer_attach_about_to_proceed (mi_about_to_proceed);
1518 observer_attach_traceframe_changed (mi_traceframe_changed);
1519 observer_attach_tsv_created (mi_tsv_created);
1520 observer_attach_tsv_deleted (mi_tsv_deleted);
1521 observer_attach_tsv_modified (mi_tsv_modified);
1522 observer_attach_breakpoint_created (mi_breakpoint_created);
1523 observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
1524 observer_attach_breakpoint_modified (mi_breakpoint_modified);
1525 observer_attach_command_param_changed (mi_command_param_changed);
1526 observer_attach_memory_changed (mi_memory_changed);
1527 observer_attach_sync_execution_done (mi_on_sync_execution_done);
4034d0ff
AT
1528 observer_attach_user_selected_context_changed
1529 (mi_user_selected_context_changed);
4a8f6654 1530}
This page took 1.290918 seconds and 4 git commands to generate.