1 /* MI Interpreter Definitions and Commands for GDB, the GNU debugger. 2 3 Copyright (C) 2002-2005, 2007-2012 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 3 of the License, or 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 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "gdb_string.h" 22 #include "interps.h" 23 #include "event-top.h" 24 #include "event-loop.h" 25 #include "inferior.h" 26 #include "ui-out.h" 27 #include "top.h" 28 #include "exceptions.h" 29 #include "mi-main.h" 30 #include "mi-cmds.h" 31 #include "mi-out.h" 32 #include "mi-console.h" 33 #include "mi-common.h" 34 #include "observer.h" 35 #include "gdbthread.h" 36 #include "solist.h" 37 #include "gdb.h" 38 39 /* These are the interpreter setup, etc. functions for the MI interpreter */ 40 static void mi_execute_command_wrapper (char *cmd); 41 static void mi_command_loop (int mi_version); 42 43 /* These are hooks that we put in place while doing interpreter_exec 44 so we can report interesting things that happened "behind the mi's 45 back" in this command */ 46 static int mi_interp_query_hook (const char *ctlstr, va_list ap) 47 ATTRIBUTE_PRINTF (1, 0); 48 49 static void mi3_command_loop (void); 50 static void mi2_command_loop (void); 51 static void mi1_command_loop (void); 52 53 static void mi_insert_notify_hooks (void); 54 static void mi_remove_notify_hooks (void); 55 static void mi_on_normal_stop (struct bpstats *bs, int print_frame); 56 57 static void mi_new_thread (struct thread_info *t); 58 static void mi_thread_exit (struct thread_info *t, int silent); 59 static void mi_inferior_added (struct inferior *inf); 60 static void mi_inferior_appeared (struct inferior *inf); 61 static void mi_inferior_exit (struct inferior *inf); 62 static void mi_inferior_removed (struct inferior *inf); 63 static void mi_on_resume (ptid_t ptid); 64 static void mi_solib_loaded (struct so_list *solib); 65 static void mi_solib_unloaded (struct so_list *solib); 66 static void mi_about_to_proceed (void); 67 static void mi_breakpoint_created (struct breakpoint *b); 68 static void mi_breakpoint_deleted (struct breakpoint *b); 69 static void mi_breakpoint_modified (struct breakpoint *b); 70 71 static int report_initial_inferior (struct inferior *inf, void *closure); 72 73 static void * 74 mi_interpreter_init (struct interp *interp, int top_level) 75 { 76 struct mi_interp *mi = XMALLOC (struct mi_interp); 77 const char *name; 78 int mi_version; 79 80 /* HACK: We need to force stdout/stderr to point at the console. This avoids 81 any potential side effects caused by legacy code that is still 82 using the TUI / fputs_unfiltered_hook. So we set up output channels for 83 this now, and swap them in when we are run. */ 84 85 raw_stdout = stdio_fileopen (stdout); 86 87 /* Create MI channels */ 88 mi->out = mi_console_file_new (raw_stdout, "~", '"'); 89 mi->err = mi_console_file_new (raw_stdout, "&", '"'); 90 mi->log = mi->err; 91 mi->targ = mi_console_file_new (raw_stdout, "@", '"'); 92 mi->event_channel = mi_console_file_new (raw_stdout, "=", 0); 93 94 name = interp_name (interp); 95 /* INTERP_MI selects the most recent released version. "mi2" was 96 released as part of GDB 6.0. */ 97 if (strcmp (name, INTERP_MI) == 0) 98 mi_version = 2; 99 else if (strcmp (name, INTERP_MI1) == 0) 100 mi_version = 1; 101 else if (strcmp (name, INTERP_MI2) == 0) 102 mi_version = 2; 103 else if (strcmp (name, INTERP_MI3) == 0) 104 mi_version = 3; 105 else 106 gdb_assert_not_reached ("unhandled MI version"); 107 108 mi->uiout = mi_out_new (mi_version); 109 110 if (top_level) 111 { 112 observer_attach_new_thread (mi_new_thread); 113 observer_attach_thread_exit (mi_thread_exit); 114 observer_attach_inferior_added (mi_inferior_added); 115 observer_attach_inferior_appeared (mi_inferior_appeared); 116 observer_attach_inferior_exit (mi_inferior_exit); 117 observer_attach_inferior_removed (mi_inferior_removed); 118 observer_attach_normal_stop (mi_on_normal_stop); 119 observer_attach_target_resumed (mi_on_resume); 120 observer_attach_solib_loaded (mi_solib_loaded); 121 observer_attach_solib_unloaded (mi_solib_unloaded); 122 observer_attach_about_to_proceed (mi_about_to_proceed); 123 observer_attach_breakpoint_created (mi_breakpoint_created); 124 observer_attach_breakpoint_deleted (mi_breakpoint_deleted); 125 observer_attach_breakpoint_modified (mi_breakpoint_modified); 126 127 /* The initial inferior is created before this function is called, so we 128 need to report it explicitly. Use iteration in case future version 129 of GDB creates more than one inferior up-front. */ 130 iterate_over_inferiors (report_initial_inferior, mi); 131 } 132 133 return mi; 134 } 135 136 static int 137 mi_interpreter_resume (void *data) 138 { 139 struct mi_interp *mi = data; 140 141 /* As per hack note in mi_interpreter_init, swap in the output channels... */ 142 gdb_setup_readline (); 143 144 /* These overwrite some of the initialization done in 145 _intialize_event_loop. */ 146 call_readline = gdb_readline2; 147 input_handler = mi_execute_command_wrapper; 148 add_file_handler (input_fd, stdin_event_handler, 0); 149 async_command_editing_p = 0; 150 /* FIXME: This is a total hack for now. PB's use of the MI 151 implicitly relies on a bug in the async support which allows 152 asynchronous commands to leak through the commmand loop. The bug 153 involves (but is not limited to) the fact that sync_execution was 154 erroneously initialized to 0. Duplicate by initializing it thus 155 here... */ 156 sync_execution = 0; 157 158 gdb_stdout = mi->out; 159 /* Route error and log output through the MI */ 160 gdb_stderr = mi->err; 161 gdb_stdlog = mi->log; 162 /* Route target output through the MI. */ 163 gdb_stdtarg = mi->targ; 164 /* Route target error through the MI as well. */ 165 gdb_stdtargerr = mi->targ; 166 167 /* Replace all the hooks that we know about. There really needs to 168 be a better way of doing this... */ 169 clear_interpreter_hooks (); 170 171 deprecated_show_load_progress = mi_load_progress; 172 173 /* If we're _the_ interpreter, take control. */ 174 if (current_interp_named_p (INTERP_MI1)) 175 deprecated_command_loop_hook = mi1_command_loop; 176 else if (current_interp_named_p (INTERP_MI2)) 177 deprecated_command_loop_hook = mi2_command_loop; 178 else if (current_interp_named_p (INTERP_MI3)) 179 deprecated_command_loop_hook = mi3_command_loop; 180 else 181 deprecated_command_loop_hook = mi2_command_loop; 182 183 return 1; 184 } 185 186 static int 187 mi_interpreter_suspend (void *data) 188 { 189 gdb_disable_readline (); 190 return 1; 191 } 192 193 static struct gdb_exception 194 mi_interpreter_exec (void *data, const char *command) 195 { 196 char *tmp = alloca (strlen (command) + 1); 197 198 strcpy (tmp, command); 199 mi_execute_command_wrapper (tmp); 200 return exception_none; 201 } 202 203 /* Never display the default gdb prompt in mi case. */ 204 static int 205 mi_interpreter_prompt_p (void *data) 206 { 207 return 0; 208 } 209 210 void 211 mi_cmd_interpreter_exec (char *command, char **argv, int argc) 212 { 213 struct interp *interp_to_use; 214 int i; 215 char *mi_error_message = NULL; 216 struct cleanup *old_chain; 217 218 if (argc < 2) 219 error (_("-interpreter-exec: " 220 "Usage: -interpreter-exec interp command")); 221 222 interp_to_use = interp_lookup (argv[0]); 223 if (interp_to_use == NULL) 224 error (_("-interpreter-exec: could not find interpreter \"%s\""), 225 argv[0]); 226 227 if (!interp_exec_p (interp_to_use)) 228 error (_("-interpreter-exec: interpreter \"%s\" " 229 "does not support command execution"), 230 argv[0]); 231 232 /* Insert the MI out hooks, making sure to also call the interpreter's hooks 233 if it has any. */ 234 /* KRS: We shouldn't need this... Events should be installed and they should 235 just ALWAYS fire something out down the MI channel... */ 236 mi_insert_notify_hooks (); 237 238 /* Now run the code... */ 239 240 old_chain = make_cleanup (null_cleanup, 0); 241 for (i = 1; i < argc; i++) 242 { 243 struct gdb_exception e = interp_exec (interp_to_use, argv[i]); 244 245 if (e.reason < 0) 246 { 247 mi_error_message = xstrdup (e.message); 248 make_cleanup (xfree, mi_error_message); 249 break; 250 } 251 } 252 253 mi_remove_notify_hooks (); 254 255 if (mi_error_message != NULL) 256 error ("%s", mi_error_message); 257 do_cleanups (old_chain); 258 } 259 260 /* 261 * mi_insert_notify_hooks - This inserts a number of hooks that are 262 * meant to produce async-notify ("=") MI messages while running 263 * commands in another interpreter using mi_interpreter_exec. The 264 * canonical use for this is to allow access to the gdb CLI 265 * interpreter from within the MI, while still producing MI style 266 * output when actions in the CLI command change gdb's state. 267 */ 268 269 static void 270 mi_insert_notify_hooks (void) 271 { 272 deprecated_query_hook = mi_interp_query_hook; 273 } 274 275 static void 276 mi_remove_notify_hooks (void) 277 { 278 deprecated_query_hook = NULL; 279 } 280 281 static int 282 mi_interp_query_hook (const char *ctlstr, va_list ap) 283 { 284 return 1; 285 } 286 287 static void 288 mi_execute_command_wrapper (char *cmd) 289 { 290 mi_execute_command (cmd, stdin == instream); 291 } 292 293 static void 294 mi1_command_loop (void) 295 { 296 mi_command_loop (1); 297 } 298 299 static void 300 mi2_command_loop (void) 301 { 302 mi_command_loop (2); 303 } 304 305 static void 306 mi3_command_loop (void) 307 { 308 mi_command_loop (3); 309 } 310 311 static void 312 mi_command_loop (int mi_version) 313 { 314 /* Turn off 8 bit strings in quoted output. Any character with the 315 high bit set is printed using C's octal format. */ 316 sevenbit_strings = 1; 317 /* Tell the world that we're alive */ 318 fputs_unfiltered ("(gdb) \n", raw_stdout); 319 gdb_flush (raw_stdout); 320 start_event_loop (); 321 } 322 323 static void 324 mi_new_thread (struct thread_info *t) 325 { 326 struct mi_interp *mi = top_level_interpreter_data (); 327 struct inferior *inf = find_inferior_pid (ptid_get_pid (t->ptid)); 328 329 gdb_assert (inf); 330 331 fprintf_unfiltered (mi->event_channel, 332 "thread-created,id=\"%d\",group-id=\"i%d\"", 333 t->num, inf->num); 334 gdb_flush (mi->event_channel); 335 } 336 337 static void 338 mi_thread_exit (struct thread_info *t, int silent) 339 { 340 struct mi_interp *mi; 341 struct inferior *inf; 342 343 if (silent) 344 return; 345 346 inf = find_inferior_pid (ptid_get_pid (t->ptid)); 347 348 mi = top_level_interpreter_data (); 349 target_terminal_ours (); 350 fprintf_unfiltered (mi->event_channel, 351 "thread-exited,id=\"%d\",group-id=\"i%d\"", 352 t->num, inf->num); 353 gdb_flush (mi->event_channel); 354 } 355 356 static void 357 mi_inferior_added (struct inferior *inf) 358 { 359 struct mi_interp *mi = top_level_interpreter_data (); 360 361 target_terminal_ours (); 362 fprintf_unfiltered (mi->event_channel, 363 "thread-group-added,id=\"i%d\"", 364 inf->num); 365 gdb_flush (mi->event_channel); 366 } 367 368 static void 369 mi_inferior_appeared (struct inferior *inf) 370 { 371 struct mi_interp *mi = top_level_interpreter_data (); 372 373 target_terminal_ours (); 374 fprintf_unfiltered (mi->event_channel, 375 "thread-group-started,id=\"i%d\",pid=\"%d\"", 376 inf->num, inf->pid); 377 gdb_flush (mi->event_channel); 378 } 379 380 static void 381 mi_inferior_exit (struct inferior *inf) 382 { 383 struct mi_interp *mi = top_level_interpreter_data (); 384 385 target_terminal_ours (); 386 if (inf->has_exit_code) 387 fprintf_unfiltered (mi->event_channel, 388 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"", 389 inf->num, int_string (inf->exit_code, 8, 0, 0, 1)); 390 else 391 fprintf_unfiltered (mi->event_channel, 392 "thread-group-exited,id=\"i%d\"", inf->num); 393 394 gdb_flush (mi->event_channel); 395 } 396 397 static void 398 mi_inferior_removed (struct inferior *inf) 399 { 400 struct mi_interp *mi = top_level_interpreter_data (); 401 402 target_terminal_ours (); 403 fprintf_unfiltered (mi->event_channel, 404 "thread-group-removed,id=\"i%d\"", 405 inf->num); 406 gdb_flush (mi->event_channel); 407 } 408 409 static void 410 mi_on_normal_stop (struct bpstats *bs, int print_frame) 411 { 412 /* Since this can be called when CLI command is executing, 413 using cli interpreter, be sure to use MI uiout for output, 414 not the current one. */ 415 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 416 417 if (print_frame) 418 { 419 int core; 420 421 if (current_uiout != mi_uiout) 422 { 423 /* The normal_stop function has printed frame information into 424 CLI uiout, or some other non-MI uiout. There's no way we 425 can extract proper fields from random uiout object, so we print 426 the frame again. In practice, this can only happen when running 427 a CLI command in MI. */ 428 struct ui_out *saved_uiout = current_uiout; 429 struct target_waitstatus last; 430 ptid_t last_ptid; 431 432 current_uiout = mi_uiout; 433 434 get_last_target_status (&last_ptid, &last); 435 bpstat_print (bs, last.kind); 436 437 print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC); 438 current_uiout = saved_uiout; 439 } 440 441 ui_out_field_int (mi_uiout, "thread-id", 442 pid_to_thread_id (inferior_ptid)); 443 if (non_stop) 444 { 445 struct cleanup *back_to = make_cleanup_ui_out_list_begin_end 446 (mi_uiout, "stopped-threads"); 447 448 ui_out_field_int (mi_uiout, NULL, 449 pid_to_thread_id (inferior_ptid)); 450 do_cleanups (back_to); 451 } 452 else 453 ui_out_field_string (mi_uiout, "stopped-threads", "all"); 454 455 core = target_core_of_thread (inferior_ptid); 456 if (core != -1) 457 ui_out_field_int (mi_uiout, "core", core); 458 } 459 460 fputs_unfiltered ("*stopped", raw_stdout); 461 mi_out_put (mi_uiout, raw_stdout); 462 mi_out_rewind (mi_uiout); 463 mi_print_timing_maybe (); 464 fputs_unfiltered ("\n", raw_stdout); 465 gdb_flush (raw_stdout); 466 } 467 468 static void 469 mi_about_to_proceed (void) 470 { 471 /* Suppress output while calling an inferior function. */ 472 473 if (!ptid_equal (inferior_ptid, null_ptid)) 474 { 475 struct thread_info *tp = inferior_thread (); 476 477 if (tp->control.in_infcall) 478 return; 479 } 480 481 mi_proceeded = 1; 482 } 483 484 /* When non-zero, no MI notifications will be emitted in 485 response to breakpoint change observers. */ 486 int mi_suppress_breakpoint_notifications = 0; 487 488 /* Emit notification about a created breakpoint. */ 489 static void 490 mi_breakpoint_created (struct breakpoint *b) 491 { 492 struct mi_interp *mi = top_level_interpreter_data (); 493 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 494 struct gdb_exception e; 495 496 if (mi_suppress_breakpoint_notifications) 497 return; 498 499 if (b->number <= 0) 500 return; 501 502 target_terminal_ours (); 503 fprintf_unfiltered (mi->event_channel, 504 "breakpoint-created"); 505 /* We want the output from gdb_breakpoint_query to go to 506 mi->event_channel. One approach would be to just 507 call gdb_breakpoint_query, and then use mi_out_put to 508 send the current content of mi_outout into mi->event_channel. 509 However, that will break if anything is output to mi_uiout 510 prior the calling the breakpoint_created notifications. 511 So, we use ui_out_redirect. */ 512 ui_out_redirect (mi_uiout, mi->event_channel); 513 TRY_CATCH (e, RETURN_MASK_ERROR) 514 gdb_breakpoint_query (mi_uiout, b->number, NULL); 515 ui_out_redirect (mi_uiout, NULL); 516 517 gdb_flush (mi->event_channel); 518 } 519 520 /* Emit notification about deleted breakpoint. */ 521 static void 522 mi_breakpoint_deleted (struct breakpoint *b) 523 { 524 struct mi_interp *mi = top_level_interpreter_data (); 525 526 if (mi_suppress_breakpoint_notifications) 527 return; 528 529 if (b->number <= 0) 530 return; 531 532 target_terminal_ours (); 533 534 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"", 535 b->number); 536 537 gdb_flush (mi->event_channel); 538 } 539 540 /* Emit notification about modified breakpoint. */ 541 static void 542 mi_breakpoint_modified (struct breakpoint *b) 543 { 544 struct mi_interp *mi = top_level_interpreter_data (); 545 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); 546 struct gdb_exception e; 547 548 if (mi_suppress_breakpoint_notifications) 549 return; 550 551 if (b->number <= 0) 552 return; 553 554 target_terminal_ours (); 555 fprintf_unfiltered (mi->event_channel, 556 "breakpoint-modified"); 557 /* We want the output from gdb_breakpoint_query to go to 558 mi->event_channel. One approach would be to just 559 call gdb_breakpoint_query, and then use mi_out_put to 560 send the current content of mi_outout into mi->event_channel. 561 However, that will break if anything is output to mi_uiout 562 prior the calling the breakpoint_created notifications. 563 So, we use ui_out_redirect. */ 564 ui_out_redirect (mi_uiout, mi->event_channel); 565 TRY_CATCH (e, RETURN_MASK_ERROR) 566 gdb_breakpoint_query (mi_uiout, b->number, NULL); 567 ui_out_redirect (mi_uiout, NULL); 568 569 gdb_flush (mi->event_channel); 570 } 571 572 573 static int 574 mi_output_running_pid (struct thread_info *info, void *arg) 575 { 576 ptid_t *ptid = arg; 577 578 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid)) 579 fprintf_unfiltered (raw_stdout, 580 "*running,thread-id=\"%d\"\n", 581 info->num); 582 583 return 0; 584 } 585 586 static int 587 mi_inferior_count (struct inferior *inf, void *arg) 588 { 589 if (inf->pid != FAKE_PROCESS_ID) 590 { 591 int *count_p = arg; 592 (*count_p)++; 593 } 594 595 return 0; 596 } 597 598 static void 599 mi_on_resume (ptid_t ptid) 600 { 601 struct thread_info *tp = NULL; 602 603 if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid)) 604 tp = inferior_thread (); 605 else 606 tp = find_thread_ptid (ptid); 607 608 /* Suppress output while calling an inferior function. */ 609 if (tp->control.in_infcall) 610 return; 611 612 /* To cater for older frontends, emit ^running, but do it only once 613 per each command. We do it here, since at this point we know 614 that the target was successfully resumed, and in non-async mode, 615 we won't return back to MI interpreter code until the target 616 is done running, so delaying the output of "^running" until then 617 will make it impossible for frontend to know what's going on. 618 619 In future (MI3), we'll be outputting "^done" here. */ 620 if (!running_result_record_printed && mi_proceeded) 621 { 622 fprintf_unfiltered (raw_stdout, "%s^running\n", 623 current_token ? current_token : ""); 624 } 625 626 if (PIDGET (ptid) == -1) 627 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); 628 else if (ptid_is_pid (ptid)) 629 { 630 int count = 0; 631 632 /* Backwards compatibility. If there's only one inferior, 633 output "all", otherwise, output each resumed thread 634 individually. */ 635 iterate_over_inferiors (mi_inferior_count, &count); 636 637 if (count == 1) 638 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"all\"\n"); 639 else 640 iterate_over_threads (mi_output_running_pid, &ptid); 641 } 642 else 643 { 644 struct thread_info *ti = find_thread_ptid (ptid); 645 646 gdb_assert (ti); 647 fprintf_unfiltered (raw_stdout, "*running,thread-id=\"%d\"\n", ti->num); 648 } 649 650 if (!running_result_record_printed && mi_proceeded) 651 { 652 running_result_record_printed = 1; 653 /* This is what gdb used to do historically -- printing prompt even if 654 it cannot actually accept any input. This will be surely removed 655 for MI3, and may be removed even earler. */ 656 /* FIXME: review the use of target_is_async_p here -- is that 657 what we want? */ 658 if (!target_is_async_p ()) 659 fputs_unfiltered ("(gdb) \n", raw_stdout); 660 } 661 gdb_flush (raw_stdout); 662 } 663 664 static void 665 mi_solib_loaded (struct so_list *solib) 666 { 667 struct mi_interp *mi = top_level_interpreter_data (); 668 669 target_terminal_ours (); 670 if (gdbarch_has_global_solist (target_gdbarch)) 671 fprintf_unfiltered (mi->event_channel, 672 "library-loaded,id=\"%s\",target-name=\"%s\"," 673 "host-name=\"%s\",symbols-loaded=\"%d\"", 674 solib->so_original_name, solib->so_original_name, 675 solib->so_name, solib->symbols_loaded); 676 else 677 fprintf_unfiltered (mi->event_channel, 678 "library-loaded,id=\"%s\",target-name=\"%s\"," 679 "host-name=\"%s\",symbols-loaded=\"%d\"," 680 "thread-group=\"i%d\"", 681 solib->so_original_name, solib->so_original_name, 682 solib->so_name, solib->symbols_loaded, 683 current_inferior ()->num); 684 685 gdb_flush (mi->event_channel); 686 } 687 688 static void 689 mi_solib_unloaded (struct so_list *solib) 690 { 691 struct mi_interp *mi = top_level_interpreter_data (); 692 693 target_terminal_ours (); 694 if (gdbarch_has_global_solist (target_gdbarch)) 695 fprintf_unfiltered (mi->event_channel, 696 "library-unloaded,id=\"%s\",target-name=\"%s\"," 697 "host-name=\"%s\"", 698 solib->so_original_name, solib->so_original_name, 699 solib->so_name); 700 else 701 fprintf_unfiltered (mi->event_channel, 702 "library-unloaded,id=\"%s\",target-name=\"%s\"," 703 "host-name=\"%s\",thread-group=\"i%d\"", 704 solib->so_original_name, solib->so_original_name, 705 solib->so_name, current_inferior ()->num); 706 707 gdb_flush (mi->event_channel); 708 } 709 710 static int 711 report_initial_inferior (struct inferior *inf, void *closure) 712 { 713 /* This function is called from mi_intepreter_init, and since 714 mi_inferior_added assumes that inferior is fully initialized 715 and top_level_interpreter_data is set, we cannot call 716 it here. */ 717 struct mi_interp *mi = closure; 718 719 target_terminal_ours (); 720 fprintf_unfiltered (mi->event_channel, 721 "thread-group-added,id=\"i%d\"", 722 inf->num); 723 gdb_flush (mi->event_channel); 724 return 0; 725 } 726 727 static struct ui_out * 728 mi_ui_out (struct interp *interp) 729 { 730 struct mi_interp *mi = interp_data (interp); 731 732 return mi->uiout; 733 } 734 735 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */ 736 737 void 738 _initialize_mi_interp (void) 739 { 740 static const struct interp_procs procs = 741 { 742 mi_interpreter_init, /* init_proc */ 743 mi_interpreter_resume, /* resume_proc */ 744 mi_interpreter_suspend, /* suspend_proc */ 745 mi_interpreter_exec, /* exec_proc */ 746 mi_interpreter_prompt_p, /* prompt_proc_p */ 747 mi_ui_out /* ui_out_proc */ 748 }; 749 750 /* The various interpreter levels. */ 751 interp_add (interp_new (INTERP_MI1, &procs)); 752 interp_add (interp_new (INTERP_MI2, &procs)); 753 interp_add (interp_new (INTERP_MI3, &procs)); 754 interp_add (interp_new (INTERP_MI, &procs)); 755 } 756