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