]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-interp.c
Remove MI version 1
[thirdparty/binutils-gdb.git] / gdb / mi / mi-interp.c
CommitLineData
4a8f6654
AC
1/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
2
4a94e368 3 Copyright (C) 2002-2022 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"
23baa4cc
SM
21
22#include "mi-interp.h"
23
4a8f6654
AC
24#include "interps.h"
25#include "event-top.h"
400b5eca 26#include "gdbsupport/event-loop.h"
4a8f6654 27#include "inferior.h"
45741a9c 28#include "infrun.h"
4a8f6654
AC
29#include "ui-out.h"
30#include "top.h"
4a8f6654
AC
31#include "mi-main.h"
32#include "mi-cmds.h"
33#include "mi-out.h"
34#include "mi-console.h"
66bb093b 35#include "mi-common.h"
76727919 36#include "observable.h"
683f2885 37#include "gdbthread.h"
c86cf029 38#include "solist.h"
8de0566d 39#include "objfiles.h"
134a2066 40#include "tracepoint.h"
17b2616c 41#include "cli-out.h"
243a9253 42#include "thread-fsm.h"
26cde2cc 43#include "cli/cli-interp.h"
268a13a5 44#include "gdbsupport/scope-exit.h"
4a8f6654 45
2b03b41d
SS
46/* These are the interpreter setup, etc. functions for the MI
47 interpreter. */
48
ee047554 49static void mi_execute_command_wrapper (const char *cmd);
95bc9f0b
TT
50static void mi_execute_command_input_handler
51 (gdb::unique_xmalloc_ptr<char> &&cmd);
4a8f6654
AC
52
53/* These are hooks that we put in place while doing interpreter_exec
2b03b41d
SS
54 so we can report interesting things that happened "behind the MI's
55 back" in this command. */
56
bee0189a 57static int mi_interp_query_hook (const char *ctlstr, va_list ap)
2b03b41d 58 ATTRIBUTE_PRINTF (1, 0);
4a8f6654 59
4a8f6654
AC
60static void mi_insert_notify_hooks (void);
61static void mi_remove_notify_hooks (void);
fd664c91
PA
62
63static void mi_on_signal_received (enum gdb_signal siggnal);
64static void mi_on_end_stepping_range (void);
65static void mi_on_signal_exited (enum gdb_signal siggnal);
66static void mi_on_exited (int exitstatus);
313f3b21 67static void mi_on_normal_stop (struct bpstat *bs, int print_frame);
fd664c91 68static void mi_on_no_history (void);
4a8f6654 69
683f2885 70static void mi_new_thread (struct thread_info *t);
a07daef3 71static void mi_thread_exit (struct thread_info *t, int silent);
38b022b4
SM
72static void mi_record_changed (struct inferior*, int, const char *,
73 const char *);
a79b8f6e
VP
74static void mi_inferior_added (struct inferior *inf);
75static void mi_inferior_appeared (struct inferior *inf);
76static void mi_inferior_exit (struct inferior *inf);
77static void mi_inferior_removed (struct inferior *inf);
e1ac3328 78static void mi_on_resume (ptid_t ptid);
c86cf029
VP
79static void mi_solib_loaded (struct so_list *solib);
80static void mi_solib_unloaded (struct so_list *solib);
f3b1572e 81static void mi_about_to_proceed (void);
201b4506 82static void mi_traceframe_changed (int tfnum, int tpnum);
134a2066
YQ
83static void mi_tsv_created (const struct trace_state_variable *tsv);
84static void mi_tsv_deleted (const struct trace_state_variable *tsv);
85static void mi_tsv_modified (const struct trace_state_variable *tsv);
8d3788bd
VP
86static void mi_breakpoint_created (struct breakpoint *b);
87static void mi_breakpoint_deleted (struct breakpoint *b);
88static void mi_breakpoint_modified (struct breakpoint *b);
5b9afe8a 89static void mi_command_param_changed (const char *param, const char *value);
8de0566d
YQ
90static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
91 ssize_t len, const bfd_byte *myaddr);
329ea579 92static void mi_on_sync_execution_done (void);
683f2885 93
05beb275
PA
94/* Display the MI prompt. */
95
96static void
9204d692 97display_mi_prompt (struct mi_interp *mi)
05beb275 98{
3b12939d
PA
99 struct ui *ui = current_ui;
100
0426ad51 101 gdb_puts ("(gdb) \n", mi->raw_stdout);
9204d692 102 gdb_flush (mi->raw_stdout);
3b12939d 103 ui->prompt_state = PROMPTED;
05beb275
PA
104}
105
73ab01a0
PA
106/* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
107 returns NULL otherwise. */
108
109static struct mi_interp *
110as_mi_interp (struct interp *interp)
111{
716b8bc5 112 return dynamic_cast<mi_interp *> (interp);
73ab01a0
PA
113}
114
e8b4efc3
TT
115/* Observer for the command_error notification. */
116
117static void
118mi_on_command_error ()
119{
120 mi_interp *mi = as_mi_interp (top_level_interpreter ());
121 if (mi != nullptr)
122 display_mi_prompt (mi);
123}
124
d6f9b0fb
PA
125void
126mi_interp::init (bool top_level)
4a8f6654 127{
d6f9b0fb 128 mi_interp *mi = this;
4a8f6654 129
9204d692
PA
130 /* Store the current output channel, so that we can create a console
131 channel that encapsulates and prefixes all gdb_output-type bits
132 coming from the rest of the debugger. */
133 mi->raw_stdout = gdb_stdout;
4a8f6654 134
2b03b41d
SS
135 /* Create MI console channels, each with a different prefix so they
136 can be distinguished. */
d7e74731
PA
137 mi->out = new mi_console_file (mi->raw_stdout, "~", '"');
138 mi->err = new mi_console_file (mi->raw_stdout, "&", '"');
4a8f6654 139 mi->log = mi->err;
d7e74731
PA
140 mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
141 mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
8e5e5494
SM
142 mi->mi_uiout = mi_out_new (name ());
143 gdb_assert (mi->mi_uiout != nullptr);
66fd2c67 144 mi->cli_uiout = new cli_ui_out (mi->out);
fd664c91 145
683f2885 146 if (top_level)
063bfe2e 147 {
788eca49
SM
148 /* The initial inferior is created before this function is called, so we
149 need to report it explicitly when initializing the top-level MI
150 interpreter.
151
152 This is also called when additional MI interpreters are added (using
153 the new-ui command), when multiple inferiors possibly exist, so we need
154 to use iteration to report all the inferiors. mi_inferior_added can't
155 be used, because it would print the event on all the other MI UIs. */
156
157 for (inferior *inf : all_inferiors ())
158 {
159 target_terminal::scoped_restore_terminal_state term_state;
160 target_terminal::ours_for_output ();
161
6cb06a8c
TT
162 gdb_printf (mi->event_channel,
163 "thread-group-added,id=\"i%d\"",
164 inf->num);
788eca49
SM
165
166 gdb_flush (mi->event_channel);
167 }
168 }
4a8f6654
AC
169}
170
d6f9b0fb
PA
171void
172mi_interp::resume ()
4a8f6654 173{
d6f9b0fb 174 struct mi_interp *mi = this;
a74e1786 175 struct ui *ui = current_ui;
4a8f6654 176
2b03b41d
SS
177 /* As per hack note in mi_interpreter_init, swap in the output
178 channels... */
3c216924 179 gdb_setup_readline (0);
4a8f6654 180
a74e1786
PA
181 ui->call_readline = gdb_readline_no_editing_callback;
182 ui->input_handler = mi_execute_command_input_handler;
4a8f6654
AC
183
184 gdb_stdout = mi->out;
2b03b41d 185 /* Route error and log output through the MI. */
4a8f6654
AC
186 gdb_stderr = mi->err;
187 gdb_stdlog = mi->log;
2b03b41d 188 /* Route target output through the MI. */
4a8f6654 189 gdb_stdtarg = mi->targ;
2b03b41d 190 /* Route target error through the MI as well. */
1f20321b 191 gdb_stdtargerr = mi->targ;
4a8f6654 192
9a4105ab 193 deprecated_show_load_progress = mi_load_progress;
4a8f6654
AC
194}
195
d6f9b0fb
PA
196void
197mi_interp::suspend ()
4a8f6654
AC
198{
199 gdb_disable_readline ();
4a8f6654
AC
200}
201
d6f9b0fb
PA
202gdb_exception
203mi_interp::exec (const char *command)
4a8f6654 204{
ee047554 205 mi_execute_command_wrapper (command);
cc06b668 206 return gdb_exception ();
4a8f6654
AC
207}
208
ce8f13f8 209void
9f33b8b7 210mi_cmd_interpreter_exec (const char *command, char **argv, int argc)
4a8f6654
AC
211{
212 struct interp *interp_to_use;
4a8f6654 213 int i;
4a8f6654
AC
214
215 if (argc < 2)
1b05df00 216 error (_("-interpreter-exec: "
9b20d036 217 "Usage: -interpreter-exec interp command"));
4a8f6654 218
8322445e 219 interp_to_use = interp_lookup (current_ui, argv[0]);
4a8f6654 220 if (interp_to_use == NULL)
1b05df00 221 error (_("-interpreter-exec: could not find interpreter \"%s\""),
9a2b4c1b 222 argv[0]);
4a8f6654 223
17b2616c
PA
224 /* Note that unlike the CLI version of this command, we don't
225 actually set INTERP_TO_USE as the current interpreter, as we
226 still want gdb_stdout, etc. to point at MI streams. */
227
2b03b41d
SS
228 /* Insert the MI out hooks, making sure to also call the
229 interpreter's hooks if it has any. */
230 /* KRS: We shouldn't need this... Events should be installed and
231 they should just ALWAYS fire something out down the MI
232 channel. */
4a8f6654
AC
233 mi_insert_notify_hooks ();
234
2b03b41d 235 /* Now run the code. */
4a8f6654 236
3d6e9d23
TT
237 SCOPE_EXIT
238 {
239 mi_remove_notify_hooks ();
240 };
241
4a8f6654
AC
242 for (i = 1; i < argc; i++)
243 {
32c1e744 244 struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
102040f0 245
32c1e744 246 if (e.reason < 0)
3d6e9d23 247 error ("%s", e.what ());
4a8f6654 248 }
4a8f6654
AC
249}
250
2b03b41d
SS
251/* This inserts a number of hooks that are meant to produce
252 async-notify ("=") MI messages while running commands in another
253 interpreter using mi_interpreter_exec. The canonical use for this
254 is to allow access to the gdb CLI interpreter from within the MI,
255 while still producing MI style output when actions in the CLI
256 command change GDB's state. */
4a8f6654
AC
257
258static void
259mi_insert_notify_hooks (void)
260{
9a4105ab 261 deprecated_query_hook = mi_interp_query_hook;
4a8f6654
AC
262}
263
264static void
11308a41 265mi_remove_notify_hooks (void)
4a8f6654 266{
9a4105ab 267 deprecated_query_hook = NULL;
4a8f6654
AC
268}
269
270static int
271mi_interp_query_hook (const char *ctlstr, va_list ap)
272{
273 return 1;
274}
275
4a8f6654 276static void
ee047554 277mi_execute_command_wrapper (const char *cmd)
4a8f6654 278{
f38d3ad1
PA
279 struct ui *ui = current_ui;
280
268a799a 281 mi_execute_command (cmd, ui->instream == ui->stdin_stream);
4a8f6654
AC
282}
283
329ea579
PA
284/* Observer for the synchronous_command_done notification. */
285
286static void
287mi_on_sync_execution_done (void)
288{
73ab01a0
PA
289 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
290
291 if (mi == NULL)
292 return;
293
0b333c5e
PA
294 /* If MI is sync, then output the MI prompt now, indicating we're
295 ready for further input. */
329ea579 296 if (!mi_async_p ())
9204d692 297 display_mi_prompt (mi);
329ea579
PA
298}
299
e837f12a
JK
300/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
301
302static void
95bc9f0b 303mi_execute_command_input_handler (gdb::unique_xmalloc_ptr<char> &&cmd)
e837f12a 304{
9204d692 305 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
3b12939d
PA
306 struct ui *ui = current_ui;
307
308 ui->prompt_state = PROMPT_NEEDED;
9204d692 309
95bc9f0b 310 mi_execute_command_wrapper (cmd.get ());
e837f12a 311
0b333c5e
PA
312 /* Print a prompt, indicating we're ready for further input, unless
313 we just started a synchronous command. In that case, we're about
314 to go back to the event loop and will output the prompt in the
315 'synchronous_command_done' observer when the target next
316 stops. */
3b12939d 317 if (ui->prompt_state == PROMPT_NEEDED)
9204d692 318 display_mi_prompt (mi);
e837f12a
JK
319}
320
d6f9b0fb
PA
321void
322mi_interp::pre_command_loop ()
4a8f6654 323{
d6f9b0fb 324 struct mi_interp *mi = this;
9204d692 325
4a8f6654 326 /* Turn off 8 bit strings in quoted output. Any character with the
2b03b41d 327 high bit set is printed using C's octal format. */
4a8f6654 328 sevenbit_strings = 1;
2b03b41d
SS
329
330 /* Tell the world that we're alive. */
9204d692 331 display_mi_prompt (mi);
4a8f6654
AC
332}
333
683f2885
VP
334static void
335mi_new_thread (struct thread_info *t)
336{
0e454242 337 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
338 {
339 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
5fe96654 340
73ab01a0
PA
341 if (mi == NULL)
342 continue;
5fe96654 343
223ffa71
TT
344 target_terminal::scoped_restore_terminal_state term_state;
345 target_terminal::ours_for_output ();
73ab01a0 346
6cb06a8c
TT
347 gdb_printf (mi->event_channel,
348 "thread-created,id=\"%d\",group-id=\"i%d\"",
349 t->global_num, t->inf->num);
73ab01a0 350 gdb_flush (mi->event_channel);
73ab01a0 351 }
683f2885
VP
352}
353
063bfe2e 354static void
a07daef3 355mi_thread_exit (struct thread_info *t, int silent)
063bfe2e 356{
0e454242 357 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
358 {
359 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
a79b8f6e 360
73ab01a0
PA
361 if (mi == NULL)
362 continue;
5fe96654 363
223ffa71
TT
364 target_terminal::scoped_restore_terminal_state term_state;
365 target_terminal::ours_for_output ();
6cb06a8c
TT
366 gdb_printf (mi->event_channel,
367 "thread-exited,id=\"%d\",group-id=\"i%d\"",
368 t->global_num, t->inf->num);
73ab01a0 369 gdb_flush (mi->event_channel);
73ab01a0 370 }
063bfe2e
VP
371}
372
82a90ccf
YQ
373/* Emit notification on changing the state of record. */
374
375static void
38b022b4
SM
376mi_record_changed (struct inferior *inferior, int started, const char *method,
377 const char *format)
82a90ccf 378{
0e454242 379 SWITCH_THRU_ALL_UIS ()
38b022b4 380 {
73ab01a0 381 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
382
383 if (mi == NULL)
384 continue;
385
223ffa71
TT
386 target_terminal::scoped_restore_terminal_state term_state;
387 target_terminal::ours_for_output ();
73ab01a0
PA
388
389 if (started)
1aec0b6a 390 {
73ab01a0
PA
391 if (format != NULL)
392 {
6cb06a8c
TT
393 gdb_printf (mi->event_channel,
394 "record-started,thread-group=\"i%d\","
395 "method=\"%s\",format=\"%s\"",
396 inferior->num, method, format);
73ab01a0
PA
397 }
398 else
399 {
6cb06a8c
TT
400 gdb_printf (mi->event_channel,
401 "record-started,thread-group=\"i%d\","
402 "method=\"%s\"",
403 inferior->num, method);
73ab01a0 404 }
1aec0b6a 405 }
38b022b4 406 else
1aec0b6a 407 {
6cb06a8c
TT
408 gdb_printf (mi->event_channel,
409 "record-stopped,thread-group=\"i%d\"",
410 inferior->num);
1aec0b6a 411 }
38b022b4 412
73ab01a0 413 gdb_flush (mi->event_channel);
73ab01a0 414 }
82a90ccf
YQ
415}
416
a79b8f6e
VP
417static void
418mi_inferior_added (struct inferior *inf)
419{
0e454242 420 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
421 {
422 struct interp *interp;
423 struct mi_interp *mi;
102040f0 424
73ab01a0
PA
425 /* We'll be called once for the initial inferior, before the top
426 level interpreter is set. */
427 interp = top_level_interpreter ();
428 if (interp == NULL)
429 continue;
5fe96654 430
73ab01a0
PA
431 mi = as_mi_interp (interp);
432 if (mi == NULL)
433 continue;
434
223ffa71
TT
435 target_terminal::scoped_restore_terminal_state term_state;
436 target_terminal::ours_for_output ();
73ab01a0 437
6cb06a8c
TT
438 gdb_printf (mi->event_channel,
439 "thread-group-added,id=\"i%d\"",
440 inf->num);
73ab01a0 441 gdb_flush (mi->event_channel);
73ab01a0 442 }
a79b8f6e
VP
443}
444
445static void
446mi_inferior_appeared (struct inferior *inf)
4a92f99b 447{
0e454242 448 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
449 {
450 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
102040f0 451
73ab01a0
PA
452 if (mi == NULL)
453 continue;
5fe96654 454
223ffa71
TT
455 target_terminal::scoped_restore_terminal_state term_state;
456 target_terminal::ours_for_output ();
73ab01a0 457
6cb06a8c
TT
458 gdb_printf (mi->event_channel,
459 "thread-group-started,id=\"i%d\",pid=\"%d\"",
460 inf->num, inf->pid);
73ab01a0 461 gdb_flush (mi->event_channel);
73ab01a0 462 }
4a92f99b
VP
463}
464
465static void
a79b8f6e 466mi_inferior_exit (struct inferior *inf)
4a92f99b 467{
0e454242 468 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
469 {
470 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
102040f0 471
73ab01a0
PA
472 if (mi == NULL)
473 continue;
8cf64490 474
223ffa71
TT
475 target_terminal::scoped_restore_terminal_state term_state;
476 target_terminal::ours_for_output ();
73ab01a0
PA
477
478 if (inf->has_exit_code)
6cb06a8c
TT
479 gdb_printf (mi->event_channel,
480 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
481 inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
73ab01a0 482 else
6cb06a8c
TT
483 gdb_printf (mi->event_channel,
484 "thread-group-exited,id=\"i%d\"", inf->num);
73ab01a0
PA
485
486 gdb_flush (mi->event_channel);
73ab01a0 487 }
4a92f99b
VP
488}
489
a79b8f6e
VP
490static void
491mi_inferior_removed (struct inferior *inf)
492{
0e454242 493 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
494 {
495 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
102040f0 496
73ab01a0
PA
497 if (mi == NULL)
498 continue;
5fe96654 499
223ffa71
TT
500 target_terminal::scoped_restore_terminal_state term_state;
501 target_terminal::ours_for_output ();
73ab01a0 502
6cb06a8c
TT
503 gdb_printf (mi->event_channel,
504 "thread-group-removed,id=\"i%d\"",
505 inf->num);
73ab01a0 506 gdb_flush (mi->event_channel);
73ab01a0 507 }
a79b8f6e
VP
508}
509
fd664c91
PA
510/* Return the MI interpreter, if it is active -- either because it's
511 the top-level interpreter or the interpreter executing the current
512 command. Returns NULL if the MI interpreter is not being used. */
513
73ab01a0
PA
514static struct mi_interp *
515find_mi_interp (void)
fd664c91 516{
73ab01a0 517 struct mi_interp *mi;
fd664c91 518
73ab01a0
PA
519 mi = as_mi_interp (top_level_interpreter ());
520 if (mi != NULL)
521 return mi;
fd664c91 522
73ab01a0
PA
523 mi = as_mi_interp (command_interp ());
524 if (mi != NULL)
525 return mi;
fd664c91 526
fd664c91
PA
527 return NULL;
528}
529
530/* Observers for several run control events that print why the
6471e7d2 531 inferior has stopped to both the MI event channel and to the MI
fd664c91
PA
532 console. If the MI interpreter is not active, print nothing. */
533
534/* Observer for the signal_received notification. */
535
536static void
537mi_on_signal_received (enum gdb_signal siggnal)
538{
0e454242 539 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
540 {
541 struct mi_interp *mi = find_mi_interp ();
542
543 if (mi == NULL)
544 continue;
fd664c91 545
73ab01a0
PA
546 print_signal_received_reason (mi->mi_uiout, siggnal);
547 print_signal_received_reason (mi->cli_uiout, siggnal);
548 }
fd664c91
PA
549}
550
551/* Observer for the end_stepping_range notification. */
552
553static void
554mi_on_end_stepping_range (void)
555{
0e454242 556 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
557 {
558 struct mi_interp *mi = find_mi_interp ();
559
560 if (mi == NULL)
561 continue;
fd664c91 562
73ab01a0
PA
563 print_end_stepping_range_reason (mi->mi_uiout);
564 print_end_stepping_range_reason (mi->cli_uiout);
565 }
fd664c91
PA
566}
567
568/* Observer for the signal_exited notification. */
17b2616c
PA
569
570static void
fd664c91 571mi_on_signal_exited (enum gdb_signal siggnal)
17b2616c 572{
0e454242 573 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
574 {
575 struct mi_interp *mi = find_mi_interp ();
576
577 if (mi == NULL)
578 continue;
fd664c91 579
73ab01a0
PA
580 print_signal_exited_reason (mi->mi_uiout, siggnal);
581 print_signal_exited_reason (mi->cli_uiout, siggnal);
582 }
fd664c91
PA
583}
584
585/* Observer for the exited notification. */
586
587static void
588mi_on_exited (int exitstatus)
589{
0e454242 590 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
591 {
592 struct mi_interp *mi = find_mi_interp ();
593
594 if (mi == NULL)
595 continue;
fd664c91 596
73ab01a0
PA
597 print_exited_reason (mi->mi_uiout, exitstatus);
598 print_exited_reason (mi->cli_uiout, exitstatus);
599 }
fd664c91
PA
600}
601
602/* Observer for the no_history notification. */
603
604static void
605mi_on_no_history (void)
606{
0e454242 607 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
608 {
609 struct mi_interp *mi = find_mi_interp ();
fd664c91 610
73ab01a0
PA
611 if (mi == NULL)
612 continue;
613
614 print_no_history_reason (mi->mi_uiout);
615 print_no_history_reason (mi->cli_uiout);
616 }
17b2616c
PA
617}
618
f7f9a841 619static void
313f3b21 620mi_on_normal_stop_1 (struct bpstat *bs, int print_frame)
f7f9a841
VP
621{
622 /* Since this can be called when CLI command is executing,
623 using cli interpreter, be sure to use MI uiout for output,
624 not the current one. */
29f94340 625 struct ui_out *mi_uiout = top_level_interpreter ()->interp_ui_out ();
d6f9b0fb 626 struct mi_interp *mi = (struct mi_interp *) top_level_interpreter ();
f7f9a841 627
1d33d6ba
VP
628 if (print_frame)
629 {
243a9253 630 struct thread_info *tp;
dc146f7c 631 int core;
26cde2cc 632 struct interp *console_interp;
102040f0 633
243a9253 634 tp = inferior_thread ();
36dfb11c 635
573269a8
LS
636 if (tp->thread_fsm () != nullptr
637 && tp->thread_fsm ()->finished_p ())
243a9253
PA
638 {
639 enum async_reply_reason reason;
36dfb11c 640
573269a8 641 reason = tp->thread_fsm ()->async_reply_reason ();
112e8700 642 mi_uiout->field_string ("reason", async_reason_lookup (reason));
1d33d6ba 643 }
243a9253 644
26cde2cc 645 console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
4c7d57e7
TT
646 /* We only want to print the displays once, and we want it to
647 look just how it would on the console, so we use this to
648 decide whether the MI stop should include them. */
649 bool console_print = should_print_stop_to_console (console_interp, tp);
650 print_stop_event (mi_uiout, !console_print);
651
652 if (console_print)
9204d692 653 print_stop_event (mi->cli_uiout);
1d33d6ba 654
381befee 655 mi_uiout->field_signed ("thread-id", tp->global_num);
1d33d6ba
VP
656 if (non_stop)
657 {
10f489e5 658 ui_out_emit_list list_emitter (mi_uiout, "stopped-threads");
102040f0 659
381befee 660 mi_uiout->field_signed (NULL, tp->global_num);
1d33d6ba
VP
661 }
662 else
112e8700 663 mi_uiout->field_string ("stopped-threads", "all");
dc146f7c 664
00431a78 665 core = target_core_of_thread (tp->ptid);
dc146f7c 666 if (core != -1)
381befee 667 mi_uiout->field_signed ("core", core);
1d33d6ba
VP
668 }
669
0426ad51 670 gdb_puts ("*stopped", mi->raw_stdout);
9204d692 671 mi_out_put (mi_uiout, mi->raw_stdout);
1d33d6ba 672 mi_out_rewind (mi_uiout);
9204d692 673 mi_print_timing_maybe (mi->raw_stdout);
0426ad51 674 gdb_puts ("\n", mi->raw_stdout);
9204d692 675 gdb_flush (mi->raw_stdout);
f7f9a841
VP
676}
677
73ab01a0 678static void
313f3b21 679mi_on_normal_stop (struct bpstat *bs, int print_frame)
73ab01a0 680{
0e454242 681 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
682 {
683 if (as_mi_interp (top_level_interpreter ()) == NULL)
684 continue;
685
686 mi_on_normal_stop_1 (bs, print_frame);
687 }
688}
689
f3b1572e
PA
690static void
691mi_about_to_proceed (void)
692{
693 /* Suppress output while calling an inferior function. */
694
d7e15655 695 if (inferior_ptid != null_ptid)
f3b1572e
PA
696 {
697 struct thread_info *tp = inferior_thread ();
102040f0 698
16c381f0 699 if (tp->control.in_infcall)
f3b1572e
PA
700 return;
701 }
702
703 mi_proceeded = 1;
704}
705
5b9afe8a
YQ
706/* When the element is non-zero, no MI notifications will be emitted in
707 response to the corresponding observers. */
2b03b41d 708
5b9afe8a
YQ
709struct mi_suppress_notification mi_suppress_notification =
710 {
711 0,
712 0,
201b4506 713 0,
4034d0ff 714 0,
5b9afe8a 715 };
8d3788bd 716
201b4506
YQ
717/* Emit notification on changing a traceframe. */
718
719static void
720mi_traceframe_changed (int tfnum, int tpnum)
721{
201b4506
YQ
722 if (mi_suppress_notification.traceframe)
723 return;
724
0e454242 725 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
726 {
727 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
201b4506 728
73ab01a0
PA
729 if (mi == NULL)
730 continue;
201b4506 731
223ffa71
TT
732 target_terminal::scoped_restore_terminal_state term_state;
733 target_terminal::ours_for_output ();
5fe96654 734
73ab01a0 735 if (tfnum >= 0)
6cb06a8c
TT
736 gdb_printf (mi->event_channel, "traceframe-changed,"
737 "num=\"%d\",tracepoint=\"%d\"",
738 tfnum, tpnum);
73ab01a0 739 else
6cb06a8c 740 gdb_printf (mi->event_channel, "traceframe-changed,end");
73ab01a0
PA
741
742 gdb_flush (mi->event_channel);
73ab01a0 743 }
201b4506
YQ
744}
745
bb25a15c
YQ
746/* Emit notification on creating a trace state variable. */
747
748static void
134a2066 749mi_tsv_created (const struct trace_state_variable *tsv)
bb25a15c 750{
0e454242 751 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
752 {
753 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
bb25a15c 754
73ab01a0
PA
755 if (mi == NULL)
756 continue;
bb25a15c 757
223ffa71
TT
758 target_terminal::scoped_restore_terminal_state term_state;
759 target_terminal::ours_for_output ();
5fe96654 760
6cb06a8c
TT
761 gdb_printf (mi->event_channel, "tsv-created,"
762 "name=\"%s\",initial=\"%s\"",
763 tsv->name.c_str (), plongest (tsv->initial_value));
73ab01a0
PA
764
765 gdb_flush (mi->event_channel);
73ab01a0 766 }
bb25a15c
YQ
767}
768
769/* Emit notification on deleting a trace state variable. */
770
771static void
134a2066 772mi_tsv_deleted (const struct trace_state_variable *tsv)
bb25a15c 773{
0e454242 774 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
775 {
776 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
bb25a15c 777
73ab01a0
PA
778 if (mi == NULL)
779 continue;
bb25a15c 780
223ffa71
TT
781 target_terminal::scoped_restore_terminal_state term_state;
782 target_terminal::ours_for_output ();
5fe96654 783
73ab01a0 784 if (tsv != NULL)
6cb06a8c
TT
785 gdb_printf (mi->event_channel, "tsv-deleted,"
786 "name=\"%s\"", tsv->name.c_str ());
73ab01a0 787 else
6cb06a8c 788 gdb_printf (mi->event_channel, "tsv-deleted");
73ab01a0
PA
789
790 gdb_flush (mi->event_channel);
73ab01a0 791 }
bb25a15c
YQ
792}
793
134a2066
YQ
794/* Emit notification on modifying a trace state variable. */
795
796static void
797mi_tsv_modified (const struct trace_state_variable *tsv)
798{
0e454242 799 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
800 {
801 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
802 struct ui_out *mi_uiout;
134a2066 803
73ab01a0
PA
804 if (mi == NULL)
805 continue;
134a2066 806
29f94340 807 mi_uiout = top_level_interpreter ()->interp_ui_out ();
134a2066 808
223ffa71
TT
809 target_terminal::scoped_restore_terminal_state term_state;
810 target_terminal::ours_for_output ();
134a2066 811
6cb06a8c
TT
812 gdb_printf (mi->event_channel,
813 "tsv-modified");
134a2066 814
992aeed8 815 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
5fe96654 816
112e8700
SM
817 mi_uiout->field_string ("name", tsv->name);
818 mi_uiout->field_string ("initial",
992aeed8 819 plongest (tsv->initial_value));
73ab01a0 820 if (tsv->value_known)
112e8700 821 mi_uiout->field_string ("current", plongest (tsv->value));
73ab01a0 822
73ab01a0 823 gdb_flush (mi->event_channel);
73ab01a0 824 }
134a2066
YQ
825}
826
65630365
PA
827/* Print breakpoint BP on MI's event channel. */
828
829static void
830mi_print_breakpoint_for_event (struct mi_interp *mi, breakpoint *bp)
831{
29f94340 832 ui_out *mi_uiout = mi->interp_ui_out ();
65630365
PA
833
834 /* We want the output from print_breakpoint to go to
835 mi->event_channel. One approach would be to just call
836 print_breakpoint, and then use mi_out_put to send the current
837 content of mi_uiout into mi->event_channel. However, that will
838 break if anything is output to mi_uiout prior to calling the
839 breakpoint_created notifications. So, we use
840 ui_out_redirect. */
992aeed8 841 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
65630365 842
a70b8144 843 try
65630365
PA
844 {
845 scoped_restore restore_uiout
846 = make_scoped_restore (&current_uiout, mi_uiout);
847
848 print_breakpoint (bp);
849 }
230d2906 850 catch (const gdb_exception &ex)
65630365
PA
851 {
852 exception_print (gdb_stderr, ex);
853 }
65630365
PA
854}
855
8d3788bd 856/* Emit notification about a created breakpoint. */
2b03b41d 857
8d3788bd
VP
858static void
859mi_breakpoint_created (struct breakpoint *b)
860{
5b9afe8a 861 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
862 return;
863
864 if (b->number <= 0)
865 return;
866
0e454242 867 SWITCH_THRU_ALL_UIS ()
492d29ea 868 {
73ab01a0 869 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 870
73ab01a0
PA
871 if (mi == NULL)
872 continue;
8d3788bd 873
223ffa71
TT
874 target_terminal::scoped_restore_terminal_state term_state;
875 target_terminal::ours_for_output ();
73ab01a0 876
6cb06a8c
TT
877 gdb_printf (mi->event_channel,
878 "breakpoint-created");
65630365 879 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
880
881 gdb_flush (mi->event_channel);
73ab01a0 882 }
8d3788bd
VP
883}
884
885/* Emit notification about deleted breakpoint. */
2b03b41d 886
8d3788bd
VP
887static void
888mi_breakpoint_deleted (struct breakpoint *b)
889{
5b9afe8a 890 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
891 return;
892
893 if (b->number <= 0)
894 return;
895
0e454242 896 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
897 {
898 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
8d3788bd 899
73ab01a0
PA
900 if (mi == NULL)
901 continue;
8d3788bd 902
223ffa71
TT
903 target_terminal::scoped_restore_terminal_state term_state;
904 target_terminal::ours_for_output ();
5fe96654 905
6cb06a8c
TT
906 gdb_printf (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
907 b->number);
73ab01a0
PA
908
909 gdb_flush (mi->event_channel);
73ab01a0 910 }
8d3788bd
VP
911}
912
913/* Emit notification about modified breakpoint. */
2b03b41d 914
8d3788bd
VP
915static void
916mi_breakpoint_modified (struct breakpoint *b)
917{
5b9afe8a 918 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
919 return;
920
921 if (b->number <= 0)
922 return;
923
0e454242 924 SWITCH_THRU_ALL_UIS ()
492d29ea 925 {
73ab01a0 926 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 927
73ab01a0
PA
928 if (mi == NULL)
929 continue;
8d3788bd 930
223ffa71
TT
931 target_terminal::scoped_restore_terminal_state term_state;
932 target_terminal::ours_for_output ();
6cb06a8c
TT
933 gdb_printf (mi->event_channel,
934 "breakpoint-modified");
65630365 935 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
936
937 gdb_flush (mi->event_channel);
73ab01a0 938 }
8d3788bd
VP
939}
940
00431a78
PA
941static void
942mi_output_running (struct thread_info *thread)
d90e17a7 943{
0e454242 944 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
945 {
946 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
947
948 if (mi == NULL)
949 continue;
950
6cb06a8c
TT
951 gdb_printf (mi->raw_stdout,
952 "*running,thread-id=\"%d\"\n",
953 thread->global_num);
73ab01a0 954 }
d90e17a7
PA
955}
956
08036331
PA
957/* Return true if there are multiple inferiors loaded. This is used
958 for backwards compatibility -- if there's only one inferior, output
959 "all", otherwise, output each resumed thread individually. */
960
961static bool
962multiple_inferiors_p ()
963{
964 int count = 0;
965 for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
966 {
967 count++;
968 if (count > 1)
969 return true;
970 }
971
972 return false;
973}
974
e1ac3328 975static void
5b6d1e4f
PA
976mi_on_resume_1 (struct mi_interp *mi,
977 process_stratum_target *targ, ptid_t ptid)
e1ac3328 978{
a2840c35
VP
979 /* To cater for older frontends, emit ^running, but do it only once
980 per each command. We do it here, since at this point we know
981 that the target was successfully resumed, and in non-async mode,
982 we won't return back to MI interpreter code until the target
983 is done running, so delaying the output of "^running" until then
984 will make it impossible for frontend to know what's going on.
985
986 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 987 if (!running_result_record_printed && mi_proceeded)
a2840c35 988 {
6cb06a8c
TT
989 gdb_printf (mi->raw_stdout, "%s^running\n",
990 current_token ? current_token : "");
a2840c35
VP
991 }
992
08036331
PA
993 /* Backwards compatibility. If doing a wildcard resume and there's
994 only one inferior, output "all", otherwise, output each resumed
995 thread individually. */
996 if ((ptid == minus_one_ptid || ptid.is_pid ())
997 && !multiple_inferiors_p ())
6cb06a8c 998 gdb_printf (mi->raw_stdout, "*running,thread-id=\"all\"\n");
e1ac3328 999 else
5b6d1e4f 1000 for (thread_info *tp : all_non_exited_threads (targ, ptid))
08036331 1001 mi_output_running (tp);
a2840c35 1002
f3b1572e 1003 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
1004 {
1005 running_result_record_printed = 1;
3b12939d
PA
1006 /* This is what gdb used to do historically -- printing prompt
1007 even if it cannot actually accept any input. This will be
1008 surely removed for MI3, and may be removed even earlier. */
1009 if (current_ui->prompt_state == PROMPT_BLOCKED)
0426ad51 1010 gdb_puts ("(gdb) \n", mi->raw_stdout);
a2840c35 1011 }
9204d692 1012 gdb_flush (mi->raw_stdout);
e1ac3328
VP
1013}
1014
c86cf029 1015static void
73ab01a0 1016mi_on_resume (ptid_t ptid)
c86cf029 1017{
73ab01a0 1018 struct thread_info *tp = NULL;
6ef284bd 1019
5b6d1e4f 1020 process_stratum_target *target = current_inferior ()->process_target ();
d7e15655 1021 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
1022 tp = inferior_thread ();
1023 else
5b6d1e4f 1024 tp = find_thread_ptid (target, ptid);
6ef284bd 1025
73ab01a0
PA
1026 /* Suppress output while calling an inferior function. */
1027 if (tp->control.in_infcall)
1028 return;
6ef284bd 1029
0e454242 1030 SWITCH_THRU_ALL_UIS ()
6ef284bd 1031 {
73ab01a0 1032 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
1033
1034 if (mi == NULL)
1035 continue;
1036
223ffa71
TT
1037 target_terminal::scoped_restore_terminal_state term_state;
1038 target_terminal::ours_for_output ();
73ab01a0 1039
5b6d1e4f 1040 mi_on_resume_1 (mi, target, ptid);
6ef284bd 1041 }
73ab01a0 1042}
6ef284bd 1043
51457a05
MAL
1044/* See mi-interp.h. */
1045
1046void
1047mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
1048{
1049 struct gdbarch *gdbarch = target_gdbarch ();
1050
1051 uiout->field_string ("id", solib->so_original_name);
1052 uiout->field_string ("target-name", solib->so_original_name);
1053 uiout->field_string ("host-name", solib->so_name);
381befee 1054 uiout->field_signed ("symbols-loaded", solib->symbols_loaded);
51457a05
MAL
1055 if (!gdbarch_has_global_solist (target_gdbarch ()))
1056 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
1057
10f489e5
TT
1058 ui_out_emit_list list_emitter (uiout, "ranges");
1059 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
1060 if (solib->addr_high != 0)
1061 {
1062 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
1063 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
1064 }
51457a05
MAL
1065}
1066
73ab01a0
PA
1067static void
1068mi_solib_loaded (struct so_list *solib)
1069{
0e454242 1070 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1071 {
1072 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1073 struct ui_out *uiout;
5fe96654 1074
73ab01a0
PA
1075 if (mi == NULL)
1076 continue;
1077
29f94340 1078 uiout = top_level_interpreter ()->interp_ui_out ();
73ab01a0 1079
223ffa71
TT
1080 target_terminal::scoped_restore_terminal_state term_state;
1081 target_terminal::ours_for_output ();
73ab01a0 1082
6cb06a8c 1083 gdb_printf (mi->event_channel, "library-loaded");
73ab01a0 1084
992aeed8 1085 ui_out_redirect_pop redir (uiout, mi->event_channel);
73ab01a0 1086
51457a05 1087 mi_output_solib_attribs (uiout, solib);
73ab01a0 1088
73ab01a0 1089 gdb_flush (mi->event_channel);
73ab01a0 1090 }
c86cf029
VP
1091}
1092
1093static void
1094mi_solib_unloaded (struct so_list *solib)
1095{
0e454242 1096 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1097 {
1098 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1099 struct ui_out *uiout;
6ef284bd 1100
73ab01a0
PA
1101 if (mi == NULL)
1102 continue;
6ef284bd 1103
29f94340 1104 uiout = top_level_interpreter ()->interp_ui_out ();
6ef284bd 1105
223ffa71
TT
1106 target_terminal::scoped_restore_terminal_state term_state;
1107 target_terminal::ours_for_output ();
6ef284bd 1108
6cb06a8c 1109 gdb_printf (mi->event_channel, "library-unloaded");
a79b8f6e 1110
992aeed8 1111 ui_out_redirect_pop redir (uiout, mi->event_channel);
5fe96654 1112
112e8700
SM
1113 uiout->field_string ("id", solib->so_original_name);
1114 uiout->field_string ("target-name", solib->so_original_name);
1115 uiout->field_string ("host-name", solib->so_name);
73ab01a0
PA
1116 if (!gdbarch_has_global_solist (target_gdbarch ()))
1117 {
112e8700 1118 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0
PA
1119 }
1120
73ab01a0 1121 gdb_flush (mi->event_channel);
73ab01a0 1122 }
c86cf029
VP
1123}
1124
5b9afe8a
YQ
1125/* Emit notification about the command parameter change. */
1126
1127static void
1128mi_command_param_changed (const char *param, const char *value)
1129{
5b9afe8a
YQ
1130 if (mi_suppress_notification.cmd_param_changed)
1131 return;
1132
0e454242 1133 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1134 {
1135 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1136 struct ui_out *mi_uiout;
5b9afe8a 1137
73ab01a0
PA
1138 if (mi == NULL)
1139 continue;
5b9afe8a 1140
29f94340 1141 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 1142
223ffa71
TT
1143 target_terminal::scoped_restore_terminal_state term_state;
1144 target_terminal::ours_for_output ();
5b9afe8a 1145
6cb06a8c 1146 gdb_printf (mi->event_channel, "cmd-param-changed");
5b9afe8a 1147
992aeed8 1148 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
5fe96654 1149
112e8700
SM
1150 mi_uiout->field_string ("param", param);
1151 mi_uiout->field_string ("value", value);
73ab01a0 1152
73ab01a0 1153 gdb_flush (mi->event_channel);
73ab01a0 1154 }
5b9afe8a
YQ
1155}
1156
8de0566d
YQ
1157/* Emit notification about the target memory change. */
1158
1159static void
1160mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1161 ssize_t len, const bfd_byte *myaddr)
1162{
8de0566d
YQ
1163 if (mi_suppress_notification.memory)
1164 return;
1165
0e454242 1166 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1167 {
1168 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1169 struct ui_out *mi_uiout;
1170 struct obj_section *sec;
8de0566d 1171
73ab01a0
PA
1172 if (mi == NULL)
1173 continue;
8de0566d 1174
29f94340 1175 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 1176
223ffa71
TT
1177 target_terminal::scoped_restore_terminal_state term_state;
1178 target_terminal::ours_for_output ();
8de0566d 1179
6cb06a8c 1180 gdb_printf (mi->event_channel, "memory-changed");
8de0566d 1181
992aeed8 1182 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
8de0566d 1183
112e8700
SM
1184 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
1185 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
33eca680 1186 mi_uiout->field_string ("len", hex_string (len));
8de0566d 1187
73ab01a0
PA
1188 /* Append 'type=code' into notification if MEMADDR falls in the range of
1189 sections contain code. */
1190 sec = find_pc_section (memaddr);
1191 if (sec != NULL && sec->objfile != NULL)
1192 {
fd361982 1193 flagword flags = bfd_section_flags (sec->the_bfd_section);
5fe96654 1194
73ab01a0 1195 if (flags & SEC_CODE)
112e8700 1196 mi_uiout->field_string ("type", "code");
73ab01a0
PA
1197 }
1198
73ab01a0 1199 gdb_flush (mi->event_channel);
73ab01a0 1200 }
8de0566d
YQ
1201}
1202
4034d0ff
AT
1203/* Emit an event when the selection context (inferior, thread, frame)
1204 changed. */
1205
1206static void
1207mi_user_selected_context_changed (user_selected_what selection)
1208{
4034d0ff
AT
1209 struct thread_info *tp;
1210
1211 /* Don't send an event if we're responding to an MI command. */
1212 if (mi_suppress_notification.user_selected_context)
1213 return;
1214
00431a78
PA
1215 if (inferior_ptid != null_ptid)
1216 tp = inferior_thread ();
1217 else
1218 tp = NULL;
4034d0ff 1219
0e454242 1220 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
1221 {
1222 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1223 struct ui_out *mi_uiout;
4034d0ff
AT
1224
1225 if (mi == NULL)
1226 continue;
1227
29f94340 1228 mi_uiout = top_level_interpreter ()->interp_ui_out ();
4034d0ff 1229
992aeed8 1230 ui_out_redirect_pop redirect_popper (mi_uiout, mi->event_channel);
4034d0ff 1231
223ffa71
TT
1232 target_terminal::scoped_restore_terminal_state term_state;
1233 target_terminal::ours_for_output ();
4034d0ff
AT
1234
1235 if (selection & USER_SELECTED_INFERIOR)
1236 print_selected_inferior (mi->cli_uiout);
1237
1238 if (tp != NULL
1239 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1240 {
1241 print_selected_thread_frame (mi->cli_uiout, selection);
1242
6cb06a8c
TT
1243 gdb_printf (mi->event_channel,
1244 "thread-selected,id=\"%d\"",
1245 tp->global_num);
4034d0ff
AT
1246
1247 if (tp->state != THREAD_RUNNING)
1248 {
1249 if (has_stack_frames ())
1250 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1251 1, SRC_AND_LOC, 1);
1252 }
1253 }
1254
1255 gdb_flush (mi->event_channel);
4034d0ff
AT
1256 }
1257}
1258
d6f9b0fb
PA
1259ui_out *
1260mi_interp::interp_ui_out ()
4801a9a3 1261{
d6f9b0fb 1262 return this->mi_uiout;
4801a9a3
PA
1263}
1264
37ce89eb
SS
1265/* Do MI-specific logging actions; save raw_stdout, and change all
1266 the consoles to use the supplied ui-file(s). */
1267
d6f9b0fb 1268void
ca1285d1
AH
1269mi_interp::set_logging (ui_file_up logfile, bool logging_redirect,
1270 bool debug_redirect)
37ce89eb 1271{
d6f9b0fb 1272 struct mi_interp *mi = this;
37ce89eb 1273
616268b6 1274 if (logfile != NULL)
37ce89eb 1275 {
9204d692 1276 mi->saved_raw_stdout = mi->raw_stdout;
616268b6 1277
2b141965 1278 ui_file *logfile_p = logfile.get ();
016c606c 1279 mi->logfile_holder = std::move (logfile);
f3a09c80
AH
1280
1281 /* If something is not being redirected, then a tee containing both the
1282 logfile and stdout. */
1283 ui_file *tee = nullptr;
ca1285d1
AH
1284 if (!logging_redirect || !debug_redirect)
1285 {
2b141965 1286 tee = new tee_file (mi->raw_stdout, logfile_p);
016c606c 1287 mi->stdout_holder.reset (tee);
ca1285d1 1288 }
f3a09c80
AH
1289
1290 mi->raw_stdout = logging_redirect ? logfile_p : tee;
37ce89eb
SS
1291 }
1292 else
1293 {
016c606c
TT
1294 mi->logfile_holder.reset ();
1295 mi->stdout_holder.reset ();
9204d692 1296 mi->raw_stdout = mi->saved_raw_stdout;
f3a09c80 1297 mi->saved_raw_stdout = nullptr;
37ce89eb 1298 }
f3a09c80 1299
d7e74731
PA
1300 mi->out->set_raw (mi->raw_stdout);
1301 mi->err->set_raw (mi->raw_stdout);
1302 mi->log->set_raw (mi->raw_stdout);
1303 mi->targ->set_raw (mi->raw_stdout);
1304 mi->event_channel->set_raw (mi->raw_stdout);
37ce89eb
SS
1305}
1306
8322445e
PA
1307/* Factory for MI interpreters. */
1308
1309static struct interp *
1310mi_interp_factory (const char *name)
1311{
d6f9b0fb 1312 return new mi_interp (name);
8322445e
PA
1313}
1314
6c265988 1315void _initialize_mi_interp ();
4a8f6654 1316void
6c265988 1317_initialize_mi_interp ()
4a8f6654 1318{
2fcf52f0 1319 /* The various interpreter levels. */
8322445e
PA
1320 interp_factory_register (INTERP_MI2, mi_interp_factory);
1321 interp_factory_register (INTERP_MI3, mi_interp_factory);
9db0d853 1322 interp_factory_register (INTERP_MI4, mi_interp_factory);
8322445e 1323 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1324
c90e7d63
SM
1325 gdb::observers::signal_received.attach (mi_on_signal_received, "mi-interp");
1326 gdb::observers::end_stepping_range.attach (mi_on_end_stepping_range,
1327 "mi-interp");
1328 gdb::observers::signal_exited.attach (mi_on_signal_exited, "mi-interp");
1329 gdb::observers::exited.attach (mi_on_exited, "mi-interp");
1330 gdb::observers::no_history.attach (mi_on_no_history, "mi-interp");
1331 gdb::observers::new_thread.attach (mi_new_thread, "mi-interp");
1332 gdb::observers::thread_exit.attach (mi_thread_exit, "mi-interp");
1333 gdb::observers::inferior_added.attach (mi_inferior_added, "mi-interp");
1334 gdb::observers::inferior_appeared.attach (mi_inferior_appeared, "mi-interp");
1335 gdb::observers::inferior_exit.attach (mi_inferior_exit, "mi-interp");
1336 gdb::observers::inferior_removed.attach (mi_inferior_removed, "mi-interp");
1337 gdb::observers::record_changed.attach (mi_record_changed, "mi-interp");
1338 gdb::observers::normal_stop.attach (mi_on_normal_stop, "mi-interp");
1339 gdb::observers::target_resumed.attach (mi_on_resume, "mi-interp");
1340 gdb::observers::solib_loaded.attach (mi_solib_loaded, "mi-interp");
1341 gdb::observers::solib_unloaded.attach (mi_solib_unloaded, "mi-interp");
1342 gdb::observers::about_to_proceed.attach (mi_about_to_proceed, "mi-interp");
1343 gdb::observers::traceframe_changed.attach (mi_traceframe_changed,
1344 "mi-interp");
1345 gdb::observers::tsv_created.attach (mi_tsv_created, "mi-interp");
1346 gdb::observers::tsv_deleted.attach (mi_tsv_deleted, "mi-interp");
1347 gdb::observers::tsv_modified.attach (mi_tsv_modified, "mi-interp");
1348 gdb::observers::breakpoint_created.attach (mi_breakpoint_created,
1349 "mi-interp");
1350 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted,
1351 "mi-interp");
1352 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified,
1353 "mi-interp");
1354 gdb::observers::command_param_changed.attach (mi_command_param_changed,
1355 "mi-interp");
e8b4efc3 1356 gdb::observers::command_error.attach (mi_on_command_error, "mi-interp");
c90e7d63
SM
1357 gdb::observers::memory_changed.attach (mi_memory_changed, "mi-interp");
1358 gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done,
1359 "mi-interp");
76727919 1360 gdb::observers::user_selected_context_changed.attach
c90e7d63 1361 (mi_user_selected_context_changed, "mi-interp");
4a8f6654 1362}