Simplify exception handling
[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 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
112e8700 639 mi_uiout->field_int ("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
112e8700 644 mi_uiout->field_int (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)
112e8700 651 mi_uiout->field_int ("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
829 TRY
830 {
831 scoped_restore restore_uiout
832 = make_scoped_restore (&current_uiout, mi_uiout);
833
834 print_breakpoint (bp);
835 }
836 CATCH (ex, RETURN_MASK_ALL)
837 {
838 exception_print (gdb_stderr, ex);
839 }
840 END_CATCH
841
842 mi_uiout->redirect (NULL);
843}
844
8d3788bd 845/* Emit notification about a created breakpoint. */
2b03b41d 846
8d3788bd
VP
847static void
848mi_breakpoint_created (struct breakpoint *b)
849{
5b9afe8a 850 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
851 return;
852
853 if (b->number <= 0)
854 return;
855
0e454242 856 SWITCH_THRU_ALL_UIS ()
492d29ea 857 {
73ab01a0 858 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 859
73ab01a0
PA
860 if (mi == NULL)
861 continue;
8d3788bd 862
223ffa71
TT
863 target_terminal::scoped_restore_terminal_state term_state;
864 target_terminal::ours_for_output ();
73ab01a0
PA
865
866 fprintf_unfiltered (mi->event_channel,
867 "breakpoint-created");
65630365 868 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
869
870 gdb_flush (mi->event_channel);
73ab01a0 871 }
8d3788bd
VP
872}
873
874/* Emit notification about deleted breakpoint. */
2b03b41d 875
8d3788bd
VP
876static void
877mi_breakpoint_deleted (struct breakpoint *b)
878{
5b9afe8a 879 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
880 return;
881
882 if (b->number <= 0)
883 return;
884
0e454242 885 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
886 {
887 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
8d3788bd 888
73ab01a0
PA
889 if (mi == NULL)
890 continue;
8d3788bd 891
223ffa71
TT
892 target_terminal::scoped_restore_terminal_state term_state;
893 target_terminal::ours_for_output ();
5fe96654 894
73ab01a0
PA
895 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
896 b->number);
897
898 gdb_flush (mi->event_channel);
73ab01a0 899 }
8d3788bd
VP
900}
901
902/* Emit notification about modified breakpoint. */
2b03b41d 903
8d3788bd
VP
904static void
905mi_breakpoint_modified (struct breakpoint *b)
906{
5b9afe8a 907 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
908 return;
909
910 if (b->number <= 0)
911 return;
912
0e454242 913 SWITCH_THRU_ALL_UIS ()
492d29ea 914 {
73ab01a0 915 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 916
73ab01a0
PA
917 if (mi == NULL)
918 continue;
8d3788bd 919
223ffa71
TT
920 target_terminal::scoped_restore_terminal_state term_state;
921 target_terminal::ours_for_output ();
73ab01a0
PA
922 fprintf_unfiltered (mi->event_channel,
923 "breakpoint-modified");
65630365 924 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
925
926 gdb_flush (mi->event_channel);
73ab01a0 927 }
8d3788bd
VP
928}
929
00431a78
PA
930static void
931mi_output_running (struct thread_info *thread)
d90e17a7 932{
0e454242 933 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
934 {
935 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
936
937 if (mi == NULL)
938 continue;
939
00431a78
PA
940 fprintf_unfiltered (mi->raw_stdout,
941 "*running,thread-id=\"%d\"\n",
942 thread->global_num);
73ab01a0 943 }
d90e17a7
PA
944}
945
08036331
PA
946/* Return true if there are multiple inferiors loaded. This is used
947 for backwards compatibility -- if there's only one inferior, output
948 "all", otherwise, output each resumed thread individually. */
949
950static bool
951multiple_inferiors_p ()
952{
953 int count = 0;
954 for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
955 {
956 count++;
957 if (count > 1)
958 return true;
959 }
960
961 return false;
962}
963
e1ac3328 964static void
9204d692 965mi_on_resume_1 (struct mi_interp *mi, 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
08036331
PA
988 for (thread_info *tp : all_non_exited_threads (ptid))
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
d7e15655 1008 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
1009 tp = inferior_thread ();
1010 else
1011 tp = find_thread_ptid (ptid);
6ef284bd 1012
73ab01a0
PA
1013 /* Suppress output while calling an inferior function. */
1014 if (tp->control.in_infcall)
1015 return;
6ef284bd 1016
0e454242 1017 SWITCH_THRU_ALL_UIS ()
6ef284bd 1018 {
73ab01a0 1019 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
1020
1021 if (mi == NULL)
1022 continue;
1023
223ffa71
TT
1024 target_terminal::scoped_restore_terminal_state term_state;
1025 target_terminal::ours_for_output ();
73ab01a0 1026
9204d692 1027 mi_on_resume_1 (mi, ptid);
6ef284bd 1028 }
73ab01a0 1029}
6ef284bd 1030
51457a05
MAL
1031/* See mi-interp.h. */
1032
1033void
1034mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
1035{
1036 struct gdbarch *gdbarch = target_gdbarch ();
1037
1038 uiout->field_string ("id", solib->so_original_name);
1039 uiout->field_string ("target-name", solib->so_original_name);
1040 uiout->field_string ("host-name", solib->so_name);
1041 uiout->field_int ("symbols-loaded", solib->symbols_loaded);
1042 if (!gdbarch_has_global_solist (target_gdbarch ()))
1043 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
1044
10f489e5
TT
1045 ui_out_emit_list list_emitter (uiout, "ranges");
1046 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
1047 if (solib->addr_high != 0)
1048 {
1049 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
1050 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
1051 }
51457a05
MAL
1052}
1053
73ab01a0
PA
1054static void
1055mi_solib_loaded (struct so_list *solib)
1056{
0e454242 1057 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1058 {
1059 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1060 struct ui_out *uiout;
5fe96654 1061
73ab01a0
PA
1062 if (mi == NULL)
1063 continue;
1064
29f94340 1065 uiout = top_level_interpreter ()->interp_ui_out ();
73ab01a0 1066
223ffa71
TT
1067 target_terminal::scoped_restore_terminal_state term_state;
1068 target_terminal::ours_for_output ();
73ab01a0
PA
1069
1070 fprintf_unfiltered (mi->event_channel, "library-loaded");
1071
112e8700 1072 uiout->redirect (mi->event_channel);
73ab01a0 1073
51457a05 1074 mi_output_solib_attribs (uiout, solib);
73ab01a0 1075
112e8700 1076 uiout->redirect (NULL);
73ab01a0
PA
1077
1078 gdb_flush (mi->event_channel);
73ab01a0 1079 }
c86cf029
VP
1080}
1081
1082static void
1083mi_solib_unloaded (struct so_list *solib)
1084{
0e454242 1085 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1086 {
1087 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1088 struct ui_out *uiout;
6ef284bd 1089
73ab01a0
PA
1090 if (mi == NULL)
1091 continue;
6ef284bd 1092
29f94340 1093 uiout = top_level_interpreter ()->interp_ui_out ();
6ef284bd 1094
223ffa71
TT
1095 target_terminal::scoped_restore_terminal_state term_state;
1096 target_terminal::ours_for_output ();
6ef284bd 1097
73ab01a0 1098 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1099
112e8700 1100 uiout->redirect (mi->event_channel);
5fe96654 1101
112e8700
SM
1102 uiout->field_string ("id", solib->so_original_name);
1103 uiout->field_string ("target-name", solib->so_original_name);
1104 uiout->field_string ("host-name", solib->so_name);
73ab01a0
PA
1105 if (!gdbarch_has_global_solist (target_gdbarch ()))
1106 {
112e8700 1107 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0
PA
1108 }
1109
112e8700 1110 uiout->redirect (NULL);
73ab01a0
PA
1111
1112 gdb_flush (mi->event_channel);
73ab01a0 1113 }
c86cf029
VP
1114}
1115
5b9afe8a
YQ
1116/* Emit notification about the command parameter change. */
1117
1118static void
1119mi_command_param_changed (const char *param, const char *value)
1120{
5b9afe8a
YQ
1121 if (mi_suppress_notification.cmd_param_changed)
1122 return;
1123
0e454242 1124 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1125 {
1126 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1127 struct ui_out *mi_uiout;
5b9afe8a 1128
73ab01a0
PA
1129 if (mi == NULL)
1130 continue;
5b9afe8a 1131
29f94340 1132 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 1133
223ffa71
TT
1134 target_terminal::scoped_restore_terminal_state term_state;
1135 target_terminal::ours_for_output ();
5b9afe8a 1136
73ab01a0 1137 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1138
112e8700 1139 mi_uiout->redirect (mi->event_channel);
5fe96654 1140
112e8700
SM
1141 mi_uiout->field_string ("param", param);
1142 mi_uiout->field_string ("value", value);
73ab01a0 1143
112e8700 1144 mi_uiout->redirect (NULL);
73ab01a0
PA
1145
1146 gdb_flush (mi->event_channel);
73ab01a0 1147 }
5b9afe8a
YQ
1148}
1149
8de0566d
YQ
1150/* Emit notification about the target memory change. */
1151
1152static void
1153mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1154 ssize_t len, const bfd_byte *myaddr)
1155{
8de0566d
YQ
1156 if (mi_suppress_notification.memory)
1157 return;
1158
0e454242 1159 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1160 {
1161 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1162 struct ui_out *mi_uiout;
1163 struct obj_section *sec;
8de0566d 1164
73ab01a0
PA
1165 if (mi == NULL)
1166 continue;
8de0566d 1167
29f94340 1168 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 1169
223ffa71
TT
1170 target_terminal::scoped_restore_terminal_state term_state;
1171 target_terminal::ours_for_output ();
8de0566d 1172
73ab01a0 1173 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1174
112e8700 1175 mi_uiout->redirect (mi->event_channel);
8de0566d 1176
112e8700
SM
1177 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
1178 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
1179 mi_uiout->field_fmt ("len", "%s", hex_string (len));
8de0566d 1180
73ab01a0
PA
1181 /* Append 'type=code' into notification if MEMADDR falls in the range of
1182 sections contain code. */
1183 sec = find_pc_section (memaddr);
1184 if (sec != NULL && sec->objfile != NULL)
1185 {
1186 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1187 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
PA
1285void
1286mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
37ce89eb 1287{
d6f9b0fb 1288 struct mi_interp *mi = this;
37ce89eb 1289
616268b6 1290 if (logfile != NULL)
37ce89eb 1291 {
9204d692 1292 mi->saved_raw_stdout = mi->raw_stdout;
616268b6
PA
1293 mi->raw_stdout = make_logging_output (mi->raw_stdout,
1294 std::move (logfile),
1295 logging_redirect);
1296
37ce89eb
SS
1297 }
1298 else
1299 {
616268b6 1300 delete mi->raw_stdout;
9204d692
PA
1301 mi->raw_stdout = mi->saved_raw_stdout;
1302 mi->saved_raw_stdout = NULL;
37ce89eb
SS
1303 }
1304
d7e74731
PA
1305 mi->out->set_raw (mi->raw_stdout);
1306 mi->err->set_raw (mi->raw_stdout);
1307 mi->log->set_raw (mi->raw_stdout);
1308 mi->targ->set_raw (mi->raw_stdout);
1309 mi->event_channel->set_raw (mi->raw_stdout);
37ce89eb
SS
1310}
1311
8322445e
PA
1312/* Factory for MI interpreters. */
1313
1314static struct interp *
1315mi_interp_factory (const char *name)
1316{
d6f9b0fb 1317 return new mi_interp (name);
8322445e
PA
1318}
1319
4a8f6654
AC
1320void
1321_initialize_mi_interp (void)
1322{
2fcf52f0 1323 /* The various interpreter levels. */
8322445e
PA
1324 interp_factory_register (INTERP_MI1, mi_interp_factory);
1325 interp_factory_register (INTERP_MI2, mi_interp_factory);
1326 interp_factory_register (INTERP_MI3, mi_interp_factory);
1327 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1328
76727919
TT
1329 gdb::observers::signal_received.attach (mi_on_signal_received);
1330 gdb::observers::end_stepping_range.attach (mi_on_end_stepping_range);
1331 gdb::observers::signal_exited.attach (mi_on_signal_exited);
1332 gdb::observers::exited.attach (mi_on_exited);
1333 gdb::observers::no_history.attach (mi_on_no_history);
1334 gdb::observers::new_thread.attach (mi_new_thread);
1335 gdb::observers::thread_exit.attach (mi_thread_exit);
1336 gdb::observers::inferior_added.attach (mi_inferior_added);
1337 gdb::observers::inferior_appeared.attach (mi_inferior_appeared);
1338 gdb::observers::inferior_exit.attach (mi_inferior_exit);
1339 gdb::observers::inferior_removed.attach (mi_inferior_removed);
1340 gdb::observers::record_changed.attach (mi_record_changed);
1341 gdb::observers::normal_stop.attach (mi_on_normal_stop);
1342 gdb::observers::target_resumed.attach (mi_on_resume);
1343 gdb::observers::solib_loaded.attach (mi_solib_loaded);
1344 gdb::observers::solib_unloaded.attach (mi_solib_unloaded);
1345 gdb::observers::about_to_proceed.attach (mi_about_to_proceed);
1346 gdb::observers::traceframe_changed.attach (mi_traceframe_changed);
1347 gdb::observers::tsv_created.attach (mi_tsv_created);
1348 gdb::observers::tsv_deleted.attach (mi_tsv_deleted);
1349 gdb::observers::tsv_modified.attach (mi_tsv_modified);
1350 gdb::observers::breakpoint_created.attach (mi_breakpoint_created);
1351 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted);
1352 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified);
1353 gdb::observers::command_param_changed.attach (mi_command_param_changed);
1354 gdb::observers::memory_changed.attach (mi_memory_changed);
1355 gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done);
1356 gdb::observers::user_selected_context_changed.attach
4034d0ff 1357 (mi_user_selected_context_changed);
4a8f6654 1358}
This page took 1.549166 seconds and 4 git commands to generate.