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