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