]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/mi/mi-interp.c
gdb: add interp::on_tsv_deleted method
[thirdparty/binutils-gdb.git] / gdb / mi / mi-interp.c
CommitLineData
4a8f6654
AC
1/* MI Interpreter Definitions and Commands for GDB, the GNU debugger.
2
213516ef 3 Copyright (C) 2002-2023 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"
23baa4cc
SM
21
22#include "mi-interp.h"
23
4a8f6654
AC
24#include "interps.h"
25#include "event-top.h"
400b5eca 26#include "gdbsupport/event-loop.h"
4a8f6654 27#include "inferior.h"
45741a9c 28#include "infrun.h"
4a8f6654 29#include "ui-out.h"
13d03262 30#include "ui.h"
4a8f6654
AC
31#include "mi-main.h"
32#include "mi-cmds.h"
33#include "mi-out.h"
34#include "mi-console.h"
66bb093b 35#include "mi-common.h"
76727919 36#include "observable.h"
683f2885 37#include "gdbthread.h"
c86cf029 38#include "solist.h"
8de0566d 39#include "objfiles.h"
134a2066 40#include "tracepoint.h"
17b2616c 41#include "cli-out.h"
243a9253 42#include "thread-fsm.h"
26cde2cc 43#include "cli/cli-interp.h"
268a13a5 44#include "gdbsupport/scope-exit.h"
4a8f6654 45
2b03b41d
SS
46/* These are the interpreter setup, etc. functions for the MI
47 interpreter. */
48
ee047554 49static void mi_execute_command_wrapper (const char *cmd);
95bc9f0b
TT
50static void mi_execute_command_input_handler
51 (gdb::unique_xmalloc_ptr<char> &&cmd);
4a8f6654
AC
52
53/* These are hooks that we put in place while doing interpreter_exec
2b03b41d
SS
54 so we can report interesting things that happened "behind the MI's
55 back" in this command. */
56
bee0189a 57static int mi_interp_query_hook (const char *ctlstr, va_list ap)
2b03b41d 58 ATTRIBUTE_PRINTF (1, 0);
4a8f6654 59
4a8f6654
AC
60static void mi_insert_notify_hooks (void);
61static void mi_remove_notify_hooks (void);
fd664c91 62
134a2066 63static void mi_tsv_modified (const struct trace_state_variable *tsv);
8d3788bd
VP
64static void mi_breakpoint_created (struct breakpoint *b);
65static void mi_breakpoint_deleted (struct breakpoint *b);
66static void mi_breakpoint_modified (struct breakpoint *b);
5b9afe8a 67static void mi_command_param_changed (const char *param, const char *value);
8de0566d
YQ
68static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
69 ssize_t len, const bfd_byte *myaddr);
683f2885 70
05beb275
PA
71/* Display the MI prompt. */
72
73static void
9204d692 74display_mi_prompt (struct mi_interp *mi)
05beb275 75{
3b12939d
PA
76 struct ui *ui = current_ui;
77
0426ad51 78 gdb_puts ("(gdb) \n", mi->raw_stdout);
9204d692 79 gdb_flush (mi->raw_stdout);
3b12939d 80 ui->prompt_state = PROMPTED;
05beb275
PA
81}
82
73ab01a0
PA
83/* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
84 returns NULL otherwise. */
85
86static struct mi_interp *
87as_mi_interp (struct interp *interp)
88{
716b8bc5 89 return dynamic_cast<mi_interp *> (interp);
73ab01a0
PA
90}
91
2736b771
SM
92void
93mi_interp::on_command_error ()
e8b4efc3 94{
2736b771 95 display_mi_prompt (this);
e8b4efc3
TT
96}
97
d6f9b0fb
PA
98void
99mi_interp::init (bool top_level)
4a8f6654 100{
d6f9b0fb 101 mi_interp *mi = this;
4a8f6654 102
9204d692
PA
103 /* Store the current output channel, so that we can create a console
104 channel that encapsulates and prefixes all gdb_output-type bits
105 coming from the rest of the debugger. */
106 mi->raw_stdout = gdb_stdout;
4a8f6654 107
2b03b41d
SS
108 /* Create MI console channels, each with a different prefix so they
109 can be distinguished. */
d7e74731
PA
110 mi->out = new mi_console_file (mi->raw_stdout, "~", '"');
111 mi->err = new mi_console_file (mi->raw_stdout, "&", '"');
4a8f6654 112 mi->log = mi->err;
d7e74731
PA
113 mi->targ = new mi_console_file (mi->raw_stdout, "@", '"');
114 mi->event_channel = new mi_console_file (mi->raw_stdout, "=", 0);
8e5e5494
SM
115 mi->mi_uiout = mi_out_new (name ());
116 gdb_assert (mi->mi_uiout != nullptr);
66fd2c67 117 mi->cli_uiout = new cli_ui_out (mi->out);
fd664c91 118
683f2885 119 if (top_level)
063bfe2e 120 {
788eca49
SM
121 /* The initial inferior is created before this function is called, so we
122 need to report it explicitly when initializing the top-level MI
123 interpreter.
124
125 This is also called when additional MI interpreters are added (using
126 the new-ui command), when multiple inferiors possibly exist, so we need
023c6d45 127 to use iteration to report all the inferiors. */
788eca49
SM
128
129 for (inferior *inf : all_inferiors ())
023c6d45 130 mi->on_inferior_added (inf);
788eca49 131 }
4a8f6654
AC
132}
133
d6f9b0fb
PA
134void
135mi_interp::resume ()
4a8f6654 136{
d6f9b0fb 137 struct mi_interp *mi = this;
a74e1786 138 struct ui *ui = current_ui;
4a8f6654 139
2b03b41d
SS
140 /* As per hack note in mi_interpreter_init, swap in the output
141 channels... */
3c216924 142 gdb_setup_readline (0);
4a8f6654 143
a74e1786
PA
144 ui->call_readline = gdb_readline_no_editing_callback;
145 ui->input_handler = mi_execute_command_input_handler;
4a8f6654
AC
146
147 gdb_stdout = mi->out;
2b03b41d 148 /* Route error and log output through the MI. */
4a8f6654
AC
149 gdb_stderr = mi->err;
150 gdb_stdlog = mi->log;
2b03b41d 151 /* Route target output through the MI. */
4a8f6654 152 gdb_stdtarg = mi->targ;
2b03b41d 153 /* Route target error through the MI as well. */
1f20321b 154 gdb_stdtargerr = mi->targ;
4a8f6654 155
9a4105ab 156 deprecated_show_load_progress = mi_load_progress;
4a8f6654
AC
157}
158
d6f9b0fb
PA
159void
160mi_interp::suspend ()
4a8f6654
AC
161{
162 gdb_disable_readline ();
4a8f6654
AC
163}
164
b885aea1 165void
d6f9b0fb 166mi_interp::exec (const char *command)
4a8f6654 167{
ee047554 168 mi_execute_command_wrapper (command);
4a8f6654
AC
169}
170
ce8f13f8 171void
9158e49a
TT
172mi_cmd_interpreter_exec (const char *command, const char *const *argv,
173 int argc)
4a8f6654
AC
174{
175 struct interp *interp_to_use;
4a8f6654 176 int i;
4a8f6654
AC
177
178 if (argc < 2)
1b05df00 179 error (_("-interpreter-exec: "
9b20d036 180 "Usage: -interpreter-exec interp command"));
4a8f6654 181
8322445e 182 interp_to_use = interp_lookup (current_ui, argv[0]);
4a8f6654 183 if (interp_to_use == NULL)
1b05df00 184 error (_("-interpreter-exec: could not find interpreter \"%s\""),
9a2b4c1b 185 argv[0]);
4a8f6654 186
17b2616c
PA
187 /* Note that unlike the CLI version of this command, we don't
188 actually set INTERP_TO_USE as the current interpreter, as we
189 still want gdb_stdout, etc. to point at MI streams. */
190
2b03b41d
SS
191 /* Insert the MI out hooks, making sure to also call the
192 interpreter's hooks if it has any. */
193 /* KRS: We shouldn't need this... Events should be installed and
194 they should just ALWAYS fire something out down the MI
195 channel. */
4a8f6654
AC
196 mi_insert_notify_hooks ();
197
2b03b41d 198 /* Now run the code. */
4a8f6654 199
3d6e9d23
TT
200 SCOPE_EXIT
201 {
202 mi_remove_notify_hooks ();
203 };
204
4a8f6654 205 for (i = 1; i < argc; i++)
b885aea1 206 interp_exec (interp_to_use, argv[i]);
4a8f6654
AC
207}
208
2b03b41d
SS
209/* This inserts a number of hooks that are meant to produce
210 async-notify ("=") MI messages while running commands in another
211 interpreter using mi_interpreter_exec. The canonical use for this
212 is to allow access to the gdb CLI interpreter from within the MI,
213 while still producing MI style output when actions in the CLI
214 command change GDB's state. */
4a8f6654
AC
215
216static void
217mi_insert_notify_hooks (void)
218{
9a4105ab 219 deprecated_query_hook = mi_interp_query_hook;
4a8f6654
AC
220}
221
222static void
11308a41 223mi_remove_notify_hooks (void)
4a8f6654 224{
9a4105ab 225 deprecated_query_hook = NULL;
4a8f6654
AC
226}
227
228static int
229mi_interp_query_hook (const char *ctlstr, va_list ap)
230{
231 return 1;
232}
233
4a8f6654 234static void
ee047554 235mi_execute_command_wrapper (const char *cmd)
4a8f6654 236{
f38d3ad1
PA
237 struct ui *ui = current_ui;
238
268a799a 239 mi_execute_command (cmd, ui->instream == ui->stdin_stream);
4a8f6654
AC
240}
241
c3d321de
SM
242void
243mi_interp::on_sync_execution_done ()
329ea579 244{
0b333c5e
PA
245 /* If MI is sync, then output the MI prompt now, indicating we're
246 ready for further input. */
329ea579 247 if (!mi_async_p ())
c3d321de 248 display_mi_prompt (this);
329ea579
PA
249}
250
e837f12a
JK
251/* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
252
253static void
95bc9f0b 254mi_execute_command_input_handler (gdb::unique_xmalloc_ptr<char> &&cmd)
e837f12a 255{
9204d692 256 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
3b12939d
PA
257 struct ui *ui = current_ui;
258
259 ui->prompt_state = PROMPT_NEEDED;
9204d692 260
95bc9f0b 261 mi_execute_command_wrapper (cmd.get ());
e837f12a 262
0b333c5e
PA
263 /* Print a prompt, indicating we're ready for further input, unless
264 we just started a synchronous command. In that case, we're about
265 to go back to the event loop and will output the prompt in the
266 'synchronous_command_done' observer when the target next
267 stops. */
3b12939d 268 if (ui->prompt_state == PROMPT_NEEDED)
9204d692 269 display_mi_prompt (mi);
e837f12a
JK
270}
271
d6f9b0fb
PA
272void
273mi_interp::pre_command_loop ()
4a8f6654 274{
d6f9b0fb 275 struct mi_interp *mi = this;
9204d692 276
4a8f6654 277 /* Turn off 8 bit strings in quoted output. Any character with the
2b03b41d 278 high bit set is printed using C's octal format. */
4a8f6654 279 sevenbit_strings = 1;
2b03b41d
SS
280
281 /* Tell the world that we're alive. */
9204d692 282 display_mi_prompt (mi);
4a8f6654
AC
283}
284
30e7e0a9
SM
285void
286mi_interp::on_new_thread (thread_info *t)
683f2885 287{
30e7e0a9
SM
288 target_terminal::scoped_restore_terminal_state term_state;
289 target_terminal::ours_for_output ();
73ab01a0 290
30e7e0a9
SM
291 gdb_printf (this->event_channel, "thread-created,id=\"%d\",group-id=\"i%d\"",
292 t->global_num, t->inf->num);
293 gdb_flush (this->event_channel);
683f2885
VP
294}
295
8e7af843
SM
296void
297mi_interp::on_thread_exited (thread_info *t, int silent)
063bfe2e 298{
8e7af843
SM
299 target_terminal::scoped_restore_terminal_state term_state;
300 target_terminal::ours_for_output ();
301 gdb_printf (this->event_channel, "thread-exited,id=\"%d\",group-id=\"i%d\"",
302 t->global_num, t->inf->num);
303 gdb_flush (this->event_channel);
063bfe2e
VP
304}
305
44fbffc6
SM
306void
307mi_interp::on_record_changed (inferior *inferior, int started,
308 const char *method, const char *format)
82a90ccf 309{
44fbffc6
SM
310 target_terminal::scoped_restore_terminal_state term_state;
311 target_terminal::ours_for_output ();
73ab01a0 312
44fbffc6
SM
313 if (started)
314 {
315 if (format != NULL)
316 gdb_printf (this->event_channel,
317 "record-started,thread-group=\"i%d\","
318 "method=\"%s\",format=\"%s\"",
319 inferior->num, method, format);
38b022b4 320 else
44fbffc6
SM
321 gdb_printf (this->event_channel,
322 "record-started,thread-group=\"i%d\","
323 "method=\"%s\"",
324 inferior->num, method);
73ab01a0 325 }
44fbffc6
SM
326 else
327 gdb_printf (this->event_channel,
328 "record-stopped,thread-group=\"i%d\"",
329 inferior->num);
330
331 gdb_flush (this->event_channel);
82a90ccf
YQ
332}
333
023c6d45
SM
334void
335mi_interp::on_inferior_added (inferior *inf)
a79b8f6e 336{
023c6d45
SM
337 target_terminal::scoped_restore_terminal_state term_state;
338 target_terminal::ours_for_output ();
73ab01a0 339
023c6d45
SM
340 gdb_printf (this->event_channel, "thread-group-added,id=\"i%d\"", inf->num);
341 gdb_flush (this->event_channel);
a79b8f6e
VP
342}
343
0c613e17
SM
344void
345mi_interp::on_inferior_appeared (inferior *inf)
4a92f99b 346{
0c613e17
SM
347 target_terminal::scoped_restore_terminal_state term_state;
348 target_terminal::ours_for_output ();
73ab01a0 349
0c613e17
SM
350 gdb_printf (this->event_channel, "thread-group-started,id=\"i%d\",pid=\"%d\"",
351 inf->num, inf->pid);
352 gdb_flush (this->event_channel);
4a92f99b
VP
353}
354
d38086cc
SM
355void
356mi_interp::on_inferior_disappeared (inferior *inf)
4a92f99b 357{
d38086cc
SM
358 target_terminal::scoped_restore_terminal_state term_state;
359 target_terminal::ours_for_output ();
73ab01a0 360
d38086cc
SM
361 if (inf->has_exit_code)
362 gdb_printf (this->event_channel,
363 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
364 inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
365 else
366 gdb_printf (this->event_channel,
367 "thread-group-exited,id=\"i%d\"", inf->num);
73ab01a0 368
d38086cc 369 gdb_flush (this->event_channel);
4a92f99b
VP
370}
371
2646bfa7
SM
372void
373mi_interp::on_inferior_removed (inferior *inf)
a79b8f6e 374{
2646bfa7
SM
375 target_terminal::scoped_restore_terminal_state term_state;
376 target_terminal::ours_for_output ();
73ab01a0 377
2646bfa7
SM
378 gdb_printf (this->event_channel, "thread-group-removed,id=\"i%d\"", inf->num);
379 gdb_flush (this->event_channel);
a79b8f6e
VP
380}
381
fd664c91 382/* Observers for several run control events that print why the
6471e7d2 383 inferior has stopped to both the MI event channel and to the MI
fd664c91
PA
384 console. If the MI interpreter is not active, print nothing. */
385
3f75a984
SM
386void
387mi_interp::on_signal_received (enum gdb_signal siggnal)
fd664c91 388{
3f75a984
SM
389 print_signal_received_reason (this->mi_uiout, siggnal);
390 print_signal_received_reason (this->cli_uiout, siggnal);
fd664c91
PA
391}
392
d6bd2ef5
SM
393void
394mi_interp::on_signal_exited (gdb_signal sig)
17b2616c 395{
d6bd2ef5
SM
396 print_signal_exited_reason (this->mi_uiout, sig);
397 print_signal_exited_reason (this->cli_uiout, sig);
fd664c91
PA
398}
399
bf64d1d5
SM
400void
401mi_interp::on_exited (int status)
fd664c91 402{
bf64d1d5
SM
403 print_exited_reason (this->mi_uiout, status);
404 print_exited_reason (this->cli_uiout, status);
fd664c91
PA
405}
406
2e5dbfab
SM
407void
408mi_interp::on_no_history ()
fd664c91 409{
2e5dbfab
SM
410 print_no_history_reason (this->mi_uiout);
411 print_no_history_reason (this->cli_uiout);
17b2616c
PA
412}
413
87829267
SM
414void
415mi_interp::on_normal_stop (struct bpstat *bs, int print_frame)
f7f9a841
VP
416{
417 /* Since this can be called when CLI command is executing,
418 using cli interpreter, be sure to use MI uiout for output,
419 not the current one. */
87829267 420 ui_out *mi_uiout = this->interp_ui_out ();
f7f9a841 421
1d33d6ba
VP
422 if (print_frame)
423 {
87829267 424 thread_info *tp = inferior_thread ();
36dfb11c 425
573269a8
LS
426 if (tp->thread_fsm () != nullptr
427 && tp->thread_fsm ()->finished_p ())
243a9253 428 {
87829267
SM
429 async_reply_reason reason
430 = tp->thread_fsm ()->async_reply_reason ();
112e8700 431 mi_uiout->field_string ("reason", async_reason_lookup (reason));
1d33d6ba 432 }
243a9253 433
87829267
SM
434 interp *console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
435
4c7d57e7
TT
436 /* We only want to print the displays once, and we want it to
437 look just how it would on the console, so we use this to
438 decide whether the MI stop should include them. */
439 bool console_print = should_print_stop_to_console (console_interp, tp);
440 print_stop_event (mi_uiout, !console_print);
441
442 if (console_print)
87829267 443 print_stop_event (this->cli_uiout);
1d33d6ba 444
381befee 445 mi_uiout->field_signed ("thread-id", tp->global_num);
1d33d6ba
VP
446 if (non_stop)
447 {
10f489e5 448 ui_out_emit_list list_emitter (mi_uiout, "stopped-threads");
102040f0 449
381befee 450 mi_uiout->field_signed (NULL, tp->global_num);
1d33d6ba
VP
451 }
452 else
112e8700 453 mi_uiout->field_string ("stopped-threads", "all");
dc146f7c 454
87829267 455 int core = target_core_of_thread (tp->ptid);
dc146f7c 456 if (core != -1)
381befee 457 mi_uiout->field_signed ("core", core);
1d33d6ba 458 }
f7f9a841 459
87829267
SM
460 gdb_puts ("*stopped", this->raw_stdout);
461 mi_out_put (mi_uiout, this->raw_stdout);
462 mi_out_rewind (mi_uiout);
463 mi_print_timing_maybe (this->raw_stdout);
464 gdb_puts ("\n", this->raw_stdout);
465 gdb_flush (this->raw_stdout);
73ab01a0
PA
466}
467
7603ea6a
SM
468void
469mi_interp::on_about_to_proceed ()
f3b1572e
PA
470{
471 /* Suppress output while calling an inferior function. */
472
d7e15655 473 if (inferior_ptid != null_ptid)
f3b1572e
PA
474 {
475 struct thread_info *tp = inferior_thread ();
102040f0 476
16c381f0 477 if (tp->control.in_infcall)
f3b1572e
PA
478 return;
479 }
480
7603ea6a 481 this->mi_proceeded = 1;
f3b1572e
PA
482}
483
5b9afe8a
YQ
484/* When the element is non-zero, no MI notifications will be emitted in
485 response to the corresponding observers. */
2b03b41d 486
5b9afe8a
YQ
487struct mi_suppress_notification mi_suppress_notification =
488 {
489 0,
490 0,
201b4506 491 0,
4034d0ff 492 0,
5b9afe8a 493 };
8d3788bd 494
0bc845fc
SM
495void
496mi_interp::on_traceframe_changed (int tfnum, int tpnum)
201b4506 497{
201b4506
YQ
498 if (mi_suppress_notification.traceframe)
499 return;
500
0bc845fc
SM
501 target_terminal::scoped_restore_terminal_state term_state;
502 target_terminal::ours_for_output ();
5fe96654 503
0bc845fc
SM
504 if (tfnum >= 0)
505 gdb_printf (this->event_channel, "traceframe-changed,"
506 "num=\"%d\",tracepoint=\"%d\"",
507 tfnum, tpnum);
508 else
509 gdb_printf (this->event_channel, "traceframe-changed,end");
73ab01a0 510
0bc845fc 511 gdb_flush (this->event_channel);
201b4506
YQ
512}
513
bf506f27
SM
514void
515mi_interp::on_tsv_created (const trace_state_variable *tsv)
bb25a15c 516{
bf506f27
SM
517 target_terminal::scoped_restore_terminal_state term_state;
518 target_terminal::ours_for_output ();
5fe96654 519
bf506f27
SM
520 gdb_printf (this->event_channel, "tsv-created,"
521 "name=\"%s\",initial=\"%s\"",
522 tsv->name.c_str (), plongest (tsv->initial_value));
73ab01a0 523
bf506f27 524 gdb_flush (this->event_channel);
bb25a15c
YQ
525}
526
f0dffaff
SM
527void
528mi_interp::on_tsv_deleted (const trace_state_variable *tsv)
bb25a15c 529{
f0dffaff
SM
530 target_terminal::scoped_restore_terminal_state term_state;
531 target_terminal::ours_for_output ();
5fe96654 532
f0dffaff
SM
533 if (tsv != nullptr)
534 gdb_printf (this->event_channel, "tsv-deleted,name=\"%s\"",
535 tsv->name.c_str ());
536 else
537 gdb_printf (this->event_channel, "tsv-deleted");
73ab01a0 538
f0dffaff 539 gdb_flush (this->event_channel);
bb25a15c
YQ
540}
541
134a2066
YQ
542/* Emit notification on modifying a trace state variable. */
543
544static void
545mi_tsv_modified (const struct trace_state_variable *tsv)
546{
0e454242 547 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
548 {
549 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
550 struct ui_out *mi_uiout;
134a2066 551
73ab01a0
PA
552 if (mi == NULL)
553 continue;
134a2066 554
29f94340 555 mi_uiout = top_level_interpreter ()->interp_ui_out ();
134a2066 556
223ffa71
TT
557 target_terminal::scoped_restore_terminal_state term_state;
558 target_terminal::ours_for_output ();
134a2066 559
6cb06a8c
TT
560 gdb_printf (mi->event_channel,
561 "tsv-modified");
134a2066 562
992aeed8 563 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
5fe96654 564
112e8700
SM
565 mi_uiout->field_string ("name", tsv->name);
566 mi_uiout->field_string ("initial",
992aeed8 567 plongest (tsv->initial_value));
73ab01a0 568 if (tsv->value_known)
112e8700 569 mi_uiout->field_string ("current", plongest (tsv->value));
73ab01a0 570
73ab01a0 571 gdb_flush (mi->event_channel);
73ab01a0 572 }
134a2066
YQ
573}
574
65630365
PA
575/* Print breakpoint BP on MI's event channel. */
576
577static void
578mi_print_breakpoint_for_event (struct mi_interp *mi, breakpoint *bp)
579{
29f94340 580 ui_out *mi_uiout = mi->interp_ui_out ();
65630365
PA
581
582 /* We want the output from print_breakpoint to go to
583 mi->event_channel. One approach would be to just call
584 print_breakpoint, and then use mi_out_put to send the current
585 content of mi_uiout into mi->event_channel. However, that will
586 break if anything is output to mi_uiout prior to calling the
587 breakpoint_created notifications. So, we use
588 ui_out_redirect. */
992aeed8 589 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
65630365 590
a70b8144 591 try
65630365
PA
592 {
593 scoped_restore restore_uiout
594 = make_scoped_restore (&current_uiout, mi_uiout);
595
596 print_breakpoint (bp);
597 }
b1ffd112 598 catch (const gdb_exception_error &ex)
65630365
PA
599 {
600 exception_print (gdb_stderr, ex);
601 }
65630365
PA
602}
603
8d3788bd 604/* Emit notification about a created breakpoint. */
2b03b41d 605
8d3788bd
VP
606static void
607mi_breakpoint_created (struct breakpoint *b)
608{
5b9afe8a 609 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
610 return;
611
612 if (b->number <= 0)
613 return;
614
0e454242 615 SWITCH_THRU_ALL_UIS ()
492d29ea 616 {
73ab01a0 617 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 618
73ab01a0
PA
619 if (mi == NULL)
620 continue;
8d3788bd 621
223ffa71
TT
622 target_terminal::scoped_restore_terminal_state term_state;
623 target_terminal::ours_for_output ();
73ab01a0 624
6cb06a8c
TT
625 gdb_printf (mi->event_channel,
626 "breakpoint-created");
65630365 627 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
628
629 gdb_flush (mi->event_channel);
73ab01a0 630 }
8d3788bd
VP
631}
632
633/* Emit notification about deleted breakpoint. */
2b03b41d 634
8d3788bd
VP
635static void
636mi_breakpoint_deleted (struct breakpoint *b)
637{
5b9afe8a 638 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
639 return;
640
641 if (b->number <= 0)
642 return;
643
0e454242 644 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
645 {
646 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
8d3788bd 647
73ab01a0
PA
648 if (mi == NULL)
649 continue;
8d3788bd 650
223ffa71
TT
651 target_terminal::scoped_restore_terminal_state term_state;
652 target_terminal::ours_for_output ();
5fe96654 653
6cb06a8c
TT
654 gdb_printf (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
655 b->number);
73ab01a0
PA
656
657 gdb_flush (mi->event_channel);
73ab01a0 658 }
8d3788bd
VP
659}
660
661/* Emit notification about modified breakpoint. */
2b03b41d 662
8d3788bd
VP
663static void
664mi_breakpoint_modified (struct breakpoint *b)
665{
5b9afe8a 666 if (mi_suppress_notification.breakpoint)
8d3788bd
VP
667 return;
668
669 if (b->number <= 0)
670 return;
671
0e454242 672 SWITCH_THRU_ALL_UIS ()
492d29ea 673 {
73ab01a0 674 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
492d29ea 675
73ab01a0
PA
676 if (mi == NULL)
677 continue;
8d3788bd 678
223ffa71
TT
679 target_terminal::scoped_restore_terminal_state term_state;
680 target_terminal::ours_for_output ();
6cb06a8c
TT
681 gdb_printf (mi->event_channel,
682 "breakpoint-modified");
65630365 683 mi_print_breakpoint_for_event (mi, b);
73ab01a0
PA
684
685 gdb_flush (mi->event_channel);
73ab01a0 686 }
8d3788bd
VP
687}
688
00431a78
PA
689static void
690mi_output_running (struct thread_info *thread)
d90e17a7 691{
0e454242 692 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
693 {
694 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
695
696 if (mi == NULL)
697 continue;
698
6cb06a8c
TT
699 gdb_printf (mi->raw_stdout,
700 "*running,thread-id=\"%d\"\n",
701 thread->global_num);
73ab01a0 702 }
d90e17a7
PA
703}
704
08036331
PA
705/* Return true if there are multiple inferiors loaded. This is used
706 for backwards compatibility -- if there's only one inferior, output
707 "all", otherwise, output each resumed thread individually. */
708
709static bool
710multiple_inferiors_p ()
711{
712 int count = 0;
713 for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
714 {
715 count++;
716 if (count > 1)
717 return true;
718 }
719
720 return false;
721}
722
e1ac3328 723static void
5b6d1e4f
PA
724mi_on_resume_1 (struct mi_interp *mi,
725 process_stratum_target *targ, ptid_t ptid)
e1ac3328 726{
a2840c35
VP
727 /* To cater for older frontends, emit ^running, but do it only once
728 per each command. We do it here, since at this point we know
729 that the target was successfully resumed, and in non-async mode,
730 we won't return back to MI interpreter code until the target
731 is done running, so delaying the output of "^running" until then
732 will make it impossible for frontend to know what's going on.
733
734 In future (MI3), we'll be outputting "^done" here. */
f818c32b 735 if (!mi->running_result_record_printed && mi->mi_proceeded)
a2840c35 736 {
6cb06a8c
TT
737 gdb_printf (mi->raw_stdout, "%s^running\n",
738 current_token ? current_token : "");
a2840c35
VP
739 }
740
08036331
PA
741 /* Backwards compatibility. If doing a wildcard resume and there's
742 only one inferior, output "all", otherwise, output each resumed
743 thread individually. */
744 if ((ptid == minus_one_ptid || ptid.is_pid ())
745 && !multiple_inferiors_p ())
6cb06a8c 746 gdb_printf (mi->raw_stdout, "*running,thread-id=\"all\"\n");
e1ac3328 747 else
5b6d1e4f 748 for (thread_info *tp : all_non_exited_threads (targ, ptid))
08036331 749 mi_output_running (tp);
a2840c35 750
f818c32b 751 if (!mi->running_result_record_printed && mi->mi_proceeded)
a2840c35 752 {
f818c32b 753 mi->running_result_record_printed = 1;
3b12939d
PA
754 /* This is what gdb used to do historically -- printing prompt
755 even if it cannot actually accept any input. This will be
756 surely removed for MI3, and may be removed even earlier. */
757 if (current_ui->prompt_state == PROMPT_BLOCKED)
0426ad51 758 gdb_puts ("(gdb) \n", mi->raw_stdout);
a2840c35 759 }
9204d692 760 gdb_flush (mi->raw_stdout);
e1ac3328
VP
761}
762
52d98df7
SM
763void
764mi_interp::on_target_resumed (ptid_t ptid)
c86cf029 765{
73ab01a0 766 struct thread_info *tp = NULL;
6ef284bd 767
5b6d1e4f 768 process_stratum_target *target = current_inferior ()->process_target ();
d7e15655 769 if (ptid == minus_one_ptid || ptid.is_pid ())
73ab01a0
PA
770 tp = inferior_thread ();
771 else
9213a6d7 772 tp = target->find_thread (ptid);
6ef284bd 773
73ab01a0
PA
774 /* Suppress output while calling an inferior function. */
775 if (tp->control.in_infcall)
776 return;
6ef284bd 777
52d98df7
SM
778 target_terminal::scoped_restore_terminal_state term_state;
779 target_terminal::ours_for_output ();
73ab01a0 780
52d98df7 781 mi_on_resume_1 (this, target, ptid);
73ab01a0 782}
6ef284bd 783
51457a05
MAL
784/* See mi-interp.h. */
785
786void
787mi_output_solib_attribs (ui_out *uiout, struct so_list *solib)
788{
789 struct gdbarch *gdbarch = target_gdbarch ();
790
791 uiout->field_string ("id", solib->so_original_name);
792 uiout->field_string ("target-name", solib->so_original_name);
793 uiout->field_string ("host-name", solib->so_name);
381befee 794 uiout->field_signed ("symbols-loaded", solib->symbols_loaded);
51457a05
MAL
795 if (!gdbarch_has_global_solist (target_gdbarch ()))
796 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
797
10f489e5
TT
798 ui_out_emit_list list_emitter (uiout, "ranges");
799 ui_out_emit_tuple tuple_emitter (uiout, NULL);
51457a05
MAL
800 if (solib->addr_high != 0)
801 {
802 uiout->field_core_addr ("from", gdbarch, solib->addr_low);
803 uiout->field_core_addr ("to", gdbarch, solib->addr_high);
804 }
51457a05
MAL
805}
806
f6485481
SM
807void
808mi_interp::on_solib_loaded (so_list *solib)
73ab01a0 809{
f6485481 810 ui_out *uiout = this->interp_ui_out ();
5fe96654 811
f6485481
SM
812 target_terminal::scoped_restore_terminal_state term_state;
813 target_terminal::ours_for_output ();
73ab01a0 814
f6485481 815 gdb_printf (this->event_channel, "library-loaded");
73ab01a0 816
f6485481 817 ui_out_redirect_pop redir (uiout, this->event_channel);
73ab01a0 818
f6485481 819 mi_output_solib_attribs (uiout, solib);
73ab01a0 820
f6485481 821 gdb_flush (this->event_channel);
c86cf029
VP
822}
823
d711fe3b
SM
824void
825mi_interp::on_solib_unloaded (so_list *solib)
c86cf029 826{
d711fe3b 827 ui_out *uiout = this->interp_ui_out ();
6ef284bd 828
d711fe3b
SM
829 target_terminal::scoped_restore_terminal_state term_state;
830 target_terminal::ours_for_output ();
6ef284bd 831
d711fe3b 832 gdb_printf (this->event_channel, "library-unloaded");
a79b8f6e 833
d711fe3b 834 ui_out_redirect_pop redir (uiout, this->event_channel);
5fe96654 835
d711fe3b
SM
836 uiout->field_string ("id", solib->so_original_name);
837 uiout->field_string ("target-name", solib->so_original_name);
838 uiout->field_string ("host-name", solib->so_name);
839 if (!gdbarch_has_global_solist (target_gdbarch ()))
840 uiout->field_fmt ("thread-group", "i%d", current_inferior ()->num);
73ab01a0 841
d711fe3b 842 gdb_flush (this->event_channel);
c86cf029
VP
843}
844
5b9afe8a
YQ
845/* Emit notification about the command parameter change. */
846
847static void
848mi_command_param_changed (const char *param, const char *value)
849{
5b9afe8a
YQ
850 if (mi_suppress_notification.cmd_param_changed)
851 return;
852
0e454242 853 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
854 {
855 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
856 struct ui_out *mi_uiout;
5b9afe8a 857
73ab01a0
PA
858 if (mi == NULL)
859 continue;
5b9afe8a 860
29f94340 861 mi_uiout = top_level_interpreter ()->interp_ui_out ();
5b9afe8a 862
223ffa71
TT
863 target_terminal::scoped_restore_terminal_state term_state;
864 target_terminal::ours_for_output ();
5b9afe8a 865
6cb06a8c 866 gdb_printf (mi->event_channel, "cmd-param-changed");
5b9afe8a 867
992aeed8 868 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
5fe96654 869
112e8700
SM
870 mi_uiout->field_string ("param", param);
871 mi_uiout->field_string ("value", value);
73ab01a0 872
73ab01a0 873 gdb_flush (mi->event_channel);
73ab01a0 874 }
5b9afe8a
YQ
875}
876
8de0566d
YQ
877/* Emit notification about the target memory change. */
878
879static void
880mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
881 ssize_t len, const bfd_byte *myaddr)
882{
8de0566d
YQ
883 if (mi_suppress_notification.memory)
884 return;
885
0e454242 886 SWITCH_THRU_ALL_UIS ()
73ab01a0
PA
887 {
888 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
889 struct ui_out *mi_uiout;
890 struct obj_section *sec;
8de0566d 891
73ab01a0
PA
892 if (mi == NULL)
893 continue;
8de0566d 894
29f94340 895 mi_uiout = top_level_interpreter ()->interp_ui_out ();
8de0566d 896
223ffa71
TT
897 target_terminal::scoped_restore_terminal_state term_state;
898 target_terminal::ours_for_output ();
8de0566d 899
6cb06a8c 900 gdb_printf (mi->event_channel, "memory-changed");
8de0566d 901
992aeed8 902 ui_out_redirect_pop redir (mi_uiout, mi->event_channel);
8de0566d 903
112e8700
SM
904 mi_uiout->field_fmt ("thread-group", "i%d", inferior->num);
905 mi_uiout->field_core_addr ("addr", target_gdbarch (), memaddr);
33eca680 906 mi_uiout->field_string ("len", hex_string (len));
8de0566d 907
73ab01a0
PA
908 /* Append 'type=code' into notification if MEMADDR falls in the range of
909 sections contain code. */
910 sec = find_pc_section (memaddr);
911 if (sec != NULL && sec->objfile != NULL)
912 {
fd361982 913 flagword flags = bfd_section_flags (sec->the_bfd_section);
5fe96654 914
73ab01a0 915 if (flags & SEC_CODE)
112e8700 916 mi_uiout->field_string ("type", "code");
73ab01a0
PA
917 }
918
73ab01a0 919 gdb_flush (mi->event_channel);
73ab01a0 920 }
8de0566d
YQ
921}
922
77cd03e2
SM
923void
924mi_interp::on_user_selected_context_changed (user_selected_what selection)
4034d0ff 925{
4034d0ff
AT
926 /* Don't send an event if we're responding to an MI command. */
927 if (mi_suppress_notification.user_selected_context)
928 return;
929
77cd03e2
SM
930 thread_info *tp = inferior_ptid != null_ptid ? inferior_thread () : nullptr;
931 ui_out *mi_uiout = this->interp_ui_out ();
932 ui_out_redirect_pop redirect_popper (mi_uiout, this->event_channel);
4034d0ff 933
77cd03e2
SM
934 target_terminal::scoped_restore_terminal_state term_state;
935 target_terminal::ours_for_output ();
4034d0ff 936
77cd03e2
SM
937 if (selection & USER_SELECTED_INFERIOR)
938 print_selected_inferior (this->cli_uiout);
4034d0ff 939
77cd03e2
SM
940 if (tp != NULL
941 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
942 {
943 print_selected_thread_frame (this->cli_uiout, selection);
4034d0ff 944
77cd03e2
SM
945 gdb_printf (this->event_channel, "thread-selected,id=\"%d\"",
946 tp->global_num);
4034d0ff 947
77cd03e2 948 if (tp->state != THREAD_RUNNING)
4034d0ff 949 {
77cd03e2
SM
950 if (has_stack_frames ())
951 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
952 1, SRC_AND_LOC, 1);
4034d0ff 953 }
4034d0ff 954 }
77cd03e2
SM
955
956 gdb_flush (this->event_channel);
4034d0ff
AT
957}
958
d6f9b0fb
PA
959ui_out *
960mi_interp::interp_ui_out ()
4801a9a3 961{
d6f9b0fb 962 return this->mi_uiout;
4801a9a3
PA
963}
964
37ce89eb
SS
965/* Do MI-specific logging actions; save raw_stdout, and change all
966 the consoles to use the supplied ui-file(s). */
967
d6f9b0fb 968void
ca1285d1
AH
969mi_interp::set_logging (ui_file_up logfile, bool logging_redirect,
970 bool debug_redirect)
37ce89eb 971{
d6f9b0fb 972 struct mi_interp *mi = this;
37ce89eb 973
616268b6 974 if (logfile != NULL)
37ce89eb 975 {
9204d692 976 mi->saved_raw_stdout = mi->raw_stdout;
616268b6 977
2b141965 978 ui_file *logfile_p = logfile.get ();
016c606c 979 mi->logfile_holder = std::move (logfile);
f3a09c80
AH
980
981 /* If something is not being redirected, then a tee containing both the
982 logfile and stdout. */
983 ui_file *tee = nullptr;
ca1285d1
AH
984 if (!logging_redirect || !debug_redirect)
985 {
2b141965 986 tee = new tee_file (mi->raw_stdout, logfile_p);
016c606c 987 mi->stdout_holder.reset (tee);
ca1285d1 988 }
f3a09c80
AH
989
990 mi->raw_stdout = logging_redirect ? logfile_p : tee;
37ce89eb
SS
991 }
992 else
993 {
016c606c
TT
994 mi->logfile_holder.reset ();
995 mi->stdout_holder.reset ();
9204d692 996 mi->raw_stdout = mi->saved_raw_stdout;
f3a09c80 997 mi->saved_raw_stdout = nullptr;
37ce89eb 998 }
f3a09c80 999
d7e74731
PA
1000 mi->out->set_raw (mi->raw_stdout);
1001 mi->err->set_raw (mi->raw_stdout);
1002 mi->log->set_raw (mi->raw_stdout);
1003 mi->targ->set_raw (mi->raw_stdout);
1004 mi->event_channel->set_raw (mi->raw_stdout);
37ce89eb
SS
1005}
1006
8322445e
PA
1007/* Factory for MI interpreters. */
1008
1009static struct interp *
1010mi_interp_factory (const char *name)
1011{
d6f9b0fb 1012 return new mi_interp (name);
8322445e
PA
1013}
1014
6c265988 1015void _initialize_mi_interp ();
4a8f6654 1016void
6c265988 1017_initialize_mi_interp ()
4a8f6654 1018{
2fcf52f0 1019 /* The various interpreter levels. */
8322445e
PA
1020 interp_factory_register (INTERP_MI2, mi_interp_factory);
1021 interp_factory_register (INTERP_MI3, mi_interp_factory);
9db0d853 1022 interp_factory_register (INTERP_MI4, mi_interp_factory);
8322445e 1023 interp_factory_register (INTERP_MI, mi_interp_factory);
73ab01a0 1024
c90e7d63
SM
1025 gdb::observers::tsv_modified.attach (mi_tsv_modified, "mi-interp");
1026 gdb::observers::breakpoint_created.attach (mi_breakpoint_created,
1027 "mi-interp");
1028 gdb::observers::breakpoint_deleted.attach (mi_breakpoint_deleted,
1029 "mi-interp");
1030 gdb::observers::breakpoint_modified.attach (mi_breakpoint_modified,
1031 "mi-interp");
1032 gdb::observers::command_param_changed.attach (mi_command_param_changed,
1033 "mi-interp");
1034 gdb::observers::memory_changed.attach (mi_memory_changed, "mi-interp");
4a8f6654 1035}