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