Make exceptions use std::string and be self-managing
[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);
c1043fc2 184 return exception_none;
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
826 TRY
827 {
828 scoped_restore restore_uiout
829 = make_scoped_restore (&current_uiout, mi_uiout);
830
831 print_breakpoint (bp);
832 }
833 CATCH (ex, RETURN_MASK_ALL)
834 {
835 exception_print (gdb_stderr, ex);
836 }
837 END_CATCH
838
839 mi_uiout->redirect (NULL);
840}
841
8d3788bd 842/* Emit notification about a created breakpoint. */
2b03b41d 843
8d3788bd
VP
844static void
845mi_breakpoint_created (struct breakpoint *b)
846{
5b9afe8a 847 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
848 return;
849
850 if (b->number <= 0)
851 return;
852
0e454242 853 SWITCH_THRU_ALL_UIS ()
492d29ea 854 {
73ab01a0 855 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 856
73ab01a0
PA
857 if (mi == NULL)
858 continue;
8d3788bd 859
223ffa71
TT
860 target_terminal::scoped_restore_terminal_state term_state;
861 target_terminal::ours_for_output ();
73ab01a0
PA
862
863 fprintf_unfiltered (mi->event_channel,
864 "breakpoint-created");
65630365 865 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
866
867 gdb_flush (mi->event_channel);
73ab01a0 868 }
8d3788bd
VP
869}
870
871/* Emit notification about deleted breakpoint. */
2b03b41d 872
8d3788bd
VP
873static void
874mi_breakpoint_deleted (struct breakpoint *b)
875{
5b9afe8a 876 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
877 return;
878
879 if (b->number <= 0)
880 return;
881
0e454242 882 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
883 {
884 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
8d3788bd 885
73ab01a0
PA
886 if (mi == NULL)
887 continue;
8d3788bd 888
223ffa71
TT
889 target_terminal::scoped_restore_terminal_state term_state;
890 target_terminal::ours_for_output ();
5fe96654 891
73ab01a0
PA
892 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
893 b->number);
894
895 gdb_flush (mi->event_channel);
73ab01a0 896 }
8d3788bd
VP
897}
898
899/* Emit notification about modified breakpoint. */
2b03b41d 900
8d3788bd
VP
901static void
902mi_breakpoint_modified (struct breakpoint *b)
903{
5b9afe8a 904 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
905 return;
906
907 if (b->number <= 0)
908 return;
909
0e454242 910 SWITCH_THRU_ALL_UIS ()
492d29ea 911 {
73ab01a0 912 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 913
73ab01a0
PA
914 if (mi == NULL)
915 continue;
8d3788bd 916
223ffa71
TT
917 target_terminal::scoped_restore_terminal_state term_state;
918 target_terminal::ours_for_output ();
73ab01a0
PA
919 fprintf_unfiltered (mi->event_channel,
920 "breakpoint-modified");
65630365 921 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
922
923 gdb_flush (mi->event_channel);
73ab01a0 924 }
8d3788bd
VP
925}
926
00431a78
PA
927static void
928mi_output_running (struct thread_info *thread)
d90e17a7 929{
0e454242 930 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
931 {
932 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
933
934 if (mi == NULL)
935 continue;
936
00431a78
PA
937 fprintf_unfiltered (mi->raw_stdout,
938 "*running,thread-id=\"%d\"\n",
939 thread->global_num);
73ab01a0 940 }
d90e17a7
PA
941}
942
08036331
PA
943/* Return true if there are multiple inferiors loaded. This is used
944 for backwards compatibility -- if there's only one inferior, output
945 "all", otherwise, output each resumed thread individually. */
946
947static bool
948multiple_inferiors_p ()
949{
950 int count = 0;
951 for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
952 {
953 count++;
954 if (count > 1)
955 return true;
956 }
957
958 return false;
959}
960
e1ac3328 961static void
9204d692 962mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
e1ac3328 963{
a2840c35
VP
964 /* To cater for older frontends, emit ^running, but do it only once
965 per each command. We do it here, since at this point we know
966 that the target was successfully resumed, and in non-async mode,
967 we won't return back to MI interpreter code until the target
968 is done running, so delaying the output of "^running" until then
969 will make it impossible for frontend to know what's going on.
970
971 In future (MI3), we'll be outputting "^done" here. */
f3b1572e 972 if (!running_result_record_printed && mi_proceeded)
a2840c35 973 {
9204d692 974 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
c271b6e2 975 current_token ? current_token : "");
a2840c35
VP
976 }
977
08036331
PA
978 /* Backwards compatibility. If doing a wildcard resume and there's
979 only one inferior, output "all", otherwise, output each resumed
980 thread individually. */
981 if ((ptid == minus_one_ptid || ptid.is_pid ())
982 && !multiple_inferiors_p ())
9204d692 983 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
e1ac3328 984 else
08036331
PA
985 for (thread_info *tp : all_non_exited_threads (ptid))
986 mi_output_running (tp);
a2840c35 987
f3b1572e 988 if (!running_result_record_printed && mi_proceeded)
a2840c35
VP
989 {
990 running_result_record_printed = 1;
3b12939d
PA
991 /* This is what gdb used to do historically -- printing prompt
992 even if it cannot actually accept any input. This will be
993 surely removed for MI3, and may be removed even earlier. */
994 if (current_ui->prompt_state == PROMPT_BLOCKED)
9204d692 995 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
a2840c35 996 }
9204d692 997 gdb_flush (mi->raw_stdout);
e1ac3328
VP
998}
999
c86cf029 1000static void
73ab01a0 1001mi_on_resume (ptid_t ptid)
c86cf029 1002{
73ab01a0 1003 struct thread_info *tp = NULL;
6ef284bd 1004
d7e15655 1005 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
1006 tp = inferior_thread ();
1007 else
1008 tp = find_thread_ptid (ptid);
6ef284bd 1009
73ab01a0
PA
1010 /* Suppress output while calling an inferior function. */
1011 if (tp->control.in_infcall)
1012 return;
6ef284bd 1013
0e454242 1014 SWITCH_THRU_ALL_UIS ()
6ef284bd 1015 {
73ab01a0 1016 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
73ab01a0
PA
1017
1018 if (mi == NULL)
1019 continue;
1020
223ffa71
TT
1021 target_terminal::scoped_restore_terminal_state term_state;
1022 target_terminal::ours_for_output ();
73ab01a0 1023
9204d692 1024 mi_on_resume_1 (mi, ptid);
6ef284bd 1025 }
73ab01a0 1026}
6ef284bd 1027
51457a05
MAL
1028/* See mi-interp.h. */
1029
1030void
1031mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
1032{
1033 struct gdbarch *gdbarch = target_gdbarch ();
1034
1035 uiout->field_string ("id", solib->so_original_name);
1036 uiout->field_string ("target-name", solib->so_original_name);
1037 uiout->field_string ("host-name", solib->so_name);
1038 uiout->field_int ("symbols-loaded", solib->symbols_loaded);
1039 if (!gdbarch_has_global_solist (target_gdbarch ()))
1040 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
1041
10f489e5
TT
1042 ui_out_emit_list list_emitter (uiout, "ranges");
1043 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
1044 if (solib->addr_high != 0)
1045 {
1046 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
1047 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
1048 }
51457a05
MAL
1049}
1050
73ab01a0
PA
1051static void
1052mi_solib_loaded (struct so_list *solib)
1053{
0e454242 1054 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1055 {
1056 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1057 struct ui_out *uiout;
5fe96654 1058
73ab01a0
PA
1059 if (mi == NULL)
1060 continue;
1061
29f94340 1062 uiout = top_level_interpreter ()->interp_ui_out ();
73ab01a0 1063
223ffa71
TT
1064 target_terminal::scoped_restore_terminal_state term_state;
1065 target_terminal::ours_for_output ();
73ab01a0
PA
1066
1067 fprintf_unfiltered (mi->event_channel, "library-loaded");
1068
112e8700 1069 uiout->redirect (mi->event_channel);
73ab01a0 1070
51457a05 1071 mi_output_solib_attribs (uiout, solib);
73ab01a0 1072
112e8700 1073 uiout->redirect (NULL);
73ab01a0
PA
1074
1075 gdb_flush (mi->event_channel);
73ab01a0 1076 }
c86cf029
VP
1077}
1078
1079static void
1080mi_solib_unloaded (struct so_list *solib)
1081{
0e454242 1082 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1083 {
1084 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1085 struct ui_out *uiout;
6ef284bd 1086
73ab01a0
PA
1087 if (mi == NULL)
1088 continue;
6ef284bd 1089
29f94340 1090 uiout = top_level_interpreter ()->interp_ui_out ();
6ef284bd 1091
223ffa71
TT
1092 target_terminal::scoped_restore_terminal_state term_state;
1093 target_terminal::ours_for_output ();
6ef284bd 1094
73ab01a0 1095 fprintf_unfiltered (mi->event_channel, "library-unloaded");
a79b8f6e 1096
112e8700 1097 uiout->redirect (mi->event_channel);
5fe96654 1098
112e8700
SM
1099 uiout->field_string ("id", solib->so_original_name);
1100 uiout->field_string ("target-name", solib->so_original_name);
1101 uiout->field_string ("host-name", solib->so_name);
73ab01a0
PA
1102 if (!gdbarch_has_global_solist (target_gdbarch ()))
1103 {
112e8700 1104 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0
PA
1105 }
1106
112e8700 1107 uiout->redirect (NULL);
73ab01a0
PA
1108
1109 gdb_flush (mi->event_channel);
73ab01a0 1110 }
c86cf029
VP
1111}
1112
5b9afe8a
YQ
1113/* Emit notification about the command parameter change. */
1114
1115static void
1116mi_command_param_changed (const char *param, const char *value)
1117{
5b9afe8a
YQ
1118 if (mi_suppress_notification.cmd_param_changed)
1119 return;
1120
0e454242 1121 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1122 {
1123 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1124 struct ui_out *mi_uiout;
5b9afe8a 1125
73ab01a0
PA
1126 if (mi == NULL)
1127 continue;
5b9afe8a 1128
29f94340 1129 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 1130
223ffa71
TT
1131 target_terminal::scoped_restore_terminal_state term_state;
1132 target_terminal::ours_for_output ();
5b9afe8a 1133
73ab01a0 1134 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
5b9afe8a 1135
112e8700 1136 mi_uiout->redirect (mi->event_channel);
5fe96654 1137
112e8700
SM
1138 mi_uiout->field_string ("param", param);
1139 mi_uiout->field_string ("value", value);
73ab01a0 1140
112e8700 1141 mi_uiout->redirect (NULL);
73ab01a0
PA
1142
1143 gdb_flush (mi->event_channel);
73ab01a0 1144 }
5b9afe8a
YQ
1145}
1146
8de0566d
YQ
1147/* Emit notification about the target memory change. */
1148
1149static void
1150mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1151 ssize_t len, const bfd_byte *myaddr)
1152{
8de0566d
YQ
1153 if (mi_suppress_notification.memory)
1154 return;
1155
0e454242 1156 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
1157 {
1158 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1159 struct ui_out *mi_uiout;
1160 struct obj_section *sec;
8de0566d 1161
73ab01a0
PA
1162 if (mi == NULL)
1163 continue;
8de0566d 1164
29f94340 1165 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 1166
223ffa71
TT
1167 target_terminal::scoped_restore_terminal_state term_state;
1168 target_terminal::ours_for_output ();
8de0566d 1169
73ab01a0 1170 fprintf_unfiltered (mi->event_channel, "memory-changed");
8de0566d 1171
112e8700 1172 mi_uiout->redirect (mi->event_channel);
8de0566d 1173
112e8700
SM
1174 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
1175 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
1176 mi_uiout->field_fmt ("len", "%s", hex_string (len));
8de0566d 1177
73ab01a0
PA
1178 /* Append 'type=code' into notification if MEMADDR falls in the range of
1179 sections contain code. */
1180 sec = find_pc_section (memaddr);
1181 if (sec != NULL && sec->objfile != NULL)
1182 {
1183 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1184 sec->the_bfd_section);
5fe96654 1185
73ab01a0 1186 if (flags & SEC_CODE)
112e8700 1187 mi_uiout->field_string ("type", "code");
73ab01a0
PA
1188 }
1189
112e8700 1190 mi_uiout->redirect (NULL);
73ab01a0
PA
1191
1192 gdb_flush (mi->event_channel);
73ab01a0 1193 }
8de0566d
YQ
1194}
1195
4034d0ff
AT
1196/* Emit an event when the selection context (inferior, thread, frame)
1197 changed. */
1198
1199static void
1200mi_user_selected_context_changed (user_selected_what selection)
1201{
4034d0ff
AT
1202 struct thread_info *tp;
1203
1204 /* Don't send an event if we're responding to an MI command. */
1205 if (mi_suppress_notification.user_selected_context)
1206 return;
1207
00431a78
PA
1208 if (inferior_ptid != null_ptid)
1209 tp = inferior_thread ();
1210 else
1211 tp = NULL;
4034d0ff 1212
0e454242 1213 SWITCH_THRU_ALL_UIS ()
4034d0ff
AT
1214 {
1215 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1216 struct ui_out *mi_uiout;
4034d0ff
AT
1217
1218 if (mi == NULL)
1219 continue;
1220
29f94340 1221 mi_uiout = top_level_interpreter ()->interp_ui_out ();
4034d0ff 1222
112e8700 1223 mi_uiout->redirect (mi->event_channel);
ca5909c7 1224 ui_out_redirect_pop redirect_popper (mi_uiout);
4034d0ff 1225
223ffa71
TT
1226 target_terminal::scoped_restore_terminal_state term_state;
1227 target_terminal::ours_for_output ();
4034d0ff
AT
1228
1229 if (selection & USER_SELECTED_INFERIOR)
1230 print_selected_inferior (mi->cli_uiout);
1231
1232 if (tp != NULL
1233 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1234 {
1235 print_selected_thread_frame (mi->cli_uiout, selection);
1236
1237 fprintf_unfiltered (mi->event_channel,
1238 "thread-selected,id=\"%d\"",
1239 tp->global_num);
1240
1241 if (tp->state != THREAD_RUNNING)
1242 {
1243 if (has_stack_frames ())
1244 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1245 1, SRC_AND_LOC, 1);
1246 }
1247 }
1248
1249 gdb_flush (mi->event_channel);
4034d0ff
AT
1250 }
1251}
1252
a79b8f6e
VP
1253static int
1254report_initial_inferior (struct inferior *inf, void *closure)
1255{
73ab01a0 1256 /* This function is called from mi_interpreter_init, and since
a79b8f6e
VP
1257 mi_inferior_added assumes that inferior is fully initialized
1258 and top_level_interpreter_data is set, we cannot call
1259 it here. */
19ba03f4 1260 struct mi_interp *mi = (struct mi_interp *) closure;
5fe96654 1261
223ffa71
TT
1262 target_terminal::scoped_restore_terminal_state term_state;
1263 target_terminal::ours_for_output ();
102040f0 1264
a79b8f6e
VP
1265 fprintf_unfiltered (mi->event_channel,
1266 "thread-group-added,id=\"i%d\"",
1267 inf->num);
1268 gdb_flush (mi->event_channel);
5fe96654 1269
a79b8f6e
VP
1270 return 0;
1271}
c86cf029 1272
d6f9b0fb
PA
1273ui_out *
1274mi_interp::interp_ui_out ()
4801a9a3 1275{
d6f9b0fb 1276 return this->mi_uiout;
4801a9a3
PA
1277}
1278
37ce89eb
SS
1279/* Do MI-specific logging actions; save raw_stdout, and change all
1280 the consoles to use the supplied ui-file(s). */
1281
d6f9b0fb
PA
1282void
1283mi_interp::set_logging (ui_file_up logfile, bool logging_redirect)
37ce89eb 1284{
d6f9b0fb 1285 struct mi_interp *mi = this;
37ce89eb 1286
616268b6 1287 if (logfile != NULL)
37ce89eb 1288 {
9204d692 1289 mi->saved_raw_stdout = mi->raw_stdout;
616268b6
PA
1290 mi->raw_stdout = make_logging_output (mi->raw_stdout,
1291 std::move (logfile),
1292 logging_redirect);
1293
37ce89eb
SS
1294 }
1295 else
1296 {
616268b6 1297 delete mi->raw_stdout;
9204d692
PA
1298 mi->raw_stdout = mi->saved_raw_stdout;
1299 mi->saved_raw_stdout = NULL;
37ce89eb
SS
1300 }
1301
d7e74731
PA
1302 mi->out->set_raw (mi->raw_stdout);
1303 mi->err->set_raw (mi->raw_stdout);
1304 mi->log->set_raw (mi->raw_stdout);
1305 mi->targ->set_raw (mi->raw_stdout);
1306 mi->event_channel->set_raw (mi->raw_stdout);
37ce89eb
SS
1307}
1308
8322445e
PA
1309/* Factory for MI interpreters. */
1310
1311static struct interp *
1312mi_interp_factory (const char *name)
1313{
d6f9b0fb 1314 return new mi_interp (name);
8322445e
PA
1315}
1316
4a8f6654
AC
1317void
1318_initialize_mi_interp (void)
1319{
2fcf52f0 1320 /* The various interpreter levels. */
8322445e
PA
1321 interp_factory_register (INTERP_MI1, mi_interp_factory);
1322 interp_factory_register (INTERP_MI2, mi_interp_factory);
1323 interp_factory_register (INTERP_MI3, mi_interp_factory);
1324 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1325
76727919
TT
1326 gdb::observers::signal_received.attach (mi_on_signal_received);
1327 gdb::observers::end_stepping_range.attach (mi_on_end_stepping_range);
1328 gdb::observers::signal_exited.attach (mi_on_signal_exited);
1329 gdb::observers::exited.attach (mi_on_exited);
1330 gdb::observers::no_history.attach (mi_on_no_history);
1331 gdb::observers::new_thread.attach (mi_new_thread);
1332 gdb::observers::thread_exit.attach (mi_thread_exit);
1333 gdb::observers::inferior_added.attach (mi_inferior_added);
1334 gdb::observers::inferior_appeared.attach (mi_inferior_appeared);
1335 gdb::observers::inferior_exit.attach (mi_inferior_exit);
1336 gdb::observers::inferior_removed.attach (mi_inferior_removed);
1337 gdb::observers::record_changed.attach (mi_record_changed);
1338 gdb::observers::normal_stop.attach (mi_on_normal_stop);
1339 gdb::observers::target_resumed.attach (mi_on_resume);
1340 gdb::observers::solib_loaded.attach (mi_solib_loaded);
1341 gdb::observers::solib_unloaded.attach (mi_solib_unloaded);
1342 gdb::observers::about_to_proceed.attach (mi_about_to_proceed);
1343 gdb::observers::traceframe_changed.attach (mi_traceframe_changed);
1344 gdb::observers::tsv_created.attach (mi_tsv_created);
1345 gdb::observers::tsv_deleted.attach (mi_tsv_deleted);
1346 gdb::observers::tsv_modified.attach (mi_tsv_modified);
1347 gdb::observers::breakpoint_created.attach (mi_breakpoint_created);
1348 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted);
1349 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified);
1350 gdb::observers::command_param_changed.attach (mi_command_param_changed);
1351 gdb::observers::memory_changed.attach (mi_memory_changed);
1352 gdb::observers::sync_execution_done.attach (mi_on_sync_execution_done);
1353 gdb::observers::user_selected_context_changed.attach
4034d0ff 1354 (mi_user_selected_context_changed);
4a8f6654 1355}
This page took 1.493578 seconds and 4 git commands to generate.