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