gdb/copyright.py: Convert to Python 3
[deliverable/binutils-gdb.git] / gdb / mi / mi-interp.c
CommitLineData
4a8f6654
AC
1/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
2
42a4f53d 3 Copyright (C) 2002-2019 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
9204d692 964mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
e1ac3328 965{
a2840c35
VP
966 /* To cater for older frontends, emit ^running, but do it only once
967 per each command. We do it here, since at this point we know
968 that the target was successfully resumed, and in non-async mode,
969 we won't return back to MI interpreter code until the target
970 is done running, so delaying the output of "^running" until then
971 will make it impossible for frontend to know what's going on.
972
973 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 974 if (!running_result_record_printed && mi_proceeded)
a2840c35 975 {
9204d692 976 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
c271b6e2 977 current_token ? current_token : "");
a2840c35
VP
978 }
979
08036331
PA
980 /* Backwards compatibility. If doing a wildcard resume and there's
981 only one inferior, output "all", otherwise, output each resumed
982 thread individually. */
983 if ((ptid == minus_one_ptid || ptid.is_pid ())
984 && !multiple_inferiors_p ())
9204d692 985 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
e1ac3328 986 else
08036331
PA
987 for (thread_info *tp : all_non_exited_threads (ptid))
988 mi_output_running (tp);
a2840c35 989
f3b1572e 990 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
991 {
992 running_result_record_printed = 1;
3b12939d
PA
993 /* This is what gdb used to do historically -- printing prompt
994 even if it cannot actually accept any input. This will be
995 surely removed for MI3, and may be removed even earlier. */
996 if (current_ui->prompt_state == PROMPT_BLOCKED)
9204d692 997 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
a2840c35 998 }
9204d692 999 gdb_flush (mi->raw_stdout);
e1ac3328
VP
1000}
1001
c86cf029 1002static void
73ab01a0 1003mi_on_resume (ptid_t ptid)
c86cf029 1004{
73ab01a0 1005 struct thread_info *tp = NULL;
6ef284bd 1006
d7e15655 1007 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
1008 tp = inferior_thread ();
1009 else
1010 tp = find_thread_ptid (ptid);
6ef284bd 1011
73ab01a0
PA
1012 /* Suppress output while calling an inferior function. */
1013 if (tp->control.in_infcall)
1014 return;
6ef284bd 1015
0e454242 1016 SWITCH_THRU_ALL_UIS ()
6ef284bd 1017 {
73ab01a0 1018 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
1019
1020 if (mi == NULL)
1021 continue;
1022
223ffa71
TT
1023 target_terminal::scoped_restore_terminal_state term_state;
1024 target_terminal::ours_for_output ();
73ab01a0 1025
9204d692 1026 mi_on_resume_1 (mi, ptid);
6ef284bd 1027 }
73ab01a0 1028}
6ef284bd 1029
51457a05
MAL
1030/* See mi-interp.h. */
1031
1032void
1033mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
1034{
1035 struct gdbarch *gdbarch = target_gdbarch ();
1036
1037 uiout->field_string ("id", solib->so_original_name);
1038 uiout->field_string ("target-name", solib->so_original_name);
1039 uiout->field_string ("host-name", solib->so_name);
381befee 1040 uiout->field_signed ("symbols-loaded", solib->symbols_loaded);
51457a05
MAL
1041 if (!gdbarch_has_global_solist (target_gdbarch ()))
1042 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
1043
10f489e5
TT
1044 ui_out_emit_list list_emitter (uiout, "ranges");
1045 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
1046 if (solib->addr_high != 0)
1047 {
1048 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
1049 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
1050 }
51457a05
MAL
1051}
1052
73ab01a0
PA
1053static void
1054mi_solib_loaded (struct so_list *solib)
1055{
0e454242 1056 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1057 {
1058 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1059 struct ui_out *uiout;
5fe96654 1060
73ab01a0
PA
1061 if (mi == NULL)
1062 continue;
1063
29f94340 1064 uiout = top_level_interpreter ()->interp_ui_out ();
73ab01a0 1065
223ffa71
TT
1066 target_terminal::scoped_restore_terminal_state term_state;
1067 target_terminal::ours_for_output ();
73ab01a0
PA
1068
1069 fprintf_unfiltered (mi->event_channel, "library-loaded");
1070
112e8700 1071 uiout->redirect (mi->event_channel);
73ab01a0 1072
51457a05 1073 mi_output_solib_attribs (uiout, solib);
73ab01a0 1074
112e8700 1075 uiout->redirect (NULL);
73ab01a0
PA
1076
1077 gdb_flush (mi->event_channel);
73ab01a0 1078 }
c86cf029
VP
1079}
1080
1081static void
1082mi_solib_unloaded (struct so_list *solib)
1083{
0e454242 1084 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1085 {
1086 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1087 struct ui_out *uiout;
6ef284bd 1088
73ab01a0
PA
1089 if (mi == NULL)
1090 continue;
6ef284bd 1091
29f94340 1092 uiout = top_level_interpreter ()->interp_ui_out ();
6ef284bd 1093
223ffa71
TT
1094 target_terminal::scoped_restore_terminal_state term_state;
1095 target_terminal::ours_for_output ();
6ef284bd 1096
73ab01a0 1097 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1098
112e8700 1099 uiout->redirect (mi->event_channel);
5fe96654 1100
112e8700
SM
1101 uiout->field_string ("id", solib->so_original_name);
1102 uiout->field_string ("target-name", solib->so_original_name);
1103 uiout->field_string ("host-name", solib->so_name);
73ab01a0
PA
1104 if (!gdbarch_has_global_solist (target_gdbarch ()))
1105 {
112e8700 1106 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0
PA
1107 }
1108
112e8700 1109 uiout->redirect (NULL);
73ab01a0
PA
1110
1111 gdb_flush (mi->event_channel);
73ab01a0 1112 }
c86cf029
VP
1113}
1114
5b9afe8a
YQ
1115/* Emit notification about the command parameter change. */
1116
1117static void
1118mi_command_param_changed (const char *param, const char *value)
1119{
5b9afe8a
YQ
1120 if (mi_suppress_notification.cmd_param_changed)
1121 return;
1122
0e454242 1123 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1124 {
1125 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1126 struct ui_out *mi_uiout;
5b9afe8a 1127
73ab01a0
PA
1128 if (mi == NULL)
1129 continue;
5b9afe8a 1130
29f94340 1131 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 1132
223ffa71
TT
1133 target_terminal::scoped_restore_terminal_state term_state;
1134 target_terminal::ours_for_output ();
5b9afe8a 1135
73ab01a0 1136 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1137
112e8700 1138 mi_uiout->redirect (mi->event_channel);
5fe96654 1139
112e8700
SM
1140 mi_uiout->field_string ("param", param);
1141 mi_uiout->field_string ("value", value);
73ab01a0 1142
112e8700 1143 mi_uiout->redirect (NULL);
73ab01a0
PA
1144
1145 gdb_flush (mi->event_channel);
73ab01a0 1146 }
5b9afe8a
YQ
1147}
1148
8de0566d
YQ
1149/* Emit notification about the target memory change. */
1150
1151static void
1152mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1153 ssize_t len, const bfd_byte *myaddr)
1154{
8de0566d
YQ
1155 if (mi_suppress_notification.memory)
1156 return;
1157
0e454242 1158 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1159 {
1160 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1161 struct ui_out *mi_uiout;
1162 struct obj_section *sec;
8de0566d 1163
73ab01a0
PA
1164 if (mi == NULL)
1165 continue;
8de0566d 1166
29f94340 1167 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 1168
223ffa71
TT
1169 target_terminal::scoped_restore_terminal_state term_state;
1170 target_terminal::ours_for_output ();
8de0566d 1171
73ab01a0 1172 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1173
112e8700 1174 mi_uiout->redirect (mi->event_channel);
8de0566d 1175
112e8700
SM
1176 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
1177 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
33eca680 1178 mi_uiout->field_string ("len", hex_string (len));
8de0566d 1179
73ab01a0
PA
1180 /* Append 'type=code' into notification if MEMADDR falls in the range of
1181 sections contain code. */
1182 sec = find_pc_section (memaddr);
1183 if (sec != NULL && sec->objfile != NULL)
1184 {
fd361982 1185 flagword flags = bfd_section_flags (sec->the_bfd_section);
5fe96654 1186
73ab01a0 1187 if (flags & SEC_CODE)
112e8700 1188 mi_uiout->field_string ("type", "code");
73ab01a0
PA
1189 }
1190
112e8700 1191 mi_uiout->redirect (NULL);
73ab01a0
PA
1192
1193 gdb_flush (mi->event_channel);
73ab01a0 1194 }
8de0566d
YQ
1195}
1196
4034d0ff
AT
1197/* Emit an event when the selection context (inferior, thread, frame)
1198 changed. */
1199
1200static void
1201mi_user_selected_context_changed (user_selected_what selection)
1202{
4034d0ff
AT
1203 struct thread_info *tp;
1204
1205 /* Don't send an event if we're responding to an MI command. */
1206 if (mi_suppress_notification.user_selected_context)
1207 return;
1208
00431a78
PA
1209 if (inferior_ptid != null_ptid)
1210 tp = inferior_thread ();
1211 else
1212 tp = NULL;
4034d0ff 1213
0e454242 1214 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
1215 {
1216 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1217 struct ui_out *mi_uiout;
4034d0ff
AT
1218
1219 if (mi == NULL)
1220 continue;
1221
29f94340 1222 mi_uiout = top_level_interpreter ()->interp_ui_out ();
4034d0ff 1223
112e8700 1224 mi_uiout->redirect (mi->event_channel);
ca5909c7 1225 ui_out_redirect_pop redirect_popper (mi_uiout);
4034d0ff 1226
223ffa71
TT
1227 target_terminal::scoped_restore_terminal_state term_state;
1228 target_terminal::ours_for_output ();
4034d0ff
AT
1229
1230 if (selection & USER_SELECTED_INFERIOR)
1231 print_selected_inferior (mi->cli_uiout);
1232
1233 if (tp != NULL
1234 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1235 {
1236 print_selected_thread_frame (mi->cli_uiout, selection);
1237
1238 fprintf_unfiltered (mi->event_channel,
1239 "thread-selected,id=\"%d\"",
1240 tp->global_num);
1241
1242 if (tp->state != THREAD_RUNNING)
1243 {
1244 if (has_stack_frames ())
1245 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1246 1, SRC_AND_LOC, 1);
1247 }
1248 }
1249
1250 gdb_flush (mi->event_channel);
4034d0ff
AT
1251 }
1252}
1253
a79b8f6e
VP
1254static int
1255report_initial_inferior (struct inferior *inf, void *closure)
1256{
73ab01a0 1257 /* This function is called from mi_interpreter_init, and since
a79b8f6e
VP
1258 mi_inferior_added assumes that inferior is fully initialized
1259 and top_level_interpreter_data is set, we cannot call
1260 it here. */
19ba03f4 1261 struct mi_interp *mi = (struct mi_interp *) closure;
5fe96654 1262
223ffa71
TT
1263 target_terminal::scoped_restore_terminal_state term_state;
1264 target_terminal::ours_for_output ();
102040f0 1265
a79b8f6e
VP
1266 fprintf_unfiltered (mi->event_channel,
1267 "thread-group-added,id=\"i%d\"",
1268 inf->num);
1269 gdb_flush (mi->event_channel);
5fe96654 1270
a79b8f6e
VP
1271 return 0;
1272}
c86cf029 1273
d6f9b0fb
PA
1274ui_out *
1275mi_interp::interp_ui_out ()
4801a9a3 1276{
d6f9b0fb 1277 return this->mi_uiout;
4801a9a3
PA
1278}
1279
37ce89eb
SS
1280/* Do MI-specific logging actions; save raw_stdout, and change all
1281 the consoles to use the supplied ui-file(s). */
1282
d6f9b0fb 1283void
ca1285d1
AH
1284mi_interp::set_logging (ui_file_up logfile, bool logging_redirect,
1285 bool debug_redirect)
37ce89eb 1286{
d6f9b0fb 1287 struct mi_interp *mi = this;
37ce89eb 1288
616268b6 1289 if (logfile != NULL)
37ce89eb 1290 {
9204d692 1291 mi->saved_raw_stdout = mi->raw_stdout;
616268b6 1292
f3a09c80
AH
1293 /* If something is being redirected, then grab logfile. */
1294 ui_file *logfile_p = nullptr;
ca1285d1
AH
1295 if (logging_redirect || debug_redirect)
1296 {
1297 logfile_p = logfile.get ();
1298 mi->saved_raw_file_to_delete = logfile_p;
1299 }
f3a09c80
AH
1300
1301 /* If something is not being redirected, then a tee containing both the
1302 logfile and stdout. */
1303 ui_file *tee = nullptr;
ca1285d1
AH
1304 if (!logging_redirect || !debug_redirect)
1305 {
1306 tee = new tee_file (mi->raw_stdout, std::move (logfile));
1307 mi->saved_raw_file_to_delete = tee;
1308 }
f3a09c80
AH
1309
1310 mi->raw_stdout = logging_redirect ? logfile_p : tee;
ca1285d1 1311 mi->raw_stdlog = debug_redirect ? logfile_p : tee;
37ce89eb
SS
1312 }
1313 else
1314 {
ca1285d1 1315 delete mi->saved_raw_file_to_delete;
9204d692 1316 mi->raw_stdout = mi->saved_raw_stdout;
f3a09c80 1317 mi->saved_raw_stdout = nullptr;
ca1285d1 1318 mi->saved_raw_file_to_delete = nullptr;
37ce89eb 1319 }
f3a09c80 1320
d7e74731
PA
1321 mi->out->set_raw (mi->raw_stdout);
1322 mi->err->set_raw (mi->raw_stdout);
1323 mi->log->set_raw (mi->raw_stdout);
1324 mi->targ->set_raw (mi->raw_stdout);
1325 mi->event_channel->set_raw (mi->raw_stdout);
37ce89eb
SS
1326}
1327
8322445e
PA
1328/* Factory for MI interpreters. */
1329
1330static struct interp *
1331mi_interp_factory (const char *name)
1332{
d6f9b0fb 1333 return new mi_interp (name);
8322445e
PA
1334}
1335
4a8f6654
AC
1336void
1337_initialize_mi_interp (void)
1338{
2fcf52f0 1339 /* The various interpreter levels. */
8322445e
PA
1340 interp_factory_register (INTERP_MI1, mi_interp_factory);
1341 interp_factory_register (INTERP_MI2, mi_interp_factory);
1342 interp_factory_register (INTERP_MI3, mi_interp_factory);
1343 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1344
76727919
TT
1345 gdb::observers::signal_received.attach (mi_on_signal_received);
1346 gdb::observers::end_stepping_range.attach (mi_on_end_stepping_range);
1347 gdb::observers::signal_exited.attach (mi_on_signal_exited);
1348 gdb::observers::exited.attach (mi_on_exited);
1349 gdb::observers::no_history.attach (mi_on_no_history);
1350 gdb::observers::new_thread.attach (mi_new_thread);
1351 gdb::observers::thread_exit.attach (mi_thread_exit);
1352 gdb::observers::inferior_added.attach (mi_inferior_added);
1353 gdb::observers::inferior_appeared.attach (mi_inferior_appeared);
1354 gdb::observers::inferior_exit.attach (mi_inferior_exit);
1355 gdb::observers::inferior_removed.attach (mi_inferior_removed);
1356 gdb::observers::record_changed.attach (mi_record_changed);
1357 gdb::observers::normal_stop.attach (mi_on_normal_stop);
1358 gdb::observers::target_resumed.attach (mi_on_resume);
1359 gdb::observers::solib_loaded.attach (mi_solib_loaded);
1360 gdb::observers::solib_unloaded.attach (mi_solib_unloaded);
1361 gdb::observers::about_to_proceed.attach (mi_about_to_proceed);
1362 gdb::observers::traceframe_changed.attach (mi_traceframe_changed);
1363 gdb::observers::tsv_created.attach (mi_tsv_created);
1364 gdb::observers::tsv_deleted.attach (mi_tsv_deleted);
1365 gdb::observers::tsv_modified.attach (mi_tsv_modified);
1366 gdb::observers::breakpoint_created.attach (mi_breakpoint_created);
1367 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted);
1368 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified);
1369 gdb::observers::command_param_changed.attach (mi_command_param_changed);
1370 gdb::observers::memory_changed.attach (mi_memory_changed);
1371 gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done);
1372 gdb::observers::user_selected_context_changed.attach
4034d0ff 1373 (mi_user_selected_context_changed);
4a8f6654 1374}
This page took 2.028415 seconds and 4 git commands to generate.