From 91985142973d550628c61d201e0a7cd3e36cd5b3 Mon Sep 17 00:00:00 2001 From: Mircea Gherzan Date: Wed, 12 Dec 2012 21:20:13 +0000 Subject: [PATCH] MI: add the -catch-load and -catch-unload commands They are equivalent to "catch load" and "catch unload" from CLI. Rationale: GUIs might be interested in catching solib load or unload events. 2012-11-16 Mircea Gherzan * Makefile.in (SUBDIR_MI_OBS): Add mi-cmd-catch.o. (SUBDIR_MI_SRCS): Add mi/mi-cmd-catch.c. * breakpoint.c (add_solib_catchpoint): New function that can be used by both CLI and MI, factored out from catch_load_or_unload. (catch_load_or_unload): Strip it down and make it use the new add_solib_catchpoint. * breakpoint.h (add_solib_catchpoint): Declare it. * mi/mi-cmd-break.h: New file. * mi/mi-cmd-break.c: Include mi-cmd-break.h. (setup_breakpoint_reporting): New function used for both catchpoints and breakpoints. (mi_cmd_break_insert): Use setup_breakpoint_reporting. * mi/mi-cmd-catch.c: New file. * mi/mi-cmds.c (mi_cmds): Add the handlers for -catch-load and -catch-unload. * mi/mi-cmds.h: Declare the handlers for -catch-load and -catch-unload. --- gdb/ChangeLog | 21 +++++++++ gdb/Makefile.in | 9 +++- gdb/breakpoint.c | 35 +++++++++++---- gdb/breakpoint.h | 5 +++ gdb/mi/mi-cmd-break.c | 34 ++++++++++---- gdb/mi/mi-cmd-break.h | 30 +++++++++++++ gdb/mi/mi-cmd-catch.c | 102 ++++++++++++++++++++++++++++++++++++++++++ gdb/mi/mi-cmds.c | 4 ++ gdb/mi/mi-cmds.h | 2 + 9 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 gdb/mi/mi-cmd-break.h create mode 100644 gdb/mi/mi-cmd-catch.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b8044cc70b..a3bcbeb69d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,24 @@ +2012-12-12 Mircea Gherzan + + * Makefile.in (SUBDIR_MI_OBS): Add mi-cmd-catch.o. + (SUBDIR_MI_SRCS): Add mi/mi-cmd-catch.c. + * breakpoint.c (add_solib_catchpoint): New function that + can be used by both CLI and MI, factored out from + catch_load_or_unload. + (catch_load_or_unload): Strip it down and make it use the + new add_solib_catchpoint. + * breakpoint.h (add_solib_catchpoint): Declare it. + * mi/mi-cmd-break.h: New file. + * mi/mi-cmd-break.c: Include mi-cmd-break.h. + (setup_breakpoint_reporting): New function used for both + catchpoints and breakpoints. + (mi_cmd_break_insert): Use setup_breakpoint_reporting. + * mi/mi-cmd-catch.c: New file. + * mi/mi-cmds.c (mi_cmds): Add the handlers for -catch-load + and -catch-unload. + * mi/mi-cmds.h: Declare the handlers for -catch-load and + -catch-unload. + 2012-11-28 Tom Tromey * dbxread.c (read_dbx_symtab): Update. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 9f6f3a9b59..22f2acbaa9 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -203,13 +203,14 @@ SUBDIR_CLI_CFLAGS= # SUBDIR_MI_OBS = \ mi-out.o mi-console.o \ - mi-cmds.o mi-cmd-env.o mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \ + mi-cmds.o mi-cmd-catch.o mi-cmd-env.o \ + mi-cmd-var.o mi-cmd-break.o mi-cmd-stack.o \ mi-cmd-file.o mi-cmd-disas.o mi-symbol-cmds.o mi-cmd-target.o \ mi-cmd-info.o mi-interp.o \ mi-main.o mi-parse.o mi-getopt.o SUBDIR_MI_SRCS = \ mi/mi-out.c mi/mi-console.c \ - mi/mi-cmds.c mi/mi-cmd-env.c \ + mi/mi-cmds.c mi/mi-cmd-catch.c mi/mi-cmd-env.c \ mi/mi-cmd-var.c mi/mi-cmd-break.c mi/mi-cmd-stack.c \ mi/mi-cmd-file.c mi/mi-cmd-disas.c mi/mi-symbol-cmds.c \ mi/mi-cmd-target.c mi/mi-cmd-info.c mi/mi-interp.c \ @@ -1825,6 +1826,10 @@ mi-cmd-break.o: $(srcdir)/mi/mi-cmd-break.c $(COMPILE) $(srcdir)/mi/mi-cmd-break.c $(POSTCOMPILE) +mi-cmd-catch.o: $(srcdir)/mi/mi-cmd-catch.c + $(COMPILE) $(srcdir)/mi/mi-cmd-catch.c + $(POSTCOMPILE) + mi-cmd-disas.o: $(srcdir)/mi/mi-cmd-disas.c $(COMPILE) $(srcdir)/mi/mi-cmd-disas.c $(POSTCOMPILE) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 01a472c631..2fe8f14665 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -7850,20 +7850,20 @@ print_recreate_catch_solib (struct breakpoint *b, struct ui_file *fp) static struct breakpoint_ops catch_solib_breakpoint_ops; -/* A helper function that does all the work for "catch load" and - "catch unload". */ +/* Shared helper function (MI and CLI) for creating and installing + a shared object event catchpoint. If IS_LOAD is non-zero then + the events to be caught are load events, otherwise they are + unload events. If IS_TEMP is non-zero the catchpoint is a + temporary one. If ENABLED is non-zero the catchpoint is + created in an enabled state. */ -static void -catch_load_or_unload (char *arg, int from_tty, int is_load, - struct cmd_list_element *command) +void +add_solib_catchpoint (char *arg, int is_load, int is_temp, int enabled) { struct solib_catchpoint *c; struct gdbarch *gdbarch = get_current_arch (); - int tempflag; struct cleanup *cleanup; - tempflag = get_cmd_context (command) == CATCH_TEMPORARY; - if (!arg) arg = ""; arg = skip_spaces (arg); @@ -7887,13 +7887,30 @@ catch_load_or_unload (char *arg, int from_tty, int is_load, } c->is_load = is_load; - init_catchpoint (&c->base, gdbarch, tempflag, NULL, + init_catchpoint (&c->base, gdbarch, is_temp, NULL, &catch_solib_breakpoint_ops); + c->base.enable_state = enabled ? bp_enabled : bp_disabled; + discard_cleanups (cleanup); install_breakpoint (0, &c->base, 1); } +/* A helper function that does all the work for "catch load" and + "catch unload". */ + +static void +catch_load_or_unload (char *arg, int from_tty, int is_load, + struct cmd_list_element *command) +{ + int tempflag; + const int enabled = 1; + + tempflag = get_cmd_context (command) == CATCH_TEMPORARY; + + add_solib_catchpoint (arg, is_load, tempflag, enabled); +} + static void catch_load_command_1 (char *arg, int from_tty, struct cmd_list_element *command) diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 546e85514e..ca0cfd619e 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -1405,6 +1405,11 @@ extern void disable_breakpoints_in_shlibs (void); /* This function returns TRUE if ep is a catchpoint. */ extern int is_catchpoint (struct breakpoint *); +/* Shared helper function (MI and CLI) for creating and installing + a shared object event catchpoint. */ +extern void add_solib_catchpoint (char *arg, int is_load, int is_temp, + int enabled); + /* Enable breakpoints and delete when hit. Called with ARG == NULL deletes all breakpoints. */ extern void delete_command (char *arg, int from_tty); diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index 487d42d547..a36e1ef492 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -29,6 +29,7 @@ #include "exceptions.h" #include "observer.h" #include "mi-main.h" +#include "mi-cmd-break.h" enum { @@ -59,6 +60,30 @@ enum bp_type REGEXP_BP }; +/* Arrange for all new breakpoints and catchpoints to be reported to + CURRENT_UIOUT until the cleanup returned by this function is run. + + Note that MI output will be probably invalid if more than one + breakpoint is created inside one MI command. */ + +struct cleanup * +setup_breakpoint_reporting (void) +{ + struct cleanup *rev_flag; + + if (! mi_breakpoint_observers_installed) + { + observer_attach_breakpoint_created (breakpoint_notify); + mi_breakpoint_observers_installed = 1; + } + + rev_flag = make_cleanup_restore_integer (&mi_can_breakpoint_notify); + mi_can_breakpoint_notify = 1; + + return rev_flag; +} + + /* Implements the -break-insert command. See the MI manual for the list of possible options. */ @@ -144,14 +169,7 @@ mi_cmd_break_insert (char *command, char **argv, int argc) address = argv[oind]; /* Now we have what we need, let's insert the breakpoint! */ - if (! mi_breakpoint_observers_installed) - { - observer_attach_breakpoint_created (breakpoint_notify); - mi_breakpoint_observers_installed = 1; - } - - back_to = make_cleanup_restore_integer (&mi_can_breakpoint_notify); - mi_can_breakpoint_notify = 1; + back_to = setup_breakpoint_reporting (); /* Note that to request a fast tracepoint, the client uses the "hardware" flag, although there's nothing of hardware related to diff --git a/gdb/mi/mi-cmd-break.h b/gdb/mi/mi-cmd-break.h new file mode 100644 index 0000000000..8a46754a12 --- /dev/null +++ b/gdb/mi/mi-cmd-break.h @@ -0,0 +1,30 @@ +/* MI Command Set - breakpoint and watchpoint commands. + Copyright (C) 2012 Free Software Foundation, Inc. + + Contributed by Intel Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef MI_CMD_BREAK_H +#define MI_CMD_BREAK_H + + +/* Setup the reporting of the insertion of a new breakpoint or + catchpoint. */ +struct cleanup *setup_breakpoint_reporting (void); + +#endif + diff --git a/gdb/mi/mi-cmd-catch.c b/gdb/mi/mi-cmd-catch.c new file mode 100644 index 0000000000..a3efa6fbb5 --- /dev/null +++ b/gdb/mi/mi-cmd-catch.c @@ -0,0 +1,102 @@ +/* MI Command Set - catch commands. + Copyright (C) 2012 Free Software Foundation, Inc. + + Contributed by Intel Corporation. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "arch-utils.h" +#include "breakpoint.h" +#include "gdb.h" +#include "libiberty.h" +#include "mi-cmds.h" +#include "mi-getopt.h" +#include "mi-cmd-break.h" + + +/* Common path for the -catch-load and -catch-unload. */ + +static void +mi_catch_load_unload (int load, char *argv[], int argc) +{ + struct solib_catchpoint *c; + struct cleanup *back_to; + const char *actual_cmd = load ? "-catch-load" : "-catch-unload"; + int temp = 0; + int enabled = 1; + int oind = 0; + char *oarg; + enum opt + { + OPT_TEMP, + OPT_DISABLED, + }; + static const struct mi_opt opts[] = + { + { "t", OPT_TEMP, 0 }, + { "d", OPT_DISABLED, 0 }, + { 0, 0, 0 } + }; + + for (;;) + { + int opt = mi_getopt (actual_cmd, argc, argv, opts, + &oind, &oarg); + + if (opt < 0) + break; + + switch ((enum opt) opt) + { + case OPT_TEMP: + temp = 1; + break; + case OPT_DISABLED: + enabled = 0; + break; + } + } + + if (oind >= argc) + error (_("-catch-load/unload: Missing ")); + if (oind < argc -1) + error (_("-catch-load/unload: Garbage following the ")); + + back_to = setup_breakpoint_reporting (); + + add_solib_catchpoint (argv[oind], load, temp, enabled); + + do_cleanups (back_to); +} + +/* Handler for the -catch-load. */ + +void +mi_cmd_catch_load (char *cmd, char *argv[], int argc) +{ + mi_catch_load_unload (1, argv, argc); +} + + +/* Handler for the -catch-unload. */ + +void +mi_cmd_catch_unload (char *cmd, char *argv[], int argc) +{ + mi_catch_load_unload (0, argv, argc); +} + diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c index 572625f3b2..0e3cd6c7a6 100644 --- a/gdb/mi/mi-cmds.c +++ b/gdb/mi/mi-cmds.c @@ -67,6 +67,10 @@ static struct mi_cmd mi_cmds[] = &mi_suppress_notification.breakpoint), DEF_MI_CMD_MI_1 ("break-watch", mi_cmd_break_watch, &mi_suppress_notification.breakpoint), + DEF_MI_CMD_MI_1 ("catch-load", mi_cmd_catch_load, + &mi_suppress_notification.breakpoint), + DEF_MI_CMD_MI_1 ("catch-unload", mi_cmd_catch_unload, + &mi_suppress_notification.breakpoint), DEF_MI_CMD_MI ("data-disassemble", mi_cmd_disassemble), DEF_MI_CMD_MI ("data-evaluate-expression", mi_cmd_data_evaluate_expression), DEF_MI_CMD_MI ("data-list-changed-registers", diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h index cf1a5ebc4f..da8df48d22 100644 --- a/gdb/mi/mi-cmds.h +++ b/gdb/mi/mi-cmds.h @@ -43,6 +43,8 @@ extern mi_cmd_argv_ftype mi_cmd_break_insert; extern mi_cmd_argv_ftype mi_cmd_break_commands; extern mi_cmd_argv_ftype mi_cmd_break_passcount; extern mi_cmd_argv_ftype mi_cmd_break_watch; +extern mi_cmd_argv_ftype mi_cmd_catch_load; +extern mi_cmd_argv_ftype mi_cmd_catch_unload; extern mi_cmd_argv_ftype mi_cmd_disassemble; extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression; extern mi_cmd_argv_ftype mi_cmd_data_list_register_names; -- 2.34.1