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