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