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