Make gdb_in_secondary_prompt_p() be per UI
[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{
9204d692
PA
96 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
97 gdb_flush (mi->raw_stdout);
05beb275
PA
98}
99
73ab01a0
PA
100/* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
101 returns NULL otherwise. */
102
103static struct mi_interp *
104as_mi_interp (struct interp *interp)
105{
106 if (ui_out_is_mi_like_p (interp_ui_out (interp)))
107 return (struct mi_interp *) interp_data (interp);
108 return NULL;
109}
110
4a8f6654 111static void *
4801a9a3 112mi_interpreter_init (struct interp *interp, int top_level)
4a8f6654 113{
70ba0933 114 struct mi_interp *mi = XNEW (struct mi_interp);
4801a9a3
PA
115 const char *name;
116 int mi_version;
4a8f6654 117
9204d692
PA
118 /* Store the current output channel, so that we can create a console
119 channel that encapsulates and prefixes all gdb_output-type bits
120 coming from the rest of the debugger. */
121 mi->raw_stdout = gdb_stdout;
4a8f6654 122
2b03b41d
SS
123 /* Create MI console channels, each with a different prefix so they
124 can be distinguished. */
9204d692
PA
125 mi->out = mi_console_file_new (mi->raw_stdout, "~", '"');
126 mi->err = mi_console_file_new (mi->raw_stdout, "&", '"');
4a8f6654 127 mi->log = mi->err;
9204d692
PA
128 mi->targ = mi_console_file_new (mi->raw_stdout, "@", '"');
129 mi->event_channel = mi_console_file_new (mi->raw_stdout, "=", 0);
4a8f6654 130
4801a9a3
PA
131 name = interp_name (interp);
132 /* INTERP_MI selects the most recent released version. "mi2" was
133 released as part of GDB 6.0. */
134 if (strcmp (name, INTERP_MI) == 0)
135 mi_version = 2;
136 else if (strcmp (name, INTERP_MI1) == 0)
137 mi_version = 1;
138 else if (strcmp (name, INTERP_MI2) == 0)
139 mi_version = 2;
140 else if (strcmp (name, INTERP_MI3) == 0)
141 mi_version = 3;
142 else
143 gdb_assert_not_reached ("unhandled MI version");
144
fd664c91
PA
145 mi->mi_uiout = mi_out_new (mi_version);
146 mi->cli_uiout = cli_out_new (mi->out);
147
683f2885 148 if (top_level)
063bfe2e 149 {
2b03b41d
SS
150 /* The initial inferior is created before this function is
151 called, so we need to report it explicitly. Use iteration in
152 case future version of GDB creates more than one inferior
153 up-front. */
a79b8f6e 154 iterate_over_inferiors (report_initial_inferior, mi);
063bfe2e 155 }
683f2885 156
4a8f6654
AC
157 return mi;
158}
159
160static int
161mi_interpreter_resume (void *data)
162{
19ba03f4 163 struct mi_interp *mi = (struct mi_interp *) data;
a74e1786 164 struct ui *ui = current_ui;
4a8f6654 165
2b03b41d
SS
166 /* As per hack note in mi_interpreter_init, swap in the output
167 channels... */
3c216924 168 gdb_setup_readline (0);
4a8f6654 169
a74e1786
PA
170 ui->call_readline = gdb_readline_no_editing_callback;
171 ui->input_handler = mi_execute_command_input_handler;
362646f5
AC
172 /* FIXME: This is a total hack for now. PB's use of the MI
173 implicitly relies on a bug in the async support which allows
174 asynchronous commands to leak through the commmand loop. The bug
175 involves (but is not limited to) the fact that sync_execution was
176 erroneously initialized to 0. Duplicate by initializing it thus
177 here... */
178 sync_execution = 0;
4a8f6654
AC
179
180 gdb_stdout = mi->out;
2b03b41d 181 /* Route error and log output through the MI. */
4a8f6654
AC
182 gdb_stderr = mi->err;
183 gdb_stdlog = mi->log;
2b03b41d 184 /* Route target output through the MI. */
4a8f6654 185 gdb_stdtarg = mi->targ;
2b03b41d 186 /* Route target error through the MI as well. */
1f20321b 187 gdb_stdtargerr = mi->targ;
4a8f6654
AC
188
189 /* Replace all the hooks that we know about. There really needs to
190 be a better way of doing this... */
191 clear_interpreter_hooks ();
192
9a4105ab 193 deprecated_show_load_progress = mi_load_progress;
4a8f6654 194
4a8f6654
AC
195 return 1;
196}
197
198static int
199mi_interpreter_suspend (void *data)
200{
201 gdb_disable_readline ();
202 return 1;
203}
204
71fff37b 205static struct gdb_exception
4a8f6654
AC
206mi_interpreter_exec (void *data, const char *command)
207{
ee047554 208 mi_execute_command_wrapper (command);
c1043fc2 209 return exception_none;
4a8f6654
AC
210}
211
ce8f13f8 212void
4a8f6654
AC
213mi_cmd_interpreter_exec (char *command, char **argv, int argc)
214{
215 struct interp *interp_to_use;
4a8f6654 216 int i;
a13e061a
PA
217 char *mi_error_message = NULL;
218 struct cleanup *old_chain;
4a8f6654
AC
219
220 if (argc < 2)
1b05df00 221 error (_("-interpreter-exec: "
9b20d036 222 "Usage: -interpreter-exec interp command"));
4a8f6654 223
8322445e 224 interp_to_use = interp_lookup (current_ui, argv[0]);
4a8f6654 225 if (interp_to_use == NULL)
1b05df00 226 error (_("-interpreter-exec: could not find interpreter \"%s\""),
9a2b4c1b 227 argv[0]);
4a8f6654 228
17b2616c
PA
229 /* Note that unlike the CLI version of this command, we don't
230 actually set INTERP_TO_USE as the current interpreter, as we
231 still want gdb_stdout, etc. to point at MI streams. */
232
2b03b41d
SS
233 /* Insert the MI out hooks, making sure to also call the
234 interpreter's hooks if it has any. */
235 /* KRS: We shouldn't need this... Events should be installed and
236 they should just ALWAYS fire something out down the MI
237 channel. */
4a8f6654
AC
238 mi_insert_notify_hooks ();
239
2b03b41d 240 /* Now run the code. */
4a8f6654 241
a13e061a 242 old_chain = make_cleanup (null_cleanup, 0);
4a8f6654
AC
243 for (i = 1; i < argc; i++)
244 {
32c1e744 245 struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
102040f0 246
32c1e744
VP
247 if (e.reason < 0)
248 {
249 mi_error_message = xstrdup (e.message);
a13e061a 250 make_cleanup (xfree, mi_error_message);
32c1e744
VP
251 break;
252 }
4a8f6654
AC
253 }
254
255 mi_remove_notify_hooks ();
256
a13e061a
PA
257 if (mi_error_message != NULL)
258 error ("%s", mi_error_message);
259 do_cleanups (old_chain);
4a8f6654
AC
260}
261
2b03b41d
SS
262/* This inserts a number of hooks that are meant to produce
263 async-notify ("=") MI messages while running commands in another
264 interpreter using mi_interpreter_exec. The canonical use for this
265 is to allow access to the gdb CLI interpreter from within the MI,
266 while still producing MI style output when actions in the CLI
267 command change GDB's state. */
4a8f6654
AC
268
269static void
270mi_insert_notify_hooks (void)
271{
9a4105ab 272 deprecated_query_hook = mi_interp_query_hook;
4a8f6654
AC
273}
274
275static void
11308a41 276mi_remove_notify_hooks (void)
4a8f6654 277{
9a4105ab 278 deprecated_query_hook = NULL;
4a8f6654
AC
279}
280
281static int
282mi_interp_query_hook (const char *ctlstr, va_list ap)
283{
284 return 1;
285}
286
4a8f6654 287static void
ee047554 288mi_execute_command_wrapper (const char *cmd)
4a8f6654 289{
f38d3ad1
PA
290 struct ui *ui = current_ui;
291
292 mi_execute_command (cmd, stdin == ui->instream);
4a8f6654
AC
293}
294
329ea579
PA
295/* Observer for the synchronous_command_done notification. */
296
297static void
298mi_on_sync_execution_done (void)
299{
73ab01a0
PA
300 struct ui *ui = current_ui;
301 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
302
303 if (mi == NULL)
304 return;
305
0b333c5e
PA
306 /* If MI is sync, then output the MI prompt now, indicating we're
307 ready for further input. */
329ea579 308 if (!mi_async_p ())
9204d692 309 display_mi_prompt (mi);
329ea579
PA
310}
311
e837f12a
JK
312/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
313
314static void
315mi_execute_command_input_handler (char *cmd)
316{
9204d692
PA
317 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
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. */
326 if (!sync_execution)
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;
102040f0 690
243a9253 691 tp = inferior_thread ();
36dfb11c 692
243a9253
PA
693 if (tp->thread_fsm != NULL
694 && thread_fsm_finished_p (tp->thread_fsm))
695 {
696 enum async_reply_reason reason;
36dfb11c 697
243a9253
PA
698 reason = thread_fsm_async_reply_reason (tp->thread_fsm);
699 ui_out_field_string (mi_uiout, "reason",
700 async_reason_lookup (reason));
1d33d6ba 701 }
243a9253
PA
702 print_stop_event (mi_uiout);
703
704 /* Breakpoint hits should always be mirrored to the console.
705 Deciding what to mirror to the console wrt to breakpoints and
706 random stops gets messy real fast. E.g., say "s" trips on a
707 breakpoint. We'd clearly want to mirror the event to the
708 console in this case. But what about more complicated cases
709 like "s&; thread n; s&", and one of those steps spawning a
710 new thread, and that thread hitting a breakpoint? It's
711 impossible in general to track whether the thread had any
712 relation to the commands that had been executed. So we just
713 simplify and always mirror breakpoints and random events to
714 the console.
715
716 OTOH, we should print the source line to the console when
717 stepping or other similar commands, iff the step was started
718 by a console command, but not if it was started with
719 -exec-step or similar. */
720 if ((bpstat_what (tp->control.stop_bpstat).main_action
721 == BPSTAT_WHAT_STOP_NOISY)
722 || !(tp->thread_fsm != NULL
723 && thread_fsm_finished_p (tp->thread_fsm))
724 || (tp->control.command_interp != NULL
725 && tp->control.command_interp != top_level_interpreter ()))
9204d692 726 print_stop_event (mi->cli_uiout);
1d33d6ba 727
5d5658a1
PA
728 tp = inferior_thread ();
729 ui_out_field_int (mi_uiout, "thread-id", tp->global_num);
1d33d6ba
VP
730 if (non_stop)
731 {
732 struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
733 (mi_uiout, "stopped-threads");
102040f0 734
5d5658a1 735 ui_out_field_int (mi_uiout, NULL, tp->global_num);
1d33d6ba
VP
736 do_cleanups (back_to);
737 }
738 else
739 ui_out_field_string (mi_uiout, "stopped-threads", "all");
dc146f7c
VP
740
741 core = target_core_of_thread (inferior_ptid);
742 if (core != -1)
743 ui_out_field_int (mi_uiout, "core", core);
1d33d6ba
VP
744 }
745
9204d692
PA
746 fputs_unfiltered ("*stopped", mi->raw_stdout);
747 mi_out_put (mi_uiout, mi->raw_stdout);
1d33d6ba 748 mi_out_rewind (mi_uiout);
9204d692
PA
749 mi_print_timing_maybe (mi->raw_stdout);
750 fputs_unfiltered ("\n", mi->raw_stdout);
751 gdb_flush (mi->raw_stdout);
f7f9a841
VP
752}
753
73ab01a0
PA
754static void
755mi_on_normal_stop (struct bpstats *bs, int print_frame)
756{
757 struct switch_thru_all_uis state;
758
759 SWITCH_THRU_ALL_UIS (state)
760 {
761 if (as_mi_interp (top_level_interpreter ()) == NULL)
762 continue;
763
764 mi_on_normal_stop_1 (bs, print_frame);
765 }
766}
767
f3b1572e
PA
768static void
769mi_about_to_proceed (void)
770{
771 /* Suppress output while calling an inferior function. */
772
773 if (!ptid_equal (inferior_ptid, null_ptid))
774 {
775 struct thread_info *tp = inferior_thread ();
102040f0 776
16c381f0 777 if (tp->control.in_infcall)
f3b1572e
PA
778 return;
779 }
780
781 mi_proceeded = 1;
782}
783
5b9afe8a
YQ
784/* When the element is non-zero, no MI notifications will be emitted in
785 response to the corresponding observers. */
2b03b41d 786
5b9afe8a
YQ
787struct mi_suppress_notification mi_suppress_notification =
788 {
789 0,
790 0,
201b4506 791 0,
5b9afe8a 792 };
8d3788bd 793
201b4506
YQ
794/* Emit notification on changing a traceframe. */
795
796static void
797mi_traceframe_changed (int tfnum, int tpnum)
798{
73ab01a0 799 struct switch_thru_all_uis state;
201b4506
YQ
800
801 if (mi_suppress_notification.traceframe)
802 return;
803
73ab01a0
PA
804 SWITCH_THRU_ALL_UIS (state)
805 {
806 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
807 struct cleanup *old_chain;
201b4506 808
73ab01a0
PA
809 if (mi == NULL)
810 continue;
201b4506 811
73ab01a0
PA
812 old_chain = make_cleanup_restore_target_terminal ();
813 target_terminal_ours_for_output ();
5fe96654 814
73ab01a0
PA
815 if (tfnum >= 0)
816 fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
817 "num=\"%d\",tracepoint=\"%d\"\n",
818 tfnum, tpnum);
819 else
820 fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
821
822 gdb_flush (mi->event_channel);
823
824 do_cleanups (old_chain);
825 }
201b4506
YQ
826}
827
bb25a15c
YQ
828/* Emit notification on creating a trace state variable. */
829
830static void
134a2066 831mi_tsv_created (const struct trace_state_variable *tsv)
bb25a15c 832{
73ab01a0 833 struct switch_thru_all_uis state;
bb25a15c 834
73ab01a0
PA
835 SWITCH_THRU_ALL_UIS (state)
836 {
837 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
838 struct cleanup *old_chain;
bb25a15c 839
73ab01a0
PA
840 if (mi == NULL)
841 continue;
bb25a15c 842
73ab01a0
PA
843 old_chain = make_cleanup_restore_target_terminal ();
844 target_terminal_ours_for_output ();
5fe96654 845
73ab01a0
PA
846 fprintf_unfiltered (mi->event_channel, "tsv-created,"
847 "name=\"%s\",initial=\"%s\"\n",
848 tsv->name, plongest (tsv->initial_value));
849
850 gdb_flush (mi->event_channel);
851
852 do_cleanups (old_chain);
853 }
bb25a15c
YQ
854}
855
856/* Emit notification on deleting a trace state variable. */
857
858static void
134a2066 859mi_tsv_deleted (const struct trace_state_variable *tsv)
bb25a15c 860{
73ab01a0 861 struct switch_thru_all_uis state;
bb25a15c 862
73ab01a0
PA
863 SWITCH_THRU_ALL_UIS (state)
864 {
865 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
866 struct cleanup *old_chain;
bb25a15c 867
73ab01a0
PA
868 if (mi == NULL)
869 continue;
bb25a15c 870
73ab01a0
PA
871 old_chain = make_cleanup_restore_target_terminal ();
872 target_terminal_ours_for_output ();
5fe96654 873
73ab01a0
PA
874 if (tsv != NULL)
875 fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
876 "name=\"%s\"\n", tsv->name);
877 else
878 fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
879
880 gdb_flush (mi->event_channel);
881
882 do_cleanups (old_chain);
883 }
bb25a15c
YQ
884}
885
134a2066
YQ
886/* Emit notification on modifying a trace state variable. */
887
888static void
889mi_tsv_modified (const struct trace_state_variable *tsv)
890{
73ab01a0 891 struct switch_thru_all_uis state;
134a2066 892
73ab01a0
PA
893 SWITCH_THRU_ALL_UIS (state)
894 {
895 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
896 struct ui_out *mi_uiout;
897 struct cleanup *old_chain;
134a2066 898
73ab01a0
PA
899 if (mi == NULL)
900 continue;
134a2066 901
73ab01a0 902 mi_uiout = interp_ui_out (top_level_interpreter ());
134a2066 903
73ab01a0
PA
904 old_chain = make_cleanup_restore_target_terminal ();
905 target_terminal_ours_for_output ();
134a2066 906
73ab01a0
PA
907 fprintf_unfiltered (mi->event_channel,
908 "tsv-modified");
134a2066 909
73ab01a0 910 ui_out_redirect (mi_uiout, mi->event_channel);
5fe96654 911
73ab01a0
PA
912 ui_out_field_string (mi_uiout, "name", tsv->name);
913 ui_out_field_string (mi_uiout, "initial",
914 plongest (tsv->initial_value));
915 if (tsv->value_known)
916 ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
917
918 ui_out_redirect (mi_uiout, NULL);
919
920 gdb_flush (mi->event_channel);
921
922 do_cleanups (old_chain);
923 }
134a2066
YQ
924}
925
8d3788bd 926/* Emit notification about a created breakpoint. */
2b03b41d 927
8d3788bd
VP
928static void
929mi_breakpoint_created (struct breakpoint *b)
930{
73ab01a0 931 struct switch_thru_all_uis state;
8d3788bd 932
5b9afe8a 933 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
934 return;
935
936 if (b->number <= 0)
937 return;
938
73ab01a0 939 SWITCH_THRU_ALL_UIS (state)
492d29ea 940 {
73ab01a0
PA
941 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
942 struct ui_out *mi_uiout;
943 struct cleanup *old_chain;
492d29ea 944
73ab01a0
PA
945 if (mi == NULL)
946 continue;
8d3788bd 947
73ab01a0 948 mi_uiout = interp_ui_out (top_level_interpreter ());
5fe96654 949
73ab01a0
PA
950 old_chain = make_cleanup_restore_target_terminal ();
951 target_terminal_ours_for_output ();
952
953 fprintf_unfiltered (mi->event_channel,
954 "breakpoint-created");
955 /* We want the output from gdb_breakpoint_query to go to
956 mi->event_channel. One approach would be to just call
957 gdb_breakpoint_query, and then use mi_out_put to send the current
958 content of mi_outout into mi->event_channel. However, that will
959 break if anything is output to mi_uiout prior to calling the
960 breakpoint_created notifications. So, we use
961 ui_out_redirect. */
962 ui_out_redirect (mi_uiout, mi->event_channel);
963 TRY
964 {
965 gdb_breakpoint_query (mi_uiout, b->number, NULL);
966 }
967 CATCH (e, RETURN_MASK_ERROR)
968 {
969 }
970 END_CATCH
971
972 ui_out_redirect (mi_uiout, NULL);
973
974 gdb_flush (mi->event_channel);
975
976 do_cleanups (old_chain);
977 }
8d3788bd
VP
978}
979
980/* Emit notification about deleted breakpoint. */
2b03b41d 981
8d3788bd
VP
982static void
983mi_breakpoint_deleted (struct breakpoint *b)
984{
73ab01a0 985 struct switch_thru_all_uis state;
8d3788bd 986
5b9afe8a 987 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
988 return;
989
990 if (b->number <= 0)
991 return;
992
73ab01a0
PA
993 SWITCH_THRU_ALL_UIS (state)
994 {
995 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
996 struct cleanup *old_chain;
8d3788bd 997
73ab01a0
PA
998 if (mi == NULL)
999 continue;
8d3788bd 1000
73ab01a0
PA
1001 old_chain = make_cleanup_restore_target_terminal ();
1002 target_terminal_ours_for_output ();
5fe96654 1003
73ab01a0
PA
1004 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
1005 b->number);
1006
1007 gdb_flush (mi->event_channel);
1008
1009 do_cleanups (old_chain);
1010 }
8d3788bd
VP
1011}
1012
1013/* Emit notification about modified breakpoint. */
2b03b41d 1014
8d3788bd
VP
1015static void
1016mi_breakpoint_modified (struct breakpoint *b)
1017{
73ab01a0 1018 struct switch_thru_all_uis state;
8d3788bd 1019
5b9afe8a 1020 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
1021 return;
1022
1023 if (b->number <= 0)
1024 return;
1025
73ab01a0 1026 SWITCH_THRU_ALL_UIS (state)
492d29ea 1027 {
73ab01a0
PA
1028 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1029 struct cleanup *old_chain;
492d29ea 1030
73ab01a0
PA
1031 if (mi == NULL)
1032 continue;
8d3788bd 1033
73ab01a0
PA
1034 old_chain = make_cleanup_restore_target_terminal ();
1035 target_terminal_ours_for_output ();
1036 fprintf_unfiltered (mi->event_channel,
1037 "breakpoint-modified");
1038 /* We want the output from gdb_breakpoint_query to go to
1039 mi->event_channel. One approach would be to just call
1040 gdb_breakpoint_query, and then use mi_out_put to send the current
1041 content of mi_outout into mi->event_channel. However, that will
1042 break if anything is output to mi_uiout prior to calling the
1043 breakpoint_created notifications. So, we use
1044 ui_out_redirect. */
1045 ui_out_redirect (mi->mi_uiout, mi->event_channel);
1046 TRY
1047 {
1048 gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
1049 }
1050 CATCH (e, RETURN_MASK_ERROR)
1051 {
1052 }
1053 END_CATCH
5fe96654 1054
73ab01a0
PA
1055 ui_out_redirect (mi->mi_uiout, NULL);
1056
1057 gdb_flush (mi->event_channel);
1058
1059 do_cleanups (old_chain);
1060 }
8d3788bd
VP
1061}
1062
d90e17a7
PA
1063static int
1064mi_output_running_pid (struct thread_info *info, void *arg)
1065{
19ba03f4 1066 ptid_t *ptid = (ptid_t *) arg;
73ab01a0 1067 struct switch_thru_all_uis state;
d90e17a7 1068
73ab01a0
PA
1069 SWITCH_THRU_ALL_UIS (state)
1070 {
1071 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1072
1073 if (mi == NULL)
1074 continue;
1075
1076 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
9204d692 1077 fprintf_unfiltered (mi->raw_stdout,
73ab01a0
PA
1078 "*running,thread-id=\"%d\"\n",
1079 info->global_num);
1080 }
d90e17a7
PA
1081
1082 return 0;
1083}
1084
1085static int
1086mi_inferior_count (struct inferior *inf, void *arg)
1087{
1088 if (inf->pid != 0)
1089 {
19ba03f4 1090 int *count_p = (int *) arg;
d90e17a7
PA
1091 (*count_p)++;
1092 }
1093
1094 return 0;
1095}
1096
e1ac3328 1097static void
9204d692 1098mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
e1ac3328 1099{
a2840c35
VP
1100 /* To cater for older frontends, emit ^running, but do it only once
1101 per each command. We do it here, since at this point we know
1102 that the target was successfully resumed, and in non-async mode,
1103 we won't return back to MI interpreter code until the target
1104 is done running, so delaying the output of "^running" until then
1105 will make it impossible for frontend to know what's going on.
1106
1107 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 1108 if (!running_result_record_printed && mi_proceeded)
a2840c35 1109 {
9204d692 1110 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
c271b6e2 1111 current_token ? current_token : "");
a2840c35
VP
1112 }
1113
dfd4cc63 1114 if (ptid_get_pid (ptid) == -1)
9204d692 1115 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
d90e17a7 1116 else if (ptid_is_pid (ptid))
bb599c81 1117 {
ab730e72 1118 int count = 0;
d90e17a7
PA
1119
1120 /* Backwards compatibility. If there's only one inferior,
1121 output "all", otherwise, output each resumed thread
1122 individually. */
1123 iterate_over_inferiors (mi_inferior_count, &count);
1124
1125 if (count == 1)
9204d692 1126 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
d90e17a7
PA
1127 else
1128 iterate_over_threads (mi_output_running_pid, &ptid);
bb599c81 1129 }
e1ac3328
VP
1130 else
1131 {
e09875d4 1132 struct thread_info *ti = find_thread_ptid (ptid);
102040f0 1133
e1ac3328 1134 gdb_assert (ti);
9204d692 1135 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n",
5d5658a1 1136 ti->global_num);
e1ac3328 1137 }
a2840c35 1138
f3b1572e 1139 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
1140 {
1141 running_result_record_printed = 1;
1142 /* This is what gdb used to do historically -- printing prompt even if
1143 it cannot actually accept any input. This will be surely removed
329ea579
PA
1144 for MI3, and may be removed even earlier. SYNC_EXECUTION is
1145 checked here because we only need to emit a prompt if a
1146 synchronous command was issued when the target is async. */
28addb40 1147 if (!target_can_async_p () || sync_execution)
9204d692 1148 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
a2840c35 1149 }
9204d692 1150 gdb_flush (mi->raw_stdout);
e1ac3328
VP
1151}
1152
c86cf029 1153static void
73ab01a0 1154mi_on_resume (ptid_t ptid)
c86cf029 1155{
73ab01a0
PA
1156 struct thread_info *tp = NULL;
1157 struct switch_thru_all_uis state;
6ef284bd 1158
73ab01a0
PA
1159 if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
1160 tp = inferior_thread ();
1161 else
1162 tp = find_thread_ptid (ptid);
6ef284bd 1163
73ab01a0
PA
1164 /* Suppress output while calling an inferior function. */
1165 if (tp->control.in_infcall)
1166 return;
6ef284bd 1167
73ab01a0 1168 SWITCH_THRU_ALL_UIS (state)
6ef284bd 1169 {
73ab01a0
PA
1170 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1171 struct cleanup *old_chain;
1172
1173 if (mi == NULL)
1174 continue;
1175
1176 old_chain = make_cleanup_restore_target_terminal ();
1177 target_terminal_ours_for_output ();
1178
9204d692 1179 mi_on_resume_1 (mi, ptid);
73ab01a0
PA
1180
1181 do_cleanups (old_chain);
6ef284bd 1182 }
73ab01a0 1183}
6ef284bd 1184
73ab01a0
PA
1185static void
1186mi_solib_loaded (struct so_list *solib)
1187{
1188 struct switch_thru_all_uis state;
a79b8f6e 1189
73ab01a0
PA
1190 SWITCH_THRU_ALL_UIS (state)
1191 {
1192 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1193 struct ui_out *uiout;
1194 struct cleanup *old_chain;
5fe96654 1195
73ab01a0
PA
1196 if (mi == NULL)
1197 continue;
1198
1199 uiout = interp_ui_out (top_level_interpreter ());
1200
1201 old_chain = make_cleanup_restore_target_terminal ();
1202 target_terminal_ours_for_output ();
1203
1204 fprintf_unfiltered (mi->event_channel, "library-loaded");
1205
1206 ui_out_redirect (uiout, mi->event_channel);
1207
1208 ui_out_field_string (uiout, "id", solib->so_original_name);
1209 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1210 ui_out_field_string (uiout, "host-name", solib->so_name);
1211 ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded);
1212 if (!gdbarch_has_global_solist (target_gdbarch ()))
1213 {
1214 ui_out_field_fmt (uiout, "thread-group", "i%d",
1215 current_inferior ()->num);
1216 }
1217
1218 ui_out_redirect (uiout, NULL);
1219
1220 gdb_flush (mi->event_channel);
1221
1222 do_cleanups (old_chain);
1223 }
c86cf029
VP
1224}
1225
1226static void
1227mi_solib_unloaded (struct so_list *solib)
1228{
73ab01a0 1229 struct switch_thru_all_uis state;
102040f0 1230
73ab01a0
PA
1231 SWITCH_THRU_ALL_UIS (state)
1232 {
1233 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1234 struct ui_out *uiout;
1235 struct cleanup *old_chain;
6ef284bd 1236
73ab01a0
PA
1237 if (mi == NULL)
1238 continue;
6ef284bd 1239
73ab01a0 1240 uiout = interp_ui_out (top_level_interpreter ());
6ef284bd 1241
73ab01a0
PA
1242 old_chain = make_cleanup_restore_target_terminal ();
1243 target_terminal_ours_for_output ();
6ef284bd 1244
73ab01a0 1245 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1246
73ab01a0 1247 ui_out_redirect (uiout, mi->event_channel);
5fe96654 1248
73ab01a0
PA
1249 ui_out_field_string (uiout, "id", solib->so_original_name);
1250 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1251 ui_out_field_string (uiout, "host-name", solib->so_name);
1252 if (!gdbarch_has_global_solist (target_gdbarch ()))
1253 {
1254 ui_out_field_fmt (uiout, "thread-group", "i%d",
1255 current_inferior ()->num);
1256 }
1257
1258 ui_out_redirect (uiout, NULL);
1259
1260 gdb_flush (mi->event_channel);
1261
1262 do_cleanups (old_chain);
1263 }
c86cf029
VP
1264}
1265
5b9afe8a
YQ
1266/* Emit notification about the command parameter change. */
1267
1268static void
1269mi_command_param_changed (const char *param, const char *value)
1270{
73ab01a0 1271 struct switch_thru_all_uis state;
5b9afe8a
YQ
1272
1273 if (mi_suppress_notification.cmd_param_changed)
1274 return;
1275
73ab01a0
PA
1276 SWITCH_THRU_ALL_UIS (state)
1277 {
1278 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1279 struct ui_out *mi_uiout;
1280 struct cleanup *old_chain;
5b9afe8a 1281
73ab01a0
PA
1282 if (mi == NULL)
1283 continue;
5b9afe8a 1284
73ab01a0 1285 mi_uiout = interp_ui_out (top_level_interpreter ());
5b9afe8a 1286
73ab01a0
PA
1287 old_chain = make_cleanup_restore_target_terminal ();
1288 target_terminal_ours_for_output ();
5b9afe8a 1289
73ab01a0 1290 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1291
73ab01a0 1292 ui_out_redirect (mi_uiout, mi->event_channel);
5fe96654 1293
73ab01a0
PA
1294 ui_out_field_string (mi_uiout, "param", param);
1295 ui_out_field_string (mi_uiout, "value", value);
1296
1297 ui_out_redirect (mi_uiout, NULL);
1298
1299 gdb_flush (mi->event_channel);
1300
1301 do_cleanups (old_chain);
1302 }
5b9afe8a
YQ
1303}
1304
8de0566d
YQ
1305/* Emit notification about the target memory change. */
1306
1307static void
1308mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1309 ssize_t len, const bfd_byte *myaddr)
1310{
73ab01a0 1311 struct switch_thru_all_uis state;
8de0566d
YQ
1312
1313 if (mi_suppress_notification.memory)
1314 return;
1315
73ab01a0
PA
1316 SWITCH_THRU_ALL_UIS (state)
1317 {
1318 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1319 struct ui_out *mi_uiout;
1320 struct obj_section *sec;
1321 struct cleanup *old_chain;
8de0566d 1322
73ab01a0
PA
1323 if (mi == NULL)
1324 continue;
8de0566d 1325
73ab01a0 1326 mi_uiout = interp_ui_out (top_level_interpreter ());
8de0566d 1327
73ab01a0
PA
1328 old_chain = make_cleanup_restore_target_terminal ();
1329 target_terminal_ours_for_output ();
8de0566d 1330
73ab01a0 1331 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1332
73ab01a0 1333 ui_out_redirect (mi_uiout, mi->event_channel);
8de0566d 1334
73ab01a0
PA
1335 ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
1336 ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
1337 ui_out_field_fmt (mi_uiout, "len", "%s", hex_string (len));
8de0566d 1338
73ab01a0
PA
1339 /* Append 'type=code' into notification if MEMADDR falls in the range of
1340 sections contain code. */
1341 sec = find_pc_section (memaddr);
1342 if (sec != NULL && sec->objfile != NULL)
1343 {
1344 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1345 sec->the_bfd_section);
5fe96654 1346
73ab01a0
PA
1347 if (flags & SEC_CODE)
1348 ui_out_field_string (mi_uiout, "type", "code");
1349 }
1350
1351 ui_out_redirect (mi_uiout, NULL);
1352
1353 gdb_flush (mi->event_channel);
1354
1355 do_cleanups (old_chain);
1356 }
8de0566d
YQ
1357}
1358
a79b8f6e
VP
1359static int
1360report_initial_inferior (struct inferior *inf, void *closure)
1361{
73ab01a0 1362 /* This function is called from mi_interpreter_init, and since
a79b8f6e
VP
1363 mi_inferior_added assumes that inferior is fully initialized
1364 and top_level_interpreter_data is set, we cannot call
1365 it here. */
19ba03f4 1366 struct mi_interp *mi = (struct mi_interp *) closure;
5fe96654
PA
1367 struct cleanup *old_chain;
1368
1369 old_chain = make_cleanup_restore_target_terminal ();
1370 target_terminal_ours_for_output ();
102040f0 1371
a79b8f6e
VP
1372 fprintf_unfiltered (mi->event_channel,
1373 "thread-group-added,id=\"i%d\"",
1374 inf->num);
1375 gdb_flush (mi->event_channel);
5fe96654
PA
1376
1377 do_cleanups (old_chain);
a79b8f6e
VP
1378 return 0;
1379}
c86cf029 1380
4801a9a3
PA
1381static struct ui_out *
1382mi_ui_out (struct interp *interp)
1383{
19ba03f4 1384 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
4801a9a3 1385
fd664c91 1386 return mi->mi_uiout;
4801a9a3
PA
1387}
1388
37ce89eb
SS
1389/* Do MI-specific logging actions; save raw_stdout, and change all
1390 the consoles to use the supplied ui-file(s). */
1391
1392static int
1393mi_set_logging (struct interp *interp, int start_log,
1394 struct ui_file *out, struct ui_file *logfile)
1395{
19ba03f4 1396 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
37ce89eb
SS
1397
1398 if (!mi)
1399 return 0;
1400
1401 if (start_log)
1402 {
1403 /* The tee created already is based on gdb_stdout, which for MI
1404 is a console and so we end up in an infinite loop of console
1405 writing to ui_file writing to console etc. So discard the
1406 existing tee (it hasn't been used yet, and MI won't ever use
1407 it), and create one based on raw_stdout instead. */
1408 if (logfile)
1409 {
1410 ui_file_delete (out);
9204d692 1411 out = tee_file_new (mi->raw_stdout, 0, logfile, 0);
37ce89eb
SS
1412 }
1413
9204d692
PA
1414 mi->saved_raw_stdout = mi->raw_stdout;
1415 mi->raw_stdout = out;
37ce89eb
SS
1416 }
1417 else
1418 {
9204d692
PA
1419 mi->raw_stdout = mi->saved_raw_stdout;
1420 mi->saved_raw_stdout = NULL;
37ce89eb
SS
1421 }
1422
9204d692
PA
1423 mi_console_set_raw (mi->out, mi->raw_stdout);
1424 mi_console_set_raw (mi->err, mi->raw_stdout);
1425 mi_console_set_raw (mi->log, mi->raw_stdout);
1426 mi_console_set_raw (mi->targ, mi->raw_stdout);
1427 mi_console_set_raw (mi->event_channel, mi->raw_stdout);
37ce89eb
SS
1428
1429 return 1;
1430}
1431
8322445e
PA
1432/* The MI interpreter's vtable. */
1433
1434static const struct interp_procs mi_interp_procs =
1435{
1436 mi_interpreter_init, /* init_proc */
1437 mi_interpreter_resume, /* resume_proc */
1438 mi_interpreter_suspend, /* suspend_proc */
1439 mi_interpreter_exec, /* exec_proc */
1440 mi_ui_out, /* ui_out_proc */
1441 mi_set_logging, /* set_logging_proc */
b2d86570 1442 mi_interpreter_pre_command_loop /* pre_command_loop_proc */
8322445e
PA
1443};
1444
1445/* Factory for MI interpreters. */
1446
1447static struct interp *
1448mi_interp_factory (const char *name)
1449{
1450 return interp_new (name, &mi_interp_procs, NULL);
1451}
1452
b9362cc7
AC
1453extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
1454
4a8f6654
AC
1455void
1456_initialize_mi_interp (void)
1457{
2fcf52f0 1458 /* The various interpreter levels. */
8322445e
PA
1459 interp_factory_register (INTERP_MI1, mi_interp_factory);
1460 interp_factory_register (INTERP_MI2, mi_interp_factory);
1461 interp_factory_register (INTERP_MI3, mi_interp_factory);
1462 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0
PA
1463
1464 observer_attach_signal_received (mi_on_signal_received);
1465 observer_attach_end_stepping_range (mi_on_end_stepping_range);
1466 observer_attach_signal_exited (mi_on_signal_exited);
1467 observer_attach_exited (mi_on_exited);
1468 observer_attach_no_history (mi_on_no_history);
1469 observer_attach_new_thread (mi_new_thread);
1470 observer_attach_thread_exit (mi_thread_exit);
1471 observer_attach_inferior_added (mi_inferior_added);
1472 observer_attach_inferior_appeared (mi_inferior_appeared);
1473 observer_attach_inferior_exit (mi_inferior_exit);
1474 observer_attach_inferior_removed (mi_inferior_removed);
1475 observer_attach_record_changed (mi_record_changed);
1476 observer_attach_normal_stop (mi_on_normal_stop);
1477 observer_attach_target_resumed (mi_on_resume);
1478 observer_attach_solib_loaded (mi_solib_loaded);
1479 observer_attach_solib_unloaded (mi_solib_unloaded);
1480 observer_attach_about_to_proceed (mi_about_to_proceed);
1481 observer_attach_traceframe_changed (mi_traceframe_changed);
1482 observer_attach_tsv_created (mi_tsv_created);
1483 observer_attach_tsv_deleted (mi_tsv_deleted);
1484 observer_attach_tsv_modified (mi_tsv_modified);
1485 observer_attach_breakpoint_created (mi_breakpoint_created);
1486 observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
1487 observer_attach_breakpoint_modified (mi_breakpoint_modified);
1488 observer_attach_command_param_changed (mi_command_param_changed);
1489 observer_attach_memory_changed (mi_memory_changed);
1490 observer_attach_sync_execution_done (mi_on_sync_execution_done);
4a8f6654 1491}
This page took 1.184949 seconds and 4 git commands to generate.