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