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