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