diff options
Diffstat (limited to 'gdb/mi/mi-interp.c')
-rw-r--r-- | gdb/mi/mi-interp.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/gdb/mi/mi-interp.c b/gdb/mi/mi-interp.c index 23c60f6..c075b0c 100644 --- a/gdb/mi/mi-interp.c +++ b/gdb/mi/mi-interp.c @@ -35,6 +35,7 @@ #include "observer.h" #include "gdbthread.h" #include "solist.h" +#include "gdb.h" /* These are the interpreter setup, etc. functions for the MI interpreter */ static void mi_execute_command_wrapper (char *cmd); @@ -64,6 +65,9 @@ static void mi_on_resume (ptid_t ptid); static void mi_solib_loaded (struct so_list *solib); static void mi_solib_unloaded (struct so_list *solib); static void mi_about_to_proceed (void); +static void mi_breakpoint_created (struct breakpoint *b); +static void mi_breakpoint_deleted (struct breakpoint *b); +static void mi_breakpoint_modified (struct breakpoint *b); static int report_initial_inferior (struct inferior *inf, void *closure); @@ -99,6 +103,9 @@ mi_interpreter_init (int top_level) observer_attach_solib_loaded (mi_solib_loaded); observer_attach_solib_unloaded (mi_solib_unloaded); observer_attach_about_to_proceed (mi_about_to_proceed); + observer_attach_breakpoint_created (mi_breakpoint_created); + observer_attach_breakpoint_deleted (mi_breakpoint_deleted); + observer_attach_breakpoint_modified (mi_breakpoint_modified); /* The initial inferior is created before this function is called, so we need to report it explicitly. Use iteration in case future version @@ -445,6 +452,95 @@ mi_about_to_proceed (void) mi_proceeded = 1; } +/* When non-zero, no MI notifications will be emitted in + response to breakpoint change observers. */ +int mi_suppress_breakpoint_notifications = 0; + +/* Emit notification about a created breakpoint. */ +static void +mi_breakpoint_created (struct breakpoint *b) +{ + struct mi_interp *mi = top_level_interpreter_data (); + struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); + struct gdb_exception e; + + if (mi_suppress_breakpoint_notifications) + return; + + if (b->number <= 0) + return; + + target_terminal_ours (); + fprintf_unfiltered (mi->event_channel, + "breakpoint-created"); + /* We want the output from gdb_breakpoint_query to go to + mi->event_channel. One approach would be to just + call gdb_breakpoint_query, and then use mi_out_put to + send the current content of mi_outout into mi->event_channel. + However, that will break if anything is output to mi_uiout + prior the calling the breakpoint_created notifications. + So, we use ui_out_redirect. */ + ui_out_redirect (mi_uiout, mi->event_channel); + TRY_CATCH (e, RETURN_MASK_ERROR) + gdb_breakpoint_query (mi_uiout, b->number, NULL); + ui_out_redirect (mi_uiout, NULL); + + gdb_flush (mi->event_channel); +} + +/* Emit notification about deleted breakpoint. */ +static void +mi_breakpoint_deleted (struct breakpoint *b) +{ + struct mi_interp *mi = top_level_interpreter_data (); + + if (mi_suppress_breakpoint_notifications) + return; + + if (b->number <= 0) + return; + + target_terminal_ours (); + + fprintf_unfiltered (mi->event_channel, "breakpoint-deleted,id=\"%d\"", + b->number); + + gdb_flush (mi->event_channel); +} + +/* Emit notification about modified breakpoint. */ +static void +mi_breakpoint_modified (struct breakpoint *b) +{ + struct mi_interp *mi = top_level_interpreter_data (); + struct ui_out *mi_uiout = interp_ui_out (top_level_interpreter ()); + struct gdb_exception e; + + if (mi_suppress_breakpoint_notifications) + return; + + if (b->number <= 0) + return; + + target_terminal_ours (); + fprintf_unfiltered (mi->event_channel, + "breakpoint-modified"); + /* We want the output from gdb_breakpoint_query to go to + mi->event_channel. One approach would be to just + call gdb_breakpoint_query, and then use mi_out_put to + send the current content of mi_outout into mi->event_channel. + However, that will break if anything is output to mi_uiout + prior the calling the breakpoint_created notifications. + So, we use ui_out_redirect. */ + ui_out_redirect (mi_uiout, mi->event_channel); + TRY_CATCH (e, RETURN_MASK_ERROR) + gdb_breakpoint_query (mi_uiout, b->number, NULL); + ui_out_redirect (mi_uiout, NULL); + + gdb_flush (mi->event_channel); +} + + static int mi_output_running_pid (struct thread_info *info, void *arg) { |