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