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