This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v8 1/3] MI: add the -catch-load and -catch-unload commands
- From: Mircea Gherzan <mircea dot gherzan at intel dot com>
- To: gdb-patches at sourceware dot org
- Cc: keven dot boell at intel dot com, mircea dot gherzan at intel dot com, marc dot khouzam at ericsson dot com, tromey at redhat dot com, vladimir at codesourcery dot com
- Date: Mon, 3 Dec 2012 15:18:33 +0100
- Subject: [PATCH v8 1/3] 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 <mircea.gherzan@intel.com>
* 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.
(mi_can_breakpoint_notify): Remove the static qualifier.
(breakpoint_notify): Take catchpoints into account.
(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.
Signed-off-by: Mircea Gherzan <mircea.gherzan@intel.com>
---
gdb/Makefile.in | 9 +++-
gdb/breakpoint.c | 35 ++++++++++++----
gdb/breakpoint.h | 5 ++
gdb/mi/mi-cmd-break.c | 38 ++++++++++++----
gdb/mi/mi-cmd-break.h | 35 +++++++++++++++
gdb/mi/mi-cmd-catch.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++
gdb/mi/mi-cmds.c | 4 ++
gdb/mi/mi-cmds.h | 2 +
8 files changed, 217 insertions(+), 21 deletions(-)
create mode 100644 gdb/mi/mi-cmd-break.h
create mode 100644 gdb/mi/mi-cmd-catch.c
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3dd7b85..40c7e80 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 \
@@ -1833,6 +1834,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 59b7bf3..3212295 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 8b1bcb7..11e432c 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 487d42d..8dd0de7 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
{
@@ -41,14 +42,18 @@ static int mi_breakpoint_observers_installed;
/* Control whether breakpoint_notify may act. */
-static int mi_can_breakpoint_notify;
+int mi_can_breakpoint_notify;
/* Output a single breakpoint, when allowed. */
static void
breakpoint_notify (struct breakpoint *b)
{
- if (mi_can_breakpoint_notify)
+ int can_notify = (b->type == bp_catchpoint
+ ? mi_can_catchpoint_notify
+ : mi_can_breakpoint_notify);
+
+ if (can_notify)
gdb_breakpoint_query (current_uiout, b->number, NULL);
}
@@ -59,6 +64,25 @@ enum bp_type
REGEXP_BP
};
+/* Setup the reporting of the insertion of a new breakpoint
+ or catchpoint. The flag at CAN_NOTIFY controls whether the
+ notifier may act. The REV_FLAG is used to return a cleanup
+ for the initial value of CAN_NOTIFY. */
+
+void setup_breakpoint_reporting (int *can_notify,
+ 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 (can_notify);
+ *can_notify = 1;
+}
+
+
/* Implements the -break-insert command.
See the MI manual for the list of possible options. */
@@ -144,14 +168,8 @@ 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;
+ setup_breakpoint_reporting (&mi_can_breakpoint_notify,
+ &back_to);
/* 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 0000000..370a377
--- /dev/null
+++ b/gdb/mi/mi-cmd-break.h
@@ -0,0 +1,35 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef MI_CMD_BREAK_H
+#define MI_CMD_BREAK_H
+
+
+extern int mi_can_breakpoint_notify;
+extern int mi_can_catchpoint_notify;
+
+/* Setup the reporting of the insertion of a new breakpoint or
+ catchpoint. */
+void setup_breakpoint_reporting (int *can_notify,
+ struct cleanup **rev_flag);
+
+
+#endif
+
diff --git a/gdb/mi/mi-cmd-catch.c b/gdb/mi/mi-cmd-catch.c
new file mode 100644
index 0000000..ae9e3c3
--- /dev/null
+++ b/gdb/mi/mi-cmd-catch.c
@@ -0,0 +1,110 @@
+/* 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 <http://www.gnu.org/licenses/>. */
+
+#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"
+
+/* True if MI catchpoint observers have been registered. */
+
+static int mi_catchpoint_observers_installed;
+
+/* Control whether catchpoint_notify may act. */
+
+int mi_can_catchpoint_notify;
+
+/* 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;
+ 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 <library name>"));
+ if (oind < argc -1)
+ error (_("-catch-load/unload: Garbage following the <library name>"));
+
+ setup_breakpoint_reporting(&mi_can_catchpoint_notify,
+ &back_to);
+
+ 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 572625f..0e3cd6c 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 cf1a5eb..da8df48 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;
--
1.7.1