Emit inferior, thread and frame selection events to all UIs
[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-2016 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 "interps.h"
22 #include "event-top.h"
23 #include "event-loop.h"
24 #include "inferior.h"
25 #include "infrun.h"
26 #include "ui-out.h"
27 #include "top.h"
28 #include "mi-main.h"
29 #include "mi-cmds.h"
30 #include "mi-out.h"
31 #include "mi-console.h"
32 #include "mi-common.h"
33 #include "observer.h"
34 #include "gdbthread.h"
35 #include "solist.h"
36 #include "gdb.h"
37 #include "objfiles.h"
38 #include "tracepoint.h"
39 #include "cli-out.h"
40 #include "thread-fsm.h"
41 #include "cli/cli-interp.h"
42
43 /* These are the interpreter setup, etc. functions for the MI
44 interpreter. */
45
46 static void mi_execute_command_wrapper (const char *cmd);
47 static void mi_execute_command_input_handler (char *cmd);
48
49 /* These are hooks that we put in place while doing interpreter_exec
50 so we can report interesting things that happened "behind the MI's
51 back" in this command. */
52
53 static int mi_interp_query_hook (const char *ctlstr, va_list ap)
54 ATTRIBUTE_PRINTF (1, 0);
55
56 static void mi_insert_notify_hooks (void);
57 static void mi_remove_notify_hooks (void);
58
59 static void mi_on_signal_received (enum gdb_signal siggnal);
60 static void mi_on_end_stepping_range (void);
61 static void mi_on_signal_exited (enum gdb_signal siggnal);
62 static void mi_on_exited (int exitstatus);
63 static void mi_on_normal_stop (struct bpstats *bs, int print_frame);
64 static void mi_on_no_history (void);
65
66 static void mi_new_thread (struct thread_info *t);
67 static void mi_thread_exit (struct thread_info *t, int silent);
68 static void mi_record_changed (struct inferior*, int, const char *,
69 const char *);
70 static void mi_inferior_added (struct inferior *inf);
71 static void mi_inferior_appeared (struct inferior *inf);
72 static void mi_inferior_exit (struct inferior *inf);
73 static void mi_inferior_removed (struct inferior *inf);
74 static void mi_on_resume (ptid_t ptid);
75 static void mi_solib_loaded (struct so_list *solib);
76 static void mi_solib_unloaded (struct so_list *solib);
77 static void mi_about_to_proceed (void);
78 static void mi_traceframe_changed (int tfnum, int tpnum);
79 static void mi_tsv_created (const struct trace_state_variable *tsv);
80 static void mi_tsv_deleted (const struct trace_state_variable *tsv);
81 static void mi_tsv_modified (const struct trace_state_variable *tsv);
82 static void mi_breakpoint_created (struct breakpoint *b);
83 static void mi_breakpoint_deleted (struct breakpoint *b);
84 static void mi_breakpoint_modified (struct breakpoint *b);
85 static void mi_command_param_changed (const char *param, const char *value);
86 static void mi_memory_changed (struct inferior *inf, CORE_ADDR memaddr,
87 ssize_t len, const bfd_byte *myaddr);
88 static void mi_on_sync_execution_done (void);
89
90 static int report_initial_inferior (struct inferior *inf, void *closure);
91
92 /* Display the MI prompt. */
93
94 static void
95 display_mi_prompt (struct mi_interp *mi)
96 {
97 struct ui *ui = current_ui;
98
99 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
100 gdb_flush (mi->raw_stdout);
101 ui->prompt_state = PROMPTED;
102 }
103
104 /* Returns the INTERP's data cast as mi_interp if INTERP is an MI, and
105 returns NULL otherwise. */
106
107 static struct mi_interp *
108 as_mi_interp (struct interp *interp)
109 {
110 if (ui_out_is_mi_like_p (interp_ui_out (interp)))
111 return (struct mi_interp *) interp_data (interp);
112 return NULL;
113 }
114
115 static void *
116 mi_interpreter_init (struct interp *interp, int top_level)
117 {
118 struct mi_interp *mi = XNEW (struct mi_interp);
119 const char *name;
120 int mi_version;
121
122 /* Store the current output channel, so that we can create a console
123 channel that encapsulates and prefixes all gdb_output-type bits
124 coming from the rest of the debugger. */
125 mi->raw_stdout = gdb_stdout;
126
127 /* Create MI console channels, each with a different prefix so they
128 can be distinguished. */
129 mi->out = mi_console_file_new (mi->raw_stdout, "~", '"');
130 mi->err = mi_console_file_new (mi->raw_stdout, "&", '"');
131 mi->log = mi->err;
132 mi->targ = mi_console_file_new (mi->raw_stdout, "@", '"');
133 mi->event_channel = mi_console_file_new (mi->raw_stdout, "=", 0);
134
135 name = interp_name (interp);
136 /* INTERP_MI selects the most recent released version. "mi2" was
137 released as part of GDB 6.0. */
138 if (strcmp (name, INTERP_MI) == 0)
139 mi_version = 2;
140 else if (strcmp (name, INTERP_MI1) == 0)
141 mi_version = 1;
142 else if (strcmp (name, INTERP_MI2) == 0)
143 mi_version = 2;
144 else if (strcmp (name, INTERP_MI3) == 0)
145 mi_version = 3;
146 else
147 gdb_assert_not_reached ("unhandled MI version");
148
149 mi->mi_uiout = mi_out_new (mi_version);
150 mi->cli_uiout = cli_out_new (mi->out);
151
152 if (top_level)
153 {
154 /* The initial inferior is created before this function is
155 called, so we need to report it explicitly. Use iteration in
156 case future version of GDB creates more than one inferior
157 up-front. */
158 iterate_over_inferiors (report_initial_inferior, mi);
159 }
160
161 return mi;
162 }
163
164 static int
165 mi_interpreter_resume (void *data)
166 {
167 struct mi_interp *mi = (struct mi_interp *) data;
168 struct ui *ui = current_ui;
169
170 /* As per hack note in mi_interpreter_init, swap in the output
171 channels... */
172 gdb_setup_readline (0);
173
174 ui->call_readline = gdb_readline_no_editing_callback;
175 ui->input_handler = mi_execute_command_input_handler;
176
177 gdb_stdout = mi->out;
178 /* Route error and log output through the MI. */
179 gdb_stderr = mi->err;
180 gdb_stdlog = mi->log;
181 /* Route target output through the MI. */
182 gdb_stdtarg = mi->targ;
183 /* Route target error through the MI as well. */
184 gdb_stdtargerr = mi->targ;
185
186 /* Replace all the hooks that we know about. There really needs to
187 be a better way of doing this... */
188 clear_interpreter_hooks ();
189
190 deprecated_show_load_progress = mi_load_progress;
191
192 return 1;
193 }
194
195 static int
196 mi_interpreter_suspend (void *data)
197 {
198 gdb_disable_readline ();
199 return 1;
200 }
201
202 static struct gdb_exception
203 mi_interpreter_exec (void *data, const char *command)
204 {
205 mi_execute_command_wrapper (command);
206 return exception_none;
207 }
208
209 void
210 mi_cmd_interpreter_exec (char *command, char **argv, int argc)
211 {
212 struct interp *interp_to_use;
213 int i;
214 char *mi_error_message = NULL;
215 struct cleanup *old_chain;
216
217 if (argc < 2)
218 error (_("-interpreter-exec: "
219 "Usage: -interpreter-exec interp command"));
220
221 interp_to_use = interp_lookup (current_ui, argv[0]);
222 if (interp_to_use == NULL)
223 error (_("-interpreter-exec: could not find interpreter \"%s\""),
224 argv[0]);
225
226 /* Note that unlike the CLI version of this command, we don't
227 actually set INTERP_TO_USE as the current interpreter, as we
228 still want gdb_stdout, etc. to point at MI streams. */
229
230 /* Insert the MI out hooks, making sure to also call the
231 interpreter's hooks if it has any. */
232 /* KRS: We shouldn't need this... Events should be installed and
233 they should just ALWAYS fire something out down the MI
234 channel. */
235 mi_insert_notify_hooks ();
236
237 /* Now run the code. */
238
239 old_chain = make_cleanup (null_cleanup, 0);
240 for (i = 1; i < argc; i++)
241 {
242 struct gdb_exception e = interp_exec (interp_to_use, argv[i]);
243
244 if (e.reason < 0)
245 {
246 mi_error_message = xstrdup (e.message);
247 make_cleanup (xfree, mi_error_message);
248 break;
249 }
250 }
251
252 mi_remove_notify_hooks ();
253
254 if (mi_error_message != NULL)
255 error ("%s", mi_error_message);
256 do_cleanups (old_chain);
257 }
258
259 /* This inserts a number of hooks that are meant to produce
260 async-notify ("=") MI messages while running commands in another
261 interpreter using mi_interpreter_exec. The canonical use for this
262 is to allow access to the gdb CLI interpreter from within the MI,
263 while still producing MI style output when actions in the CLI
264 command change GDB's state. */
265
266 static void
267 mi_insert_notify_hooks (void)
268 {
269 deprecated_query_hook = mi_interp_query_hook;
270 }
271
272 static void
273 mi_remove_notify_hooks (void)
274 {
275 deprecated_query_hook = NULL;
276 }
277
278 static int
279 mi_interp_query_hook (const char *ctlstr, va_list ap)
280 {
281 return 1;
282 }
283
284 static void
285 mi_execute_command_wrapper (const char *cmd)
286 {
287 struct ui *ui = current_ui;
288
289 mi_execute_command (cmd, ui->instream == ui->stdin_stream);
290 }
291
292 /* Observer for the synchronous_command_done notification. */
293
294 static void
295 mi_on_sync_execution_done (void)
296 {
297 struct ui *ui = current_ui;
298 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
299
300 if (mi == NULL)
301 return;
302
303 /* If MI is sync, then output the MI prompt now, indicating we're
304 ready for further input. */
305 if (!mi_async_p ())
306 display_mi_prompt (mi);
307 }
308
309 /* mi_execute_command_wrapper wrapper suitable for INPUT_HANDLER. */
310
311 static void
312 mi_execute_command_input_handler (char *cmd)
313 {
314 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
315 struct ui *ui = current_ui;
316
317 ui->prompt_state = PROMPT_NEEDED;
318
319 mi_execute_command_wrapper (cmd);
320
321 /* Print a prompt, indicating we're ready for further input, unless
322 we just started a synchronous command. In that case, we're about
323 to go back to the event loop and will output the prompt in the
324 'synchronous_command_done' observer when the target next
325 stops. */
326 if (ui->prompt_state == PROMPT_NEEDED)
327 display_mi_prompt (mi);
328 }
329
330 static void
331 mi_interpreter_pre_command_loop (struct interp *self)
332 {
333 struct mi_interp *mi = (struct mi_interp *) interp_data (self);
334
335 /* Turn off 8 bit strings in quoted output. Any character with the
336 high bit set is printed using C's octal format. */
337 sevenbit_strings = 1;
338
339 /* Tell the world that we're alive. */
340 display_mi_prompt (mi);
341 }
342
343 static void
344 mi_new_thread (struct thread_info *t)
345 {
346 struct inferior *inf = find_inferior_ptid (t->ptid);
347 struct switch_thru_all_uis state;
348
349 gdb_assert (inf);
350
351 SWITCH_THRU_ALL_UIS (state)
352 {
353 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
354 struct cleanup *old_chain;
355
356 if (mi == NULL)
357 continue;
358
359 old_chain = make_cleanup_restore_target_terminal ();
360 target_terminal_ours_for_output ();
361
362 fprintf_unfiltered (mi->event_channel,
363 "thread-created,id=\"%d\",group-id=\"i%d\"",
364 t->global_num, inf->num);
365 gdb_flush (mi->event_channel);
366
367 do_cleanups (old_chain);
368 }
369 }
370
371 static void
372 mi_thread_exit (struct thread_info *t, int silent)
373 {
374 struct switch_thru_all_uis state;
375
376 if (silent)
377 return;
378
379 SWITCH_THRU_ALL_UIS (state)
380 {
381 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
382 struct cleanup *old_chain;
383
384 if (mi == NULL)
385 continue;
386
387 old_chain = make_cleanup_restore_target_terminal ();
388 target_terminal_ours_for_output ();
389 fprintf_unfiltered (mi->event_channel,
390 "thread-exited,id=\"%d\",group-id=\"i%d\"",
391 t->global_num, t->inf->num);
392 gdb_flush (mi->event_channel);
393
394 do_cleanups (old_chain);
395 }
396 }
397
398 /* Emit notification on changing the state of record. */
399
400 static void
401 mi_record_changed (struct inferior *inferior, int started, const char *method,
402 const char *format)
403 {
404 struct switch_thru_all_uis state;
405
406 SWITCH_THRU_ALL_UIS (state)
407 {
408 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
409 struct cleanup *old_chain;
410
411 if (mi == NULL)
412 continue;
413
414 old_chain = make_cleanup_restore_target_terminal ();
415 target_terminal_ours_for_output ();
416
417 if (started)
418 {
419 if (format != NULL)
420 {
421 fprintf_unfiltered (mi->event_channel,
422 "record-started,thread-group=\"i%d\","
423 "method=\"%s\",format=\"%s\"",
424 inferior->num, method, format);
425 }
426 else
427 {
428 fprintf_unfiltered (mi->event_channel,
429 "record-started,thread-group=\"i%d\","
430 "method=\"%s\"",
431 inferior->num, method);
432 }
433 }
434 else
435 {
436 fprintf_unfiltered (mi->event_channel,
437 "record-stopped,thread-group=\"i%d\"",
438 inferior->num);
439 }
440
441 gdb_flush (mi->event_channel);
442
443 do_cleanups (old_chain);
444 }
445 }
446
447 static void
448 mi_inferior_added (struct inferior *inf)
449 {
450 struct switch_thru_all_uis state;
451
452 SWITCH_THRU_ALL_UIS (state)
453 {
454 struct interp *interp;
455 struct mi_interp *mi;
456 struct cleanup *old_chain;
457
458 /* We'll be called once for the initial inferior, before the top
459 level interpreter is set. */
460 interp = top_level_interpreter ();
461 if (interp == NULL)
462 continue;
463
464 mi = as_mi_interp (interp);
465 if (mi == NULL)
466 continue;
467
468 old_chain = make_cleanup_restore_target_terminal ();
469 target_terminal_ours_for_output ();
470
471 fprintf_unfiltered (mi->event_channel,
472 "thread-group-added,id=\"i%d\"",
473 inf->num);
474 gdb_flush (mi->event_channel);
475
476 do_cleanups (old_chain);
477 }
478 }
479
480 static void
481 mi_inferior_appeared (struct inferior *inf)
482 {
483 struct switch_thru_all_uis state;
484
485 SWITCH_THRU_ALL_UIS (state)
486 {
487 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
488 struct cleanup *old_chain;
489
490 if (mi == NULL)
491 continue;
492
493 old_chain = make_cleanup_restore_target_terminal ();
494 target_terminal_ours_for_output ();
495
496 fprintf_unfiltered (mi->event_channel,
497 "thread-group-started,id=\"i%d\",pid=\"%d\"",
498 inf->num, inf->pid);
499 gdb_flush (mi->event_channel);
500 do_cleanups (old_chain);
501 }
502 }
503
504 static void
505 mi_inferior_exit (struct inferior *inf)
506 {
507 struct switch_thru_all_uis state;
508
509 SWITCH_THRU_ALL_UIS (state)
510 {
511 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
512 struct cleanup *old_chain;
513
514 if (mi == NULL)
515 continue;
516
517 old_chain = make_cleanup_restore_target_terminal ();
518 target_terminal_ours_for_output ();
519
520 if (inf->has_exit_code)
521 fprintf_unfiltered (mi->event_channel,
522 "thread-group-exited,id=\"i%d\",exit-code=\"%s\"",
523 inf->num, int_string (inf->exit_code, 8, 0, 0, 1));
524 else
525 fprintf_unfiltered (mi->event_channel,
526 "thread-group-exited,id=\"i%d\"", inf->num);
527
528 gdb_flush (mi->event_channel);
529 do_cleanups (old_chain);
530 }
531 }
532
533 static void
534 mi_inferior_removed (struct inferior *inf)
535 {
536 struct switch_thru_all_uis state;
537
538 SWITCH_THRU_ALL_UIS (state)
539 {
540 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
541 struct cleanup *old_chain;
542
543 if (mi == NULL)
544 continue;
545
546 old_chain = make_cleanup_restore_target_terminal ();
547 target_terminal_ours_for_output ();
548
549 fprintf_unfiltered (mi->event_channel,
550 "thread-group-removed,id=\"i%d\"",
551 inf->num);
552 gdb_flush (mi->event_channel);
553
554 do_cleanups (old_chain);
555 }
556 }
557
558 /* Return the MI interpreter, if it is active -- either because it's
559 the top-level interpreter or the interpreter executing the current
560 command. Returns NULL if the MI interpreter is not being used. */
561
562 static struct mi_interp *
563 find_mi_interp (void)
564 {
565 struct mi_interp *mi;
566
567 mi = as_mi_interp (top_level_interpreter ());
568 if (mi != NULL)
569 return mi;
570
571 mi = as_mi_interp (command_interp ());
572 if (mi != NULL)
573 return mi;
574
575 return NULL;
576 }
577
578 /* Observers for several run control events that print why the
579 inferior has stopped to both the the MI event channel and to the MI
580 console. If the MI interpreter is not active, print nothing. */
581
582 /* Observer for the signal_received notification. */
583
584 static void
585 mi_on_signal_received (enum gdb_signal siggnal)
586 {
587 struct switch_thru_all_uis state;
588
589 SWITCH_THRU_ALL_UIS (state)
590 {
591 struct mi_interp *mi = find_mi_interp ();
592
593 if (mi == NULL)
594 continue;
595
596 print_signal_received_reason (mi->mi_uiout, siggnal);
597 print_signal_received_reason (mi->cli_uiout, siggnal);
598 }
599 }
600
601 /* Observer for the end_stepping_range notification. */
602
603 static void
604 mi_on_end_stepping_range (void)
605 {
606 struct switch_thru_all_uis state;
607
608 SWITCH_THRU_ALL_UIS (state)
609 {
610 struct mi_interp *mi = find_mi_interp ();
611
612 if (mi == NULL)
613 continue;
614
615 print_end_stepping_range_reason (mi->mi_uiout);
616 print_end_stepping_range_reason (mi->cli_uiout);
617 }
618 }
619
620 /* Observer for the signal_exited notification. */
621
622 static void
623 mi_on_signal_exited (enum gdb_signal siggnal)
624 {
625 struct switch_thru_all_uis state;
626
627 SWITCH_THRU_ALL_UIS (state)
628 {
629 struct mi_interp *mi = find_mi_interp ();
630
631 if (mi == NULL)
632 continue;
633
634 print_signal_exited_reason (mi->mi_uiout, siggnal);
635 print_signal_exited_reason (mi->cli_uiout, siggnal);
636 }
637 }
638
639 /* Observer for the exited notification. */
640
641 static void
642 mi_on_exited (int exitstatus)
643 {
644 struct switch_thru_all_uis state;
645
646 SWITCH_THRU_ALL_UIS (state)
647 {
648 struct mi_interp *mi = find_mi_interp ();
649
650 if (mi == NULL)
651 continue;
652
653 print_exited_reason (mi->mi_uiout, exitstatus);
654 print_exited_reason (mi->cli_uiout, exitstatus);
655 }
656 }
657
658 /* Observer for the no_history notification. */
659
660 static void
661 mi_on_no_history (void)
662 {
663 struct switch_thru_all_uis state;
664
665 SWITCH_THRU_ALL_UIS (state)
666 {
667 struct mi_interp *mi = find_mi_interp ();
668
669 if (mi == NULL)
670 continue;
671
672 print_no_history_reason (mi->mi_uiout);
673 print_no_history_reason (mi->cli_uiout);
674 }
675 }
676
677 static void
678 mi_on_normal_stop_1 (struct bpstats *bs, int print_frame)
679 {
680 /* Since this can be called when CLI command is executing,
681 using cli interpreter, be sure to use MI uiout for output,
682 not the current one. */
683 struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ());
684 struct mi_interp *mi = (struct mi_interp *) top_level_interpreter_data ();
685
686 if (print_frame)
687 {
688 struct thread_info *tp;
689 int core;
690 struct interp *console_interp;
691
692 tp = inferior_thread ();
693
694 if (tp->thread_fsm != NULL
695 && thread_fsm_finished_p (tp->thread_fsm))
696 {
697 enum async_reply_reason reason;
698
699 reason = thread_fsm_async_reply_reason (tp->thread_fsm);
700 ui_out_field_string (mi_uiout, "reason",
701 async_reason_lookup (reason));
702 }
703 print_stop_event (mi_uiout);
704
705 console_interp = interp_lookup (current_ui, INTERP_CONSOLE);
706 if (should_print_stop_to_console (console_interp, tp))
707 print_stop_event (mi->cli_uiout);
708
709 ui_out_field_int (mi_uiout, "thread-id", tp->global_num);
710 if (non_stop)
711 {
712 struct cleanup *back_to = make_cleanup_ui_out_list_begin_end
713 (mi_uiout, "stopped-threads");
714
715 ui_out_field_int (mi_uiout, NULL, tp->global_num);
716 do_cleanups (back_to);
717 }
718 else
719 ui_out_field_string (mi_uiout, "stopped-threads", "all");
720
721 core = target_core_of_thread (inferior_ptid);
722 if (core != -1)
723 ui_out_field_int (mi_uiout, "core", core);
724 }
725
726 fputs_unfiltered ("*stopped", mi->raw_stdout);
727 mi_out_put (mi_uiout, mi->raw_stdout);
728 mi_out_rewind (mi_uiout);
729 mi_print_timing_maybe (mi->raw_stdout);
730 fputs_unfiltered ("\n", mi->raw_stdout);
731 gdb_flush (mi->raw_stdout);
732 }
733
734 static void
735 mi_on_normal_stop (struct bpstats *bs, int print_frame)
736 {
737 struct switch_thru_all_uis state;
738
739 SWITCH_THRU_ALL_UIS (state)
740 {
741 if (as_mi_interp (top_level_interpreter ()) == NULL)
742 continue;
743
744 mi_on_normal_stop_1 (bs, print_frame);
745 }
746 }
747
748 static void
749 mi_about_to_proceed (void)
750 {
751 /* Suppress output while calling an inferior function. */
752
753 if (!ptid_equal (inferior_ptid, null_ptid))
754 {
755 struct thread_info *tp = inferior_thread ();
756
757 if (tp->control.in_infcall)
758 return;
759 }
760
761 mi_proceeded = 1;
762 }
763
764 /* When the element is non-zero, no MI notifications will be emitted in
765 response to the corresponding observers. */
766
767 struct mi_suppress_notification mi_suppress_notification =
768 {
769 0,
770 0,
771 0,
772 0,
773 };
774
775 /* Emit notification on changing a traceframe. */
776
777 static void
778 mi_traceframe_changed (int tfnum, int tpnum)
779 {
780 struct switch_thru_all_uis state;
781
782 if (mi_suppress_notification.traceframe)
783 return;
784
785 SWITCH_THRU_ALL_UIS (state)
786 {
787 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
788 struct cleanup *old_chain;
789
790 if (mi == NULL)
791 continue;
792
793 old_chain = make_cleanup_restore_target_terminal ();
794 target_terminal_ours_for_output ();
795
796 if (tfnum >= 0)
797 fprintf_unfiltered (mi->event_channel, "traceframe-changed,"
798 "num=\"%d\",tracepoint=\"%d\"\n",
799 tfnum, tpnum);
800 else
801 fprintf_unfiltered (mi->event_channel, "traceframe-changed,end");
802
803 gdb_flush (mi->event_channel);
804
805 do_cleanups (old_chain);
806 }
807 }
808
809 /* Emit notification on creating a trace state variable. */
810
811 static void
812 mi_tsv_created (const struct trace_state_variable *tsv)
813 {
814 struct switch_thru_all_uis state;
815
816 SWITCH_THRU_ALL_UIS (state)
817 {
818 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
819 struct cleanup *old_chain;
820
821 if (mi == NULL)
822 continue;
823
824 old_chain = make_cleanup_restore_target_terminal ();
825 target_terminal_ours_for_output ();
826
827 fprintf_unfiltered (mi->event_channel, "tsv-created,"
828 "name=\"%s\",initial=\"%s\"\n",
829 tsv->name, plongest (tsv->initial_value));
830
831 gdb_flush (mi->event_channel);
832
833 do_cleanups (old_chain);
834 }
835 }
836
837 /* Emit notification on deleting a trace state variable. */
838
839 static void
840 mi_tsv_deleted (const struct trace_state_variable *tsv)
841 {
842 struct switch_thru_all_uis state;
843
844 SWITCH_THRU_ALL_UIS (state)
845 {
846 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
847 struct cleanup *old_chain;
848
849 if (mi == NULL)
850 continue;
851
852 old_chain = make_cleanup_restore_target_terminal ();
853 target_terminal_ours_for_output ();
854
855 if (tsv != NULL)
856 fprintf_unfiltered (mi->event_channel, "tsv-deleted,"
857 "name=\"%s\"\n", tsv->name);
858 else
859 fprintf_unfiltered (mi->event_channel, "tsv-deleted\n");
860
861 gdb_flush (mi->event_channel);
862
863 do_cleanups (old_chain);
864 }
865 }
866
867 /* Emit notification on modifying a trace state variable. */
868
869 static void
870 mi_tsv_modified (const struct trace_state_variable *tsv)
871 {
872 struct switch_thru_all_uis state;
873
874 SWITCH_THRU_ALL_UIS (state)
875 {
876 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
877 struct ui_out *mi_uiout;
878 struct cleanup *old_chain;
879
880 if (mi == NULL)
881 continue;
882
883 mi_uiout = interp_ui_out (top_level_interpreter ());
884
885 old_chain = make_cleanup_restore_target_terminal ();
886 target_terminal_ours_for_output ();
887
888 fprintf_unfiltered (mi->event_channel,
889 "tsv-modified");
890
891 ui_out_redirect (mi_uiout, mi->event_channel);
892
893 ui_out_field_string (mi_uiout, "name", tsv->name);
894 ui_out_field_string (mi_uiout, "initial",
895 plongest (tsv->initial_value));
896 if (tsv->value_known)
897 ui_out_field_string (mi_uiout, "current", plongest (tsv->value));
898
899 ui_out_redirect (mi_uiout, NULL);
900
901 gdb_flush (mi->event_channel);
902
903 do_cleanups (old_chain);
904 }
905 }
906
907 /* Emit notification about a created breakpoint. */
908
909 static void
910 mi_breakpoint_created (struct breakpoint *b)
911 {
912 struct switch_thru_all_uis state;
913
914 if (mi_suppress_notification.breakpoint)
915 return;
916
917 if (b->number <= 0)
918 return;
919
920 SWITCH_THRU_ALL_UIS (state)
921 {
922 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
923 struct ui_out *mi_uiout;
924 struct cleanup *old_chain;
925
926 if (mi == NULL)
927 continue;
928
929 mi_uiout = interp_ui_out (top_level_interpreter ());
930
931 old_chain = make_cleanup_restore_target_terminal ();
932 target_terminal_ours_for_output ();
933
934 fprintf_unfiltered (mi->event_channel,
935 "breakpoint-created");
936 /* We want the output from gdb_breakpoint_query to go to
937 mi->event_channel. One approach would be to just call
938 gdb_breakpoint_query, and then use mi_out_put to send the current
939 content of mi_outout into mi->event_channel. However, that will
940 break if anything is output to mi_uiout prior to calling the
941 breakpoint_created notifications. So, we use
942 ui_out_redirect. */
943 ui_out_redirect (mi_uiout, mi->event_channel);
944 TRY
945 {
946 gdb_breakpoint_query (mi_uiout, b->number, NULL);
947 }
948 CATCH (e, RETURN_MASK_ERROR)
949 {
950 }
951 END_CATCH
952
953 ui_out_redirect (mi_uiout, NULL);
954
955 gdb_flush (mi->event_channel);
956
957 do_cleanups (old_chain);
958 }
959 }
960
961 /* Emit notification about deleted breakpoint. */
962
963 static void
964 mi_breakpoint_deleted (struct breakpoint *b)
965 {
966 struct switch_thru_all_uis state;
967
968 if (mi_suppress_notification.breakpoint)
969 return;
970
971 if (b->number <= 0)
972 return;
973
974 SWITCH_THRU_ALL_UIS (state)
975 {
976 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
977 struct cleanup *old_chain;
978
979 if (mi == NULL)
980 continue;
981
982 old_chain = make_cleanup_restore_target_terminal ();
983 target_terminal_ours_for_output ();
984
985 fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"",
986 b->number);
987
988 gdb_flush (mi->event_channel);
989
990 do_cleanups (old_chain);
991 }
992 }
993
994 /* Emit notification about modified breakpoint. */
995
996 static void
997 mi_breakpoint_modified (struct breakpoint *b)
998 {
999 struct switch_thru_all_uis state;
1000
1001 if (mi_suppress_notification.breakpoint)
1002 return;
1003
1004 if (b->number <= 0)
1005 return;
1006
1007 SWITCH_THRU_ALL_UIS (state)
1008 {
1009 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1010 struct cleanup *old_chain;
1011
1012 if (mi == NULL)
1013 continue;
1014
1015 old_chain = make_cleanup_restore_target_terminal ();
1016 target_terminal_ours_for_output ();
1017 fprintf_unfiltered (mi->event_channel,
1018 "breakpoint-modified");
1019 /* We want the output from gdb_breakpoint_query to go to
1020 mi->event_channel. One approach would be to just call
1021 gdb_breakpoint_query, and then use mi_out_put to send the current
1022 content of mi_outout into mi->event_channel. However, that will
1023 break if anything is output to mi_uiout prior to calling the
1024 breakpoint_created notifications. So, we use
1025 ui_out_redirect. */
1026 ui_out_redirect (mi->mi_uiout, mi->event_channel);
1027 TRY
1028 {
1029 gdb_breakpoint_query (mi->mi_uiout, b->number, NULL);
1030 }
1031 CATCH (e, RETURN_MASK_ERROR)
1032 {
1033 }
1034 END_CATCH
1035
1036 ui_out_redirect (mi->mi_uiout, NULL);
1037
1038 gdb_flush (mi->event_channel);
1039
1040 do_cleanups (old_chain);
1041 }
1042 }
1043
1044 static int
1045 mi_output_running_pid (struct thread_info *info, void *arg)
1046 {
1047 ptid_t *ptid = (ptid_t *) arg;
1048 struct switch_thru_all_uis state;
1049
1050 SWITCH_THRU_ALL_UIS (state)
1051 {
1052 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1053
1054 if (mi == NULL)
1055 continue;
1056
1057 if (ptid_get_pid (*ptid) == ptid_get_pid (info->ptid))
1058 fprintf_unfiltered (mi->raw_stdout,
1059 "*running,thread-id=\"%d\"\n",
1060 info->global_num);
1061 }
1062
1063 return 0;
1064 }
1065
1066 static int
1067 mi_inferior_count (struct inferior *inf, void *arg)
1068 {
1069 if (inf->pid != 0)
1070 {
1071 int *count_p = (int *) arg;
1072 (*count_p)++;
1073 }
1074
1075 return 0;
1076 }
1077
1078 static void
1079 mi_on_resume_1 (struct mi_interp *mi, ptid_t ptid)
1080 {
1081 /* To cater for older frontends, emit ^running, but do it only once
1082 per each command. We do it here, since at this point we know
1083 that the target was successfully resumed, and in non-async mode,
1084 we won't return back to MI interpreter code until the target
1085 is done running, so delaying the output of "^running" until then
1086 will make it impossible for frontend to know what's going on.
1087
1088 In future (MI3), we'll be outputting "^done" here. */
1089 if (!running_result_record_printed && mi_proceeded)
1090 {
1091 fprintf_unfiltered (mi->raw_stdout, "%s^running\n",
1092 current_token ? current_token : "");
1093 }
1094
1095 if (ptid_get_pid (ptid) == -1)
1096 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
1097 else if (ptid_is_pid (ptid))
1098 {
1099 int count = 0;
1100
1101 /* Backwards compatibility. If there's only one inferior,
1102 output "all", otherwise, output each resumed thread
1103 individually. */
1104 iterate_over_inferiors (mi_inferior_count, &count);
1105
1106 if (count == 1)
1107 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"all\"\n");
1108 else
1109 iterate_over_threads (mi_output_running_pid, &ptid);
1110 }
1111 else
1112 {
1113 struct thread_info *ti = find_thread_ptid (ptid);
1114
1115 gdb_assert (ti);
1116 fprintf_unfiltered (mi->raw_stdout, "*running,thread-id=\"%d\"\n",
1117 ti->global_num);
1118 }
1119
1120 if (!running_result_record_printed && mi_proceeded)
1121 {
1122 running_result_record_printed = 1;
1123 /* This is what gdb used to do historically -- printing prompt
1124 even if it cannot actually accept any input. This will be
1125 surely removed for MI3, and may be removed even earlier. */
1126 if (current_ui->prompt_state == PROMPT_BLOCKED)
1127 fputs_unfiltered ("(gdb) \n", mi->raw_stdout);
1128 }
1129 gdb_flush (mi->raw_stdout);
1130 }
1131
1132 static void
1133 mi_on_resume (ptid_t ptid)
1134 {
1135 struct thread_info *tp = NULL;
1136 struct switch_thru_all_uis state;
1137
1138 if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
1139 tp = inferior_thread ();
1140 else
1141 tp = find_thread_ptid (ptid);
1142
1143 /* Suppress output while calling an inferior function. */
1144 if (tp->control.in_infcall)
1145 return;
1146
1147 SWITCH_THRU_ALL_UIS (state)
1148 {
1149 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1150 struct cleanup *old_chain;
1151
1152 if (mi == NULL)
1153 continue;
1154
1155 old_chain = make_cleanup_restore_target_terminal ();
1156 target_terminal_ours_for_output ();
1157
1158 mi_on_resume_1 (mi, ptid);
1159
1160 do_cleanups (old_chain);
1161 }
1162 }
1163
1164 static void
1165 mi_solib_loaded (struct so_list *solib)
1166 {
1167 struct switch_thru_all_uis state;
1168
1169 SWITCH_THRU_ALL_UIS (state)
1170 {
1171 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1172 struct ui_out *uiout;
1173 struct cleanup *old_chain;
1174
1175 if (mi == NULL)
1176 continue;
1177
1178 uiout = interp_ui_out (top_level_interpreter ());
1179
1180 old_chain = make_cleanup_restore_target_terminal ();
1181 target_terminal_ours_for_output ();
1182
1183 fprintf_unfiltered (mi->event_channel, "library-loaded");
1184
1185 ui_out_redirect (uiout, mi->event_channel);
1186
1187 ui_out_field_string (uiout, "id", solib->so_original_name);
1188 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1189 ui_out_field_string (uiout, "host-name", solib->so_name);
1190 ui_out_field_int (uiout, "symbols-loaded", solib->symbols_loaded);
1191 if (!gdbarch_has_global_solist (target_gdbarch ()))
1192 {
1193 ui_out_field_fmt (uiout, "thread-group", "i%d",
1194 current_inferior ()->num);
1195 }
1196
1197 ui_out_redirect (uiout, NULL);
1198
1199 gdb_flush (mi->event_channel);
1200
1201 do_cleanups (old_chain);
1202 }
1203 }
1204
1205 static void
1206 mi_solib_unloaded (struct so_list *solib)
1207 {
1208 struct switch_thru_all_uis state;
1209
1210 SWITCH_THRU_ALL_UIS (state)
1211 {
1212 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1213 struct ui_out *uiout;
1214 struct cleanup *old_chain;
1215
1216 if (mi == NULL)
1217 continue;
1218
1219 uiout = interp_ui_out (top_level_interpreter ());
1220
1221 old_chain = make_cleanup_restore_target_terminal ();
1222 target_terminal_ours_for_output ();
1223
1224 fprintf_unfiltered (mi->event_channel, "library-unloaded");
1225
1226 ui_out_redirect (uiout, mi->event_channel);
1227
1228 ui_out_field_string (uiout, "id", solib->so_original_name);
1229 ui_out_field_string (uiout, "target-name", solib->so_original_name);
1230 ui_out_field_string (uiout, "host-name", solib->so_name);
1231 if (!gdbarch_has_global_solist (target_gdbarch ()))
1232 {
1233 ui_out_field_fmt (uiout, "thread-group", "i%d",
1234 current_inferior ()->num);
1235 }
1236
1237 ui_out_redirect (uiout, NULL);
1238
1239 gdb_flush (mi->event_channel);
1240
1241 do_cleanups (old_chain);
1242 }
1243 }
1244
1245 /* Emit notification about the command parameter change. */
1246
1247 static void
1248 mi_command_param_changed (const char *param, const char *value)
1249 {
1250 struct switch_thru_all_uis state;
1251
1252 if (mi_suppress_notification.cmd_param_changed)
1253 return;
1254
1255 SWITCH_THRU_ALL_UIS (state)
1256 {
1257 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1258 struct ui_out *mi_uiout;
1259 struct cleanup *old_chain;
1260
1261 if (mi == NULL)
1262 continue;
1263
1264 mi_uiout = interp_ui_out (top_level_interpreter ());
1265
1266 old_chain = make_cleanup_restore_target_terminal ();
1267 target_terminal_ours_for_output ();
1268
1269 fprintf_unfiltered (mi->event_channel, "cmd-param-changed");
1270
1271 ui_out_redirect (mi_uiout, mi->event_channel);
1272
1273 ui_out_field_string (mi_uiout, "param", param);
1274 ui_out_field_string (mi_uiout, "value", value);
1275
1276 ui_out_redirect (mi_uiout, NULL);
1277
1278 gdb_flush (mi->event_channel);
1279
1280 do_cleanups (old_chain);
1281 }
1282 }
1283
1284 /* Emit notification about the target memory change. */
1285
1286 static void
1287 mi_memory_changed (struct inferior *inferior, CORE_ADDR memaddr,
1288 ssize_t len, const bfd_byte *myaddr)
1289 {
1290 struct switch_thru_all_uis state;
1291
1292 if (mi_suppress_notification.memory)
1293 return;
1294
1295 SWITCH_THRU_ALL_UIS (state)
1296 {
1297 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1298 struct ui_out *mi_uiout;
1299 struct obj_section *sec;
1300 struct cleanup *old_chain;
1301
1302 if (mi == NULL)
1303 continue;
1304
1305 mi_uiout = interp_ui_out (top_level_interpreter ());
1306
1307 old_chain = make_cleanup_restore_target_terminal ();
1308 target_terminal_ours_for_output ();
1309
1310 fprintf_unfiltered (mi->event_channel, "memory-changed");
1311
1312 ui_out_redirect (mi_uiout, mi->event_channel);
1313
1314 ui_out_field_fmt (mi_uiout, "thread-group", "i%d", inferior->num);
1315 ui_out_field_core_addr (mi_uiout, "addr", target_gdbarch (), memaddr);
1316 ui_out_field_fmt (mi_uiout, "len", "%s", hex_string (len));
1317
1318 /* Append 'type=code' into notification if MEMADDR falls in the range of
1319 sections contain code. */
1320 sec = find_pc_section (memaddr);
1321 if (sec != NULL && sec->objfile != NULL)
1322 {
1323 flagword flags = bfd_get_section_flags (sec->objfile->obfd,
1324 sec->the_bfd_section);
1325
1326 if (flags & SEC_CODE)
1327 ui_out_field_string (mi_uiout, "type", "code");
1328 }
1329
1330 ui_out_redirect (mi_uiout, NULL);
1331
1332 gdb_flush (mi->event_channel);
1333
1334 do_cleanups (old_chain);
1335 }
1336 }
1337
1338 /* Emit an event when the selection context (inferior, thread, frame)
1339 changed. */
1340
1341 static void
1342 mi_user_selected_context_changed (user_selected_what selection)
1343 {
1344 struct switch_thru_all_uis state;
1345 struct thread_info *tp;
1346
1347 /* Don't send an event if we're responding to an MI command. */
1348 if (mi_suppress_notification.user_selected_context)
1349 return;
1350
1351 tp = find_thread_ptid (inferior_ptid);
1352
1353 SWITCH_THRU_ALL_UIS (state)
1354 {
1355 struct mi_interp *mi = as_mi_interp (top_level_interpreter ());
1356 struct ui_out *mi_uiout;
1357 struct cleanup *old_chain;
1358
1359 if (mi == NULL)
1360 continue;
1361
1362 mi_uiout = interp_ui_out (top_level_interpreter ());
1363
1364 ui_out_redirect (mi_uiout, mi->event_channel);
1365
1366 old_chain = make_cleanup_ui_out_redirect_pop (mi_uiout);
1367
1368 make_cleanup_restore_target_terminal ();
1369 target_terminal_ours_for_output ();
1370
1371 if (selection & USER_SELECTED_INFERIOR)
1372 print_selected_inferior (mi->cli_uiout);
1373
1374 if (tp != NULL
1375 && (selection & (USER_SELECTED_THREAD | USER_SELECTED_FRAME)))
1376 {
1377 print_selected_thread_frame (mi->cli_uiout, selection);
1378
1379 fprintf_unfiltered (mi->event_channel,
1380 "thread-selected,id=\"%d\"",
1381 tp->global_num);
1382
1383 if (tp->state != THREAD_RUNNING)
1384 {
1385 if (has_stack_frames ())
1386 print_stack_frame_to_uiout (mi_uiout, get_selected_frame (NULL),
1387 1, SRC_AND_LOC, 1);
1388 }
1389 }
1390
1391 gdb_flush (mi->event_channel);
1392 do_cleanups (old_chain);
1393 }
1394 }
1395
1396 static int
1397 report_initial_inferior (struct inferior *inf, void *closure)
1398 {
1399 /* This function is called from mi_interpreter_init, and since
1400 mi_inferior_added assumes that inferior is fully initialized
1401 and top_level_interpreter_data is set, we cannot call
1402 it here. */
1403 struct mi_interp *mi = (struct mi_interp *) closure;
1404 struct cleanup *old_chain;
1405
1406 old_chain = make_cleanup_restore_target_terminal ();
1407 target_terminal_ours_for_output ();
1408
1409 fprintf_unfiltered (mi->event_channel,
1410 "thread-group-added,id=\"i%d\"",
1411 inf->num);
1412 gdb_flush (mi->event_channel);
1413
1414 do_cleanups (old_chain);
1415 return 0;
1416 }
1417
1418 static struct ui_out *
1419 mi_ui_out (struct interp *interp)
1420 {
1421 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
1422
1423 return mi->mi_uiout;
1424 }
1425
1426 /* Do MI-specific logging actions; save raw_stdout, and change all
1427 the consoles to use the supplied ui-file(s). */
1428
1429 static int
1430 mi_set_logging (struct interp *interp, int start_log,
1431 struct ui_file *out, struct ui_file *logfile)
1432 {
1433 struct mi_interp *mi = (struct mi_interp *) interp_data (interp);
1434
1435 if (!mi)
1436 return 0;
1437
1438 if (start_log)
1439 {
1440 /* The tee created already is based on gdb_stdout, which for MI
1441 is a console and so we end up in an infinite loop of console
1442 writing to ui_file writing to console etc. So discard the
1443 existing tee (it hasn't been used yet, and MI won't ever use
1444 it), and create one based on raw_stdout instead. */
1445 if (logfile)
1446 {
1447 ui_file_delete (out);
1448 out = tee_file_new (mi->raw_stdout, 0, logfile, 0);
1449 }
1450
1451 mi->saved_raw_stdout = mi->raw_stdout;
1452 mi->raw_stdout = out;
1453 }
1454 else
1455 {
1456 mi->raw_stdout = mi->saved_raw_stdout;
1457 mi->saved_raw_stdout = NULL;
1458 }
1459
1460 mi_console_set_raw (mi->out, mi->raw_stdout);
1461 mi_console_set_raw (mi->err, mi->raw_stdout);
1462 mi_console_set_raw (mi->log, mi->raw_stdout);
1463 mi_console_set_raw (mi->targ, mi->raw_stdout);
1464 mi_console_set_raw (mi->event_channel, mi->raw_stdout);
1465
1466 return 1;
1467 }
1468
1469 /* The MI interpreter's vtable. */
1470
1471 static const struct interp_procs mi_interp_procs =
1472 {
1473 mi_interpreter_init, /* init_proc */
1474 mi_interpreter_resume, /* resume_proc */
1475 mi_interpreter_suspend, /* suspend_proc */
1476 mi_interpreter_exec, /* exec_proc */
1477 mi_ui_out, /* ui_out_proc */
1478 mi_set_logging, /* set_logging_proc */
1479 mi_interpreter_pre_command_loop /* pre_command_loop_proc */
1480 };
1481
1482 /* Factory for MI interpreters. */
1483
1484 static struct interp *
1485 mi_interp_factory (const char *name)
1486 {
1487 return interp_new (name, &mi_interp_procs, NULL);
1488 }
1489
1490 extern initialize_file_ftype _initialize_mi_interp; /* -Wmissing-prototypes */
1491
1492 void
1493 _initialize_mi_interp (void)
1494 {
1495 /* The various interpreter levels. */
1496 interp_factory_register (INTERP_MI1, mi_interp_factory);
1497 interp_factory_register (INTERP_MI2, mi_interp_factory);
1498 interp_factory_register (INTERP_MI3, mi_interp_factory);
1499 interp_factory_register (INTERP_MI, mi_interp_factory);
1500
1501 observer_attach_signal_received (mi_on_signal_received);
1502 observer_attach_end_stepping_range (mi_on_end_stepping_range);
1503 observer_attach_signal_exited (mi_on_signal_exited);
1504 observer_attach_exited (mi_on_exited);
1505 observer_attach_no_history (mi_on_no_history);
1506 observer_attach_new_thread (mi_new_thread);
1507 observer_attach_thread_exit (mi_thread_exit);
1508 observer_attach_inferior_added (mi_inferior_added);
1509 observer_attach_inferior_appeared (mi_inferior_appeared);
1510 observer_attach_inferior_exit (mi_inferior_exit);
1511 observer_attach_inferior_removed (mi_inferior_removed);
1512 observer_attach_record_changed (mi_record_changed);
1513 observer_attach_normal_stop (mi_on_normal_stop);
1514 observer_attach_target_resumed (mi_on_resume);
1515 observer_attach_solib_loaded (mi_solib_loaded);
1516 observer_attach_solib_unloaded (mi_solib_unloaded);
1517 observer_attach_about_to_proceed (mi_about_to_proceed);
1518 observer_attach_traceframe_changed (mi_traceframe_changed);
1519 observer_attach_tsv_created (mi_tsv_created);
1520 observer_attach_tsv_deleted (mi_tsv_deleted);
1521 observer_attach_tsv_modified (mi_tsv_modified);
1522 observer_attach_breakpoint_created (mi_breakpoint_created);
1523 observer_attach_breakpoint_deleted (mi_breakpoint_deleted);
1524 observer_attach_breakpoint_modified (mi_breakpoint_modified);
1525 observer_attach_command_param_changed (mi_command_param_changed);
1526 observer_attach_memory_changed (mi_memory_changed);
1527 observer_attach_sync_execution_done (mi_on_sync_execution_done);
1528 observer_attach_user_selected_context_changed
1529 (mi_user_selected_context_changed);
1530 }
This page took 0.062742 seconds and 4 git commands to generate.