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