Add comments describing tui_ui_out and its fields, cleanup a bit
[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"
4a8f6654
AC
21#include "interps.h"
22#include "event-top.h"
23#include "event-loop.h"
24#include "inferior.h"
45741a9c 25#include "infrun.h"
4a8f6654
AC
26#include "ui-out.h"
27#include "top.h"
4a8f6654
AC
28#include "mi-main.h"
29#include "mi-cmds.h"
30#include "mi-out.h"
31#include "mi-console.h"
66bb093b 32#include "mi-common.h"
76727919 33#include "observable.h"
683f2885 34#include "gdbthread.h"
c86cf029 35#include "solist.h"
8de0566d 36#include "objfiles.h"
134a2066 37#include "tracepoint.h"
17b2616c 38#include "cli-out.h"
243a9253 39#include "thread-fsm.h"
26cde2cc 40#include "cli/cli-interp.h"
4a8f6654 41
2b03b41d
SS
42/* These are the interpreter setup, etc. functions for the MI
43 interpreter. */
44
ee047554 45static void mi_execute_command_wrapper (const char *cmd);
95bc9f0b
TT
46static void mi_execute_command_input_handler
47 (gdb::unique_xmalloc_ptr<char> &&cmd);
4a8f6654
AC
48
49/* These are hooks that we put in place while doing interpreter_exec
2b03b41d
SS
50 so we can report interesting things that happened "behind the MI's
51 back" in this command. */
52
bee0189a 53static int mi_interp_query_hook (const char *ctlstr, va_list ap)
2b03b41d 54 ATTRIBUTE_PRINTF (1, 0);
4a8f6654 55
4a8f6654
AC
56static void mi_insert_notify_hooks (void);
57static void mi_remove_notify_hooks (void);
fd664c91
PA
58
59static void mi_on_signal_received (enum gdb_signal siggnal);
60static void mi_on_end_stepping_range (void);
61static void mi_on_signal_exited (enum gdb_signal siggnal);
62static void mi_on_exited (int exitstatus);
1d33d6ba 63static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
fd664c91 64static void mi_on_no_history (void);
4a8f6654 65
683f2885 66static void mi_new_thread (struct thread_info *t);
a07daef3 67static void mi_thread_exit (struct thread_info *t, int silent);
38b022b4
SM
68static void mi_record_changed (struct inferior*, int, const char *,
69 const char *);
a79b8f6e
VP
70static void mi_inferior_added (struct inferior *inf);
71static void mi_inferior_appeared (struct inferior *inf);
72static void mi_inferior_exit (struct inferior *inf);
73static void mi_inferior_removed (struct inferior *inf);
e1ac3328 74static void mi_on_resume (ptid_t ptid);
c86cf029
VP
75static void mi_solib_loaded (struct so_list *solib);
76static void mi_solib_unloaded (struct so_list *solib);
f3b1572e 77static void mi_about_to_proceed (void);
201b4506 78static void mi_traceframe_changed (int tfnum, int tpnum);
134a2066
YQ
79static void mi_tsv_created (const struct trace_state_variable *tsv);
80static void mi_tsv_deleted (const struct trace_state_variable *tsv);
81static void mi_tsv_modified (const struct trace_state_variable *tsv);
8d3788bd
VP
82static void mi_breakpoint_created (struct breakpoint *b);
83static void mi_breakpoint_deleted (struct breakpoint *b);
84static void mi_breakpoint_modified (struct breakpoint *b);
5b9afe8a 85static void mi_command_param_changed (const char *param, const char *value);
8de0566d
YQ
86static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
87 ssize_t len, const bfd_byte *myaddr);
329ea579 88static void mi_on_sync_execution_done (void);
683f2885 89
a79b8f6e
VP
90static int report_initial_inferior (struct inferior *inf, void *closure);
91
05beb275
PA
92/* Display the MI prompt. */
93
94static void
9204d692 95display_mi_prompt (struct mi_interp *mi)
05beb275 96{
3b12939d
PA
97 struct ui *ui = current_ui;
98
9204d692
PA
99 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
100 gdb_flush (mi->raw_stdout);
3b12939d 101 ui->prompt_state = PROMPTED;
05beb275
PA
102}
103
73ab01a0
PA
104/* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
105 returns NULL otherwise. */
106
107static struct mi_interp *
108as_mi_interp (struct interp *interp)
109{
716b8bc5 110 return dynamic_cast<mi_interp *> (interp);
73ab01a0
PA
111}
112
d6f9b0fb
PA
113void
114mi_interp::init (bool top_level)
4a8f6654 115{
d6f9b0fb 116 mi_interp *mi = this;
4a8f6654 117
9204d692
PA
118 /* Store the current output channel, so that we can create a console
119 channel that encapsulates and prefixes all gdb_output-type bits
120 coming from the rest of the debugger. */
121 mi->raw_stdout = gdb_stdout;
4a8f6654 122
2b03b41d
SS
123 /* Create MI console channels, each with a different prefix so they
124 can be distinguished. */
d7e74731
PA
125 mi->out = new mi_console_file (mi->raw_stdout, "~", '"');
126 mi->err = new mi_console_file (mi->raw_stdout, "&", '"');
4a8f6654 127 mi->log = mi->err;
d7e74731
PA
128 mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
129 mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
8e5e5494
SM
130 mi->mi_uiout = mi_out_new (name ());
131 gdb_assert (mi->mi_uiout != nullptr);
fd664c91
PA
132 mi->cli_uiout = cli_out_new (mi->out);
133
683f2885 134 if (top_level)
063bfe2e 135 {
2b03b41d
SS
136 /* The initial inferior is created before this function is
137 called, so we need to report it explicitly. Use iteration in
138 case future version of GDB creates more than one inferior
139 up-front. */
a79b8f6e 140 iterate_over_inferiors (report_initial_inferior, mi);
063bfe2e 141 }
4a8f6654
AC
142}
143
d6f9b0fb
PA
144void
145mi_interp::resume ()
4a8f6654 146{
d6f9b0fb 147 struct mi_interp *mi = this;
a74e1786 148 struct ui *ui = current_ui;
4a8f6654 149
2b03b41d
SS
150 /* As per hack note in mi_interpreter_init, swap in the output
151 channels... */
3c216924 152 gdb_setup_readline (0);
4a8f6654 153
a74e1786
PA
154 ui->call_readline = gdb_readline_no_editing_callback;
155 ui->input_handler = mi_execute_command_input_handler;
4a8f6654
AC
156
157 gdb_stdout = mi->out;
2b03b41d 158 /* Route error and log output through the MI. */
4a8f6654
AC
159 gdb_stderr = mi->err;
160 gdb_stdlog = mi->log;
2b03b41d 161 /* Route target output through the MI. */
4a8f6654 162 gdb_stdtarg = mi->targ;
2b03b41d 163 /* Route target error through the MI as well. */
1f20321b 164 gdb_stdtargerr = mi->targ;
4a8f6654
AC
165
166 /* Replace all the hooks that we know about. There really needs to
167 be a better way of doing this... */
168 clear_interpreter_hooks ();
169
9a4105ab 170 deprecated_show_load_progress = mi_load_progress;
4a8f6654
AC
171}
172
d6f9b0fb
PA
173void
174mi_interp::suspend ()
4a8f6654
AC
175{
176 gdb_disable_readline ();
4a8f6654
AC
177}
178
d6f9b0fb
PA
179gdb_exception
180mi_interp::exec (const char *command)
4a8f6654 181{
ee047554 182 mi_execute_command_wrapper (command);
c1043fc2 183 return exception_none;
4a8f6654
AC
184}
185
ce8f13f8 186void
9f33b8b7 187mi_cmd_interpreter_exec (const char *command, char **argv, int argc)
4a8f6654
AC
188{
189 struct interp *interp_to_use;
4a8f6654 190 int i;
4a8f6654
AC
191
192 if (argc < 2)
1b05df00 193 error (_("-interpreter-exec: "
9b20d036 194 "Usage: -interpreter-exec interp command"));
4a8f6654 195
8322445e 196 interp_to_use = interp_lookup (current_ui, argv[0]);
4a8f6654 197 if (interp_to_use == NULL)
1b05df00 198 error (_("-interpreter-exec: could not find interpreter \"%s\""),
9a2b4c1b 199 argv[0]);
4a8f6654 200
17b2616c
PA
201 /* Note that unlike the CLI version of this command, we don't
202 actually set INTERP_TO_USE as the current interpreter, as we
203 still want gdb_stdout, etc. to point at MI streams. */
204
2b03b41d
SS
205 /* Insert the MI out hooks, making sure to also call the
206 interpreter's hooks if it has any. */
207 /* KRS: We shouldn't need this... Events should be installed and
208 they should just ALWAYS fire something out down the MI
209 channel. */
4a8f6654
AC
210 mi_insert_notify_hooks ();
211
2b03b41d 212 /* Now run the code. */
4a8f6654 213
56496dd4 214 std::string mi_error_message;
4a8f6654
AC
215 for (i = 1; i < argc; i++)
216 {
32c1e744 217 struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
102040f0 218
32c1e744
VP
219 if (e.reason < 0)
220 {
56496dd4 221 mi_error_message = e.message;
32c1e744
VP
222 break;
223 }
4a8f6654
AC
224 }
225
226 mi_remove_notify_hooks ();
227
56496dd4
TT
228 if (!mi_error_message.empty ())
229 error ("%s", mi_error_message.c_str ());
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
PA
628 print_stop_event (mi_uiout);
629
26cde2cc
PA
630 console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
631 if (should_print_stop_to_console (console_interp, tp))
9204d692 632 print_stop_event (mi->cli_uiout);
1d33d6ba 633
112e8700 634 mi_uiout->field_int ("thread-id", tp->global_num);
1d33d6ba
VP
635 if (non_stop)
636 {
10f489e5 637 ui_out_emit_list list_emitter (mi_uiout, "stopped-threads");
102040f0 638
112e8700 639 mi_uiout->field_int (NULL, tp->global_num);
1d33d6ba
VP
640 }
641 else
112e8700 642 mi_uiout->field_string ("stopped-threads", "all");
dc146f7c 643
00431a78 644 core = target_core_of_thread (tp->ptid);
dc146f7c 645 if (core != -1)
112e8700 646 mi_uiout->field_int ("core", core);
1d33d6ba
VP
647 }
648
9204d692
PA
649 fputs_unfiltered ("*stopped", mi->raw_stdout);
650 mi_out_put (mi_uiout, mi->raw_stdout);
1d33d6ba 651 mi_out_rewind (mi_uiout);
9204d692
PA
652 mi_print_timing_maybe (mi->raw_stdout);
653 fputs_unfiltered ("\n", mi->raw_stdout);
654 gdb_flush (mi->raw_stdout);
f7f9a841
VP
655}
656
73ab01a0
PA
657static void
658mi_on_normal_stop (struct bpstats *bs, int print_frame)
659{
0e454242 660 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
661 {
662 if (as_mi_interp (top_level_interpreter ()) == NULL)
663 continue;
664
665 mi_on_normal_stop_1 (bs, print_frame);
666 }
667}
668
f3b1572e
PA
669static void
670mi_about_to_proceed (void)
671{
672 /* Suppress output while calling an inferior function. */
673
d7e15655 674 if (inferior_ptid != null_ptid)
f3b1572e
PA
675 {
676 struct thread_info *tp = inferior_thread ();
102040f0 677
16c381f0 678 if (tp->control.in_infcall)
f3b1572e
PA
679 return;
680 }
681
682 mi_proceeded = 1;
683}
684
5b9afe8a
YQ
685/* When the element is non-zero, no MI notifications will be emitted in
686 response to the corresponding observers. */
2b03b41d 687
5b9afe8a
YQ
688struct mi_suppress_notification mi_suppress_notification =
689 {
690 0,
691 0,
201b4506 692 0,
4034d0ff 693 0,
5b9afe8a 694 };
8d3788bd 695
201b4506
YQ
696/* Emit notification on changing a traceframe. */
697
698static void
699mi_traceframe_changed (int tfnum, int tpnum)
700{
201b4506
YQ
701 if (mi_suppress_notification.traceframe)
702 return;
703
0e454242 704 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
705 {
706 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
201b4506 707
73ab01a0
PA
708 if (mi == NULL)
709 continue;
201b4506 710
223ffa71
TT
711 target_terminal::scoped_restore_terminal_state term_state;
712 target_terminal::ours_for_output ();
5fe96654 713
73ab01a0
PA
714 if (tfnum >= 0)
715 fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
716 "num=\"%d\",tracepoint=\"%d\"\n",
717 tfnum, tpnum);
718 else
719 fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
720
721 gdb_flush (mi->event_channel);
73ab01a0 722 }
201b4506
YQ
723}
724
bb25a15c
YQ
725/* Emit notification on creating a trace state variable. */
726
727static void
134a2066 728mi_tsv_created (const struct trace_state_variable *tsv)
bb25a15c 729{
0e454242 730 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
731 {
732 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
bb25a15c 733
73ab01a0
PA
734 if (mi == NULL)
735 continue;
bb25a15c 736
223ffa71
TT
737 target_terminal::scoped_restore_terminal_state term_state;
738 target_terminal::ours_for_output ();
5fe96654 739
73ab01a0
PA
740 fprintf_unfiltered (mi->event_channel, "tsv-created,"
741 "name=\"%s\",initial=\"%s\"\n",
c252925c 742 tsv->name.c_str (), plongest (tsv->initial_value));
73ab01a0
PA
743
744 gdb_flush (mi->event_channel);
73ab01a0 745 }
bb25a15c
YQ
746}
747
748/* Emit notification on deleting a trace state variable. */
749
750static void
134a2066 751mi_tsv_deleted (const struct trace_state_variable *tsv)
bb25a15c 752{
0e454242 753 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
754 {
755 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
bb25a15c 756
73ab01a0
PA
757 if (mi == NULL)
758 continue;
bb25a15c 759
223ffa71
TT
760 target_terminal::scoped_restore_terminal_state term_state;
761 target_terminal::ours_for_output ();
5fe96654 762
73ab01a0
PA
763 if (tsv != NULL)
764 fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
c252925c 765 "name=\"%s\"\n", tsv->name.c_str ());
73ab01a0
PA
766 else
767 fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
768
769 gdb_flush (mi->event_channel);
73ab01a0 770 }
bb25a15c
YQ
771}
772
134a2066
YQ
773/* Emit notification on modifying a trace state variable. */
774
775static void
776mi_tsv_modified (const struct trace_state_variable *tsv)
777{
0e454242 778 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
779 {
780 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
781 struct ui_out *mi_uiout;
134a2066 782
73ab01a0
PA
783 if (mi == NULL)
784 continue;
134a2066 785
29f94340 786 mi_uiout = top_level_interpreter ()->interp_ui_out ();
134a2066 787
223ffa71
TT
788 target_terminal::scoped_restore_terminal_state term_state;
789 target_terminal::ours_for_output ();
134a2066 790
73ab01a0
PA
791 fprintf_unfiltered (mi->event_channel,
792 "tsv-modified");
134a2066 793
112e8700 794 mi_uiout->redirect (mi->event_channel);
5fe96654 795
112e8700
SM
796 mi_uiout->field_string ("name", tsv->name);
797 mi_uiout->field_string ("initial",
73ab01a0
PA
798 plongest (tsv->initial_value));
799 if (tsv->value_known)
112e8700 800 mi_uiout->field_string ("current", plongest (tsv->value));
73ab01a0 801
112e8700 802 mi_uiout->redirect (NULL);
73ab01a0
PA
803
804 gdb_flush (mi->event_channel);
73ab01a0 805 }
134a2066
YQ
806}
807
65630365
PA
808/* Print breakpoint BP on MI's event channel. */
809
810static void
811mi_print_breakpoint_for_event (struct mi_interp *mi, breakpoint *bp)
812{
29f94340 813 ui_out *mi_uiout = mi->interp_ui_out ();
65630365
PA
814
815 /* We want the output from print_breakpoint to go to
816 mi->event_channel. One approach would be to just call
817 print_breakpoint, and then use mi_out_put to send the current
818 content of mi_uiout into mi->event_channel. However, that will
819 break if anything is output to mi_uiout prior to calling the
820 breakpoint_created notifications. So, we use
821 ui_out_redirect. */
822 mi_uiout->redirect (mi->event_channel);
823
824 TRY
825 {
826 scoped_restore restore_uiout
827 = make_scoped_restore (&current_uiout, mi_uiout);
828
829 print_breakpoint (bp);
830 }
831 CATCH (ex, RETURN_MASK_ALL)
832 {
833 exception_print (gdb_stderr, ex);
834 }
835 END_CATCH
836
837 mi_uiout->redirect (NULL);
838}
839
8d3788bd 840/* Emit notification about a created breakpoint. */
2b03b41d 841
8d3788bd
VP
842static void
843mi_breakpoint_created (struct breakpoint *b)
844{
5b9afe8a 845 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
846 return;
847
848 if (b->number <= 0)
849 return;
850
0e454242 851 SWITCH_THRU_ALL_UIS ()
492d29ea 852 {
73ab01a0 853 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 854
73ab01a0
PA
855 if (mi == NULL)
856 continue;
8d3788bd 857
223ffa71
TT
858 target_terminal::scoped_restore_terminal_state term_state;
859 target_terminal::ours_for_output ();
73ab01a0
PA
860
861 fprintf_unfiltered (mi->event_channel,
862 "breakpoint-created");
65630365 863 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
864
865 gdb_flush (mi->event_channel);
73ab01a0 866 }
8d3788bd
VP
867}
868
869/* Emit notification about deleted breakpoint. */
2b03b41d 870
8d3788bd
VP
871static void
872mi_breakpoint_deleted (struct breakpoint *b)
873{
5b9afe8a 874 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
875 return;
876
877 if (b->number <= 0)
878 return;
879
0e454242 880 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
881 {
882 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
8d3788bd 883
73ab01a0
PA
884 if (mi == NULL)
885 continue;
8d3788bd 886
223ffa71
TT
887 target_terminal::scoped_restore_terminal_state term_state;
888 target_terminal::ours_for_output ();
5fe96654 889
73ab01a0
PA
890 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
891 b->number);
892
893 gdb_flush (mi->event_channel);
73ab01a0 894 }
8d3788bd
VP
895}
896
897/* Emit notification about modified breakpoint. */
2b03b41d 898
8d3788bd
VP
899static void
900mi_breakpoint_modified (struct breakpoint *b)
901{
5b9afe8a 902 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
903 return;
904
905 if (b->number <= 0)
906 return;
907
0e454242 908 SWITCH_THRU_ALL_UIS ()
492d29ea 909 {
73ab01a0 910 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 911
73ab01a0
PA
912 if (mi == NULL)
913 continue;
8d3788bd 914
223ffa71
TT
915 target_terminal::scoped_restore_terminal_state term_state;
916 target_terminal::ours_for_output ();
73ab01a0
PA
917 fprintf_unfiltered (mi->event_channel,
918 "breakpoint-modified");
65630365 919 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
920
921 gdb_flush (mi->event_channel);
73ab01a0 922 }
8d3788bd
VP
923}
924
00431a78
PA
925static void
926mi_output_running (struct thread_info *thread)
d90e17a7 927{
0e454242 928 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
929 {
930 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
931
932 if (mi == NULL)
933 continue;
934
00431a78
PA
935 fprintf_unfiltered (mi->raw_stdout,
936 "*running,thread-id=\"%d\"\n",
937 thread->global_num);
73ab01a0 938 }
d90e17a7
PA
939}
940
08036331
PA
941/* Return true if there are multiple inferiors loaded. This is used
942 for backwards compatibility -- if there's only one inferior, output
943 "all", otherwise, output each resumed thread individually. */
944
945static bool
946multiple_inferiors_p ()
947{
948 int count = 0;
949 for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
950 {
951 count++;
952 if (count > 1)
953 return true;
954 }
955
956 return false;
957}
958
e1ac3328 959static void
9204d692 960mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
e1ac3328 961{
a2840c35
VP
962 /* To cater for older frontends, emit ^running, but do it only once
963 per each command. We do it here, since at this point we know
964 that the target was successfully resumed, and in non-async mode,
965 we won't return back to MI interpreter code until the target
966 is done running, so delaying the output of "^running" until then
967 will make it impossible for frontend to know what's going on.
968
969 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 970 if (!running_result_record_printed && mi_proceeded)
a2840c35 971 {
9204d692 972 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
c271b6e2 973 current_token ? current_token : "");
a2840c35
VP
974 }
975
08036331
PA
976 /* Backwards compatibility. If doing a wildcard resume and there's
977 only one inferior, output "all", otherwise, output each resumed
978 thread individually. */
979 if ((ptid == minus_one_ptid || ptid.is_pid ())
980 && !multiple_inferiors_p ())
9204d692 981 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
e1ac3328 982 else
08036331
PA
983 for (thread_info *tp : all_non_exited_threads (ptid))
984 mi_output_running (tp);
a2840c35 985
f3b1572e 986 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
987 {
988 running_result_record_printed = 1;
3b12939d
PA
989 /* This is what gdb used to do historically -- printing prompt
990 even if it cannot actually accept any input. This will be
991 surely removed for MI3, and may be removed even earlier. */
992 if (current_ui->prompt_state == PROMPT_BLOCKED)
9204d692 993 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
a2840c35 994 }
9204d692 995 gdb_flush (mi->raw_stdout);
e1ac3328
VP
996}
997
c86cf029 998static void
73ab01a0 999mi_on_resume (ptid_t ptid)
c86cf029 1000{
73ab01a0 1001 struct thread_info *tp = NULL;
6ef284bd 1002
d7e15655 1003 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
1004 tp = inferior_thread ();
1005 else
1006 tp = find_thread_ptid (ptid);
6ef284bd 1007
73ab01a0
PA
1008 /* Suppress output while calling an inferior function. */
1009 if (tp->control.in_infcall)
1010 return;
6ef284bd 1011
0e454242 1012 SWITCH_THRU_ALL_UIS ()
6ef284bd 1013 {
73ab01a0 1014 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
1015
1016 if (mi == NULL)
1017 continue;
1018
223ffa71
TT
1019 target_terminal::scoped_restore_terminal_state term_state;
1020 target_terminal::ours_for_output ();
73ab01a0 1021
9204d692 1022 mi_on_resume_1 (mi, ptid);
6ef284bd 1023 }
73ab01a0 1024}
6ef284bd 1025
51457a05
MAL
1026/* See mi-interp.h. */
1027
1028void
1029mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
1030{
1031 struct gdbarch *gdbarch = target_gdbarch ();
1032
1033 uiout->field_string ("id", solib->so_original_name);
1034 uiout->field_string ("target-name", solib->so_original_name);
1035 uiout->field_string ("host-name", solib->so_name);
1036 uiout->field_int ("symbols-loaded", solib->symbols_loaded);
1037 if (!gdbarch_has_global_solist (target_gdbarch ()))
1038 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
1039
10f489e5
TT
1040 ui_out_emit_list list_emitter (uiout, "ranges");
1041 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
1042 if (solib->addr_high != 0)
1043 {
1044 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
1045 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
1046 }
51457a05
MAL
1047}
1048
73ab01a0
PA
1049static void
1050mi_solib_loaded (struct so_list *solib)
1051{
0e454242 1052 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1053 {
1054 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1055 struct ui_out *uiout;
5fe96654 1056
73ab01a0
PA
1057 if (mi == NULL)
1058 continue;
1059
29f94340 1060 uiout = top_level_interpreter ()->interp_ui_out ();
73ab01a0 1061
223ffa71
TT
1062 target_terminal::scoped_restore_terminal_state term_state;
1063 target_terminal::ours_for_output ();
73ab01a0
PA
1064
1065 fprintf_unfiltered (mi->event_channel, "library-loaded");
1066
112e8700 1067 uiout->redirect (mi->event_channel);
73ab01a0 1068
51457a05 1069 mi_output_solib_attribs (uiout, solib);
73ab01a0 1070
112e8700 1071 uiout->redirect (NULL);
73ab01a0
PA
1072
1073 gdb_flush (mi->event_channel);
73ab01a0 1074 }
c86cf029
VP
1075}
1076
1077static void
1078mi_solib_unloaded (struct so_list *solib)
1079{
0e454242 1080 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1081 {
1082 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1083 struct ui_out *uiout;
6ef284bd 1084
73ab01a0
PA
1085 if (mi == NULL)
1086 continue;
6ef284bd 1087
29f94340 1088 uiout = top_level_interpreter ()->interp_ui_out ();
6ef284bd 1089
223ffa71
TT
1090 target_terminal::scoped_restore_terminal_state term_state;
1091 target_terminal::ours_for_output ();
6ef284bd 1092
73ab01a0 1093 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1094
112e8700 1095 uiout->redirect (mi->event_channel);
5fe96654 1096
112e8700
SM
1097 uiout->field_string ("id", solib->so_original_name);
1098 uiout->field_string ("target-name", solib->so_original_name);
1099 uiout->field_string ("host-name", solib->so_name);
73ab01a0
PA
1100 if (!gdbarch_has_global_solist (target_gdbarch ()))
1101 {
112e8700 1102 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0
PA
1103 }
1104
112e8700 1105 uiout->redirect (NULL);
73ab01a0
PA
1106
1107 gdb_flush (mi->event_channel);
73ab01a0 1108 }
c86cf029
VP
1109}
1110
5b9afe8a
YQ
1111/* Emit notification about the command parameter change. */
1112
1113static void
1114mi_command_param_changed (const char *param, const char *value)
1115{
5b9afe8a
YQ
1116 if (mi_suppress_notification.cmd_param_changed)
1117 return;
1118
0e454242 1119 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1120 {
1121 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1122 struct ui_out *mi_uiout;
5b9afe8a 1123
73ab01a0
PA
1124 if (mi == NULL)
1125 continue;
5b9afe8a 1126
29f94340 1127 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 1128
223ffa71
TT
1129 target_terminal::scoped_restore_terminal_state term_state;
1130 target_terminal::ours_for_output ();
5b9afe8a 1131
73ab01a0 1132 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1133
112e8700 1134 mi_uiout->redirect (mi->event_channel);
5fe96654 1135
112e8700
SM
1136 mi_uiout->field_string ("param", param);
1137 mi_uiout->field_string ("value", value);
73ab01a0 1138
112e8700 1139 mi_uiout->redirect (NULL);
73ab01a0
PA
1140
1141 gdb_flush (mi->event_channel);
73ab01a0 1142 }
5b9afe8a
YQ
1143}
1144
8de0566d
YQ
1145/* Emit notification about the target memory change. */
1146
1147static void
1148mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1149 ssize_t len, const bfd_byte *myaddr)
1150{
8de0566d
YQ
1151 if (mi_suppress_notification.memory)
1152 return;
1153
0e454242 1154 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1155 {
1156 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1157 struct ui_out *mi_uiout;
1158 struct obj_section *sec;
8de0566d 1159
73ab01a0
PA
1160 if (mi == NULL)
1161 continue;
8de0566d 1162
29f94340 1163 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 1164
223ffa71
TT
1165 target_terminal::scoped_restore_terminal_state term_state;
1166 target_terminal::ours_for_output ();
8de0566d 1167
73ab01a0 1168 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1169
112e8700 1170 mi_uiout->redirect (mi->event_channel);
8de0566d 1171
112e8700
SM
1172 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
1173 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
1174 mi_uiout->field_fmt ("len", "%s", hex_string (len));
8de0566d 1175
73ab01a0
PA
1176 /* Append 'type=code' into notification if MEMADDR falls in the range of
1177 sections contain code. */
1178 sec = find_pc_section (memaddr);
1179 if (sec != NULL && sec->objfile != NULL)
1180 {
1181 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1182 sec->the_bfd_section);
5fe96654 1183
73ab01a0 1184 if (flags & SEC_CODE)
112e8700 1185 mi_uiout->field_string ("type", "code");
73ab01a0
PA
1186 }
1187
112e8700 1188 mi_uiout->redirect (NULL);
73ab01a0
PA
1189
1190 gdb_flush (mi->event_channel);
73ab01a0 1191 }
8de0566d
YQ
1192}
1193
4034d0ff
AT
1194/* Emit an event when the selection context (inferior, thread, frame)
1195 changed. */
1196
1197static void
1198mi_user_selected_context_changed (user_selected_what selection)
1199{
4034d0ff
AT
1200 struct thread_info *tp;
1201
1202 /* Don't send an event if we're responding to an MI command. */
1203 if (mi_suppress_notification.user_selected_context)
1204 return;
1205
00431a78
PA
1206 if (inferior_ptid != null_ptid)
1207 tp = inferior_thread ();
1208 else
1209 tp = NULL;
4034d0ff 1210
0e454242 1211 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
1212 {
1213 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1214 struct ui_out *mi_uiout;
4034d0ff
AT
1215
1216 if (mi == NULL)
1217 continue;
1218
29f94340 1219 mi_uiout = top_level_interpreter ()->interp_ui_out ();
4034d0ff 1220
112e8700 1221 mi_uiout->redirect (mi->event_channel);
ca5909c7 1222 ui_out_redirect_pop redirect_popper (mi_uiout);
4034d0ff 1223
223ffa71
TT
1224 target_terminal::scoped_restore_terminal_state term_state;
1225 target_terminal::ours_for_output ();
4034d0ff
AT
1226
1227 if (selection & USER_SELECTED_INFERIOR)
1228 print_selected_inferior (mi->cli_uiout);
1229
1230 if (tp != NULL
1231 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1232 {
1233 print_selected_thread_frame (mi->cli_uiout, selection);
1234
1235 fprintf_unfiltered (mi->event_channel,
1236 "thread-selected,id=\"%d\"",
1237 tp->global_num);
1238
1239 if (tp->state != THREAD_RUNNING)
1240 {
1241 if (has_stack_frames ())
1242 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1243 1, SRC_AND_LOC, 1);
1244 }
1245 }
1246
1247 gdb_flush (mi->event_channel);
4034d0ff
AT
1248 }
1249}
1250
a79b8f6e
VP
1251static int
1252report_initial_inferior (struct inferior *inf, void *closure)
1253{
73ab01a0 1254 /* This function is called from mi_interpreter_init, and since
a79b8f6e
VP
1255 mi_inferior_added assumes that inferior is fully initialized
1256 and top_level_interpreter_data is set, we cannot call
1257 it here. */
19ba03f4 1258 struct mi_interp *mi = (struct mi_interp *) closure;
5fe96654 1259
223ffa71
TT
1260 target_terminal::scoped_restore_terminal_state term_state;
1261 target_terminal::ours_for_output ();
102040f0 1262
a79b8f6e
VP
1263 fprintf_unfiltered (mi->event_channel,
1264 "thread-group-added,id=\"i%d\"",
1265 inf->num);
1266 gdb_flush (mi->event_channel);
5fe96654 1267
a79b8f6e
VP
1268 return 0;
1269}
c86cf029 1270
d6f9b0fb
PA
1271ui_out *
1272mi_interp::interp_ui_out ()
4801a9a3 1273{
d6f9b0fb 1274 return this->mi_uiout;
4801a9a3
PA
1275}
1276
37ce89eb
SS
1277/* Do MI-specific logging actions; save raw_stdout, and change all
1278 the consoles to use the supplied ui-file(s). */
1279
d6f9b0fb
PA
1280void
1281mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
37ce89eb 1282{
d6f9b0fb 1283 struct mi_interp *mi = this;
37ce89eb 1284
616268b6 1285 if (logfile != NULL)
37ce89eb 1286 {
9204d692 1287 mi->saved_raw_stdout = mi->raw_stdout;
616268b6
PA
1288 mi->raw_stdout = make_logging_output (mi->raw_stdout,
1289 std::move (logfile),
1290 logging_redirect);
1291
37ce89eb
SS
1292 }
1293 else
1294 {
616268b6 1295 delete mi->raw_stdout;
9204d692
PA
1296 mi->raw_stdout = mi->saved_raw_stdout;
1297 mi->saved_raw_stdout = NULL;
37ce89eb
SS
1298 }
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
4a8f6654
AC
1315void
1316_initialize_mi_interp (void)
1317{
2fcf52f0 1318 /* The various interpreter levels. */
8322445e
PA
1319 interp_factory_register (INTERP_MI1, mi_interp_factory);
1320 interp_factory_register (INTERP_MI2, mi_interp_factory);
1321 interp_factory_register (INTERP_MI3, mi_interp_factory);
1322 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1323
76727919
TT
1324 gdb::observers::signal_received.attach (mi_on_signal_received);
1325 gdb::observers::end_stepping_range.attach (mi_on_end_stepping_range);
1326 gdb::observers::signal_exited.attach (mi_on_signal_exited);
1327 gdb::observers::exited.attach (mi_on_exited);
1328 gdb::observers::no_history.attach (mi_on_no_history);
1329 gdb::observers::new_thread.attach (mi_new_thread);
1330 gdb::observers::thread_exit.attach (mi_thread_exit);
1331 gdb::observers::inferior_added.attach (mi_inferior_added);
1332 gdb::observers::inferior_appeared.attach (mi_inferior_appeared);
1333 gdb::observers::inferior_exit.attach (mi_inferior_exit);
1334 gdb::observers::inferior_removed.attach (mi_inferior_removed);
1335 gdb::observers::record_changed.attach (mi_record_changed);
1336 gdb::observers::normal_stop.attach (mi_on_normal_stop);
1337 gdb::observers::target_resumed.attach (mi_on_resume);
1338 gdb::observers::solib_loaded.attach (mi_solib_loaded);
1339 gdb::observers::solib_unloaded.attach (mi_solib_unloaded);
1340 gdb::observers::about_to_proceed.attach (mi_about_to_proceed);
1341 gdb::observers::traceframe_changed.attach (mi_traceframe_changed);
1342 gdb::observers::tsv_created.attach (mi_tsv_created);
1343 gdb::observers::tsv_deleted.attach (mi_tsv_deleted);
1344 gdb::observers::tsv_modified.attach (mi_tsv_modified);
1345 gdb::observers::breakpoint_created.attach (mi_breakpoint_created);
1346 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted);
1347 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified);
1348 gdb::observers::command_param_changed.attach (mi_command_param_changed);
1349 gdb::observers::memory_changed.attach (mi_memory_changed);
1350 gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done);
1351 gdb::observers::user_selected_context_changed.attach
4034d0ff 1352 (mi_user_selected_context_changed);
4a8f6654 1353}
This page took 1.492571 seconds and 4 git commands to generate.