This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA/RFC 3/4] New GDB/MI commands to catch Ada exceptions


This patch introduces two new GDB/MI commands implementing the equivalent
of the "catch exception" and  "catch assert" GDB/CLI commands. They are:

  -catch-exception [-c COND] [-d] [-e EXCEPTION_NAME] [-t] [-u]
  -catch-assert [-c COND] [-d] [-t]

The options mean:

  -c COND: Attach the given condition to the catchpoint
  -d: Make the newly created catchpoint disabled.
  -e EXCEPTION_NAME: The catchpoint will only stop when EXCEPTION_NAME
      is raised, and ignore other exceptions.
  -t: Create a temporary catchpoint
  -u: The catchpoint will only stop when an unhandled exception gets raised.

The command names are mapped directly from their CLI counterparts
("catch exception" and "catch assert"), and the options try to follow
the general scheme used by -break-insert or -catch-load. I am happy
making any change to their name of the options if it makes sense.

gdb/ChangeLog:

        * breakpoint.h (init_ada_exception_breakpoint): Add parameter
        "enabled".
        * breakpoint.c (init_ada_exception_breakpoint): Add parameter
        "enabled".  Set B->ENABLE_STATE accordingly.
        * ada-lang.h (ada_exception_catchpoint_kind): Move here from
        ada-lang.c.
        (create_ada_exception_catchpoint): Add declaration.
        * ada-lang.c (ada_exception_catchpoint_kind): Move to ada-lang.h.
        (create_ada_exception_catchpoint): Make non-static. Add new
        parameter "disabled". Use it in call to
        init_ada_exception_breakpoint.
        (catch_ada_exception_command): Add parameter "enabled" in call
        to create_ada_exception_catchpoint.
        (catch_assert_command): Likewise.

        * mi/mi-cmds.h (mi_cmd_catch_assert, mi_cmd_catch_exception):
        Add declarations.
        * mi/mi-cmds.c (mi_cmds): Add the "catch-assert" and
        "catch-exception" commands.
        * mi/mi-cmd-catch.c: Add #include "ada-lang.h".
        (mi_cmd_catch_assert, mi_cmd_catch_exception): New functions.

Tested on x86_64-linux.  Thoughts?

Thank you!
-- 
Joel

---
 gdb/ada-lang.c        |  21 +++-----
 gdb/ada-lang.h        |  15 ++++++
 gdb/breakpoint.c      |   3 +-
 gdb/breakpoint.h      |   1 +
 gdb/mi/mi-cmd-catch.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/mi/mi-cmds.c      |   4 ++
 gdb/mi/mi-cmds.h      |   2 +
 7 files changed, 162 insertions(+), 15 deletions(-)

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 3c7e4cf..9ff3ab9 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10981,16 +10981,6 @@ ada_modulus (struct type *type)
    variants of the runtime, we use a sniffer that will determine
    the runtime variant used by the program being debugged.  */
 
-/* The different types of catchpoints that we introduced for catching
-   Ada exceptions.  */
-
-enum ada_exception_catchpoint_kind
-{
-  ada_catch_exception,
-  ada_catch_exception_unhandled,
-  ada_catch_assert
-};
-
 /* Ada's standard exceptions.  */
 
 static char *standard_exc[] = {
@@ -12190,12 +12180,13 @@ ada_exception_sal (enum ada_exception_catchpoint_kind ex, char *excep_string,
 
    FROM_TTY is the usual argument passed to all commands implementations.  */
 
-static void
+void
 create_ada_exception_catchpoint (struct gdbarch *gdbarch,
 				 enum ada_exception_catchpoint_kind ex_kind,
 				 char *excep_string,
 				 char *cond_string,
 				 int tempflag,
+				 int disabled,
 				 int from_tty)
 {
   struct ada_catchpoint *c;
@@ -12206,7 +12197,7 @@ create_ada_exception_catchpoint (struct gdbarch *gdbarch,
 
   c = XNEW (struct ada_catchpoint);
   init_ada_exception_breakpoint (&c->base, gdbarch, sal, addr_string,
-				 ops, tempflag, from_tty);
+				 ops, tempflag, disabled, from_tty);
   c->excep_string = excep_string;
   create_excep_cond_exprs (c);
   if (cond_string != NULL)
@@ -12234,7 +12225,8 @@ catch_ada_exception_command (char *arg, int from_tty,
 				     &cond_string);
   create_ada_exception_catchpoint (gdbarch, ex_kind,
 				   excep_string, cond_string,
-				   tempflag, from_tty);
+				   tempflag, 1 /* enabled */,
+				   from_tty);
 }
 
 /* Split the arguments specified in a "catch assert" command.
@@ -12284,7 +12276,8 @@ catch_assert_command (char *arg, int from_tty,
   catch_ada_assert_command_split (arg, &cond_string);
   create_ada_exception_catchpoint (gdbarch, ada_catch_assert,
 				   NULL, cond_string,
-				   tempflag, from_tty);
+				   tempflag, 1 /* enabled */,
+				   from_tty);
 }
                                 /* Operators */
 /* Information about operators given special treatment in functions
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 4ea25b8..151ced8 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -114,6 +114,16 @@ enum ada_renaming_category
     ADA_SUBPROGRAM_RENAMING
   };
 
+/* The different types of catchpoints that we introduced for catching
+   Ada exceptions.  */
+
+enum ada_exception_catchpoint_kind
+{
+  ada_catch_exception,
+  ada_catch_exception_unhandled,
+  ada_catch_assert
+};
+
 /* Ada task structures.  */
 
 struct ada_task_info
@@ -374,6 +384,11 @@ extern char *ada_main_name (void);
 
 extern char *ada_name_for_lookup (const char *name);
 
+extern void create_ada_exception_catchpoint
+  (struct gdbarch *gdbarch, enum ada_exception_catchpoint_kind ex_kind,
+   char *excep_string, char *cond_string, int tempflag, int disabled,
+   int from_tty);
+
 /* Tasking-related: ada-tasks.c */
 
 extern int valid_task_id (int);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index d3e9e49..c31756d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -11620,6 +11620,7 @@ init_ada_exception_breakpoint (struct breakpoint *b,
 			       char *addr_string,
 			       const struct breakpoint_ops *ops,
 			       int tempflag,
+			       int enabled,
 			       int from_tty)
 {
   if (from_tty)
@@ -11642,7 +11643,7 @@ init_ada_exception_breakpoint (struct breakpoint *b,
 
   init_raw_breakpoint (b, gdbarch, sal, bp_breakpoint, ops);
 
-  b->enable_state = bp_enabled;
+  b->enable_state = enabled ? bp_enabled : bp_disabled;
   b->disposition = tempflag ? disp_del : disp_donttouch;
   b->addr_string = addr_string;
   b->language = language_ada;
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index faedb4a..4a25fb7 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -1238,6 +1238,7 @@ extern void
 				 char *addr_string,
 				 const struct breakpoint_ops *ops,
 				 int tempflag,
+				 int enabled,
 				 int from_tty);
 
 extern void init_catchpoint (struct breakpoint *b,
diff --git a/gdb/mi/mi-cmd-catch.c b/gdb/mi/mi-cmd-catch.c
index cd932fe..23e30d0 100644
--- a/gdb/mi/mi-cmd-catch.c
+++ b/gdb/mi/mi-cmd-catch.c
@@ -23,10 +23,141 @@
 #include "breakpoint.h"
 #include "gdb.h"
 #include "libiberty.h"
+#include "ada-lang.h"
 #include "mi-cmds.h"
 #include "mi-getopt.h"
 #include "mi-cmd-break.h"
 
+/* Handler for the -catch-assert command.  */
+
+void
+mi_cmd_catch_assert (char *cmd, char *argv[], int argc)
+{
+  struct gdbarch *gdbarch = get_current_arch();
+  char *condition = NULL;
+  int enabled = 1;
+  int temp = 0;
+
+  int oind = 0;
+  char *oarg;
+
+  enum opt
+    {
+      OPT_CONDITION, OPT_DISABLED, OPT_TEMP,
+    };
+  static const struct mi_opt opts[] =
+    {
+      { "c", OPT_CONDITION, 1},
+      { "d", OPT_DISABLED, 0 },
+      { "t", OPT_TEMP, 0 },
+      { 0, 0, 0 }
+    };
+
+  for (;;)
+    {
+      int opt = mi_getopt ("-catch-assert", argc, argv, opts,
+			   &oind, &oarg);
+
+      if (opt < 0)
+        break;
+
+      switch ((enum opt) opt)
+        {
+	case OPT_CONDITION:
+	  condition = oarg;
+	  break;
+	case OPT_DISABLED:
+	  enabled = 0;
+	  break;
+	case OPT_TEMP:
+	  temp = 1;
+	  break;
+        }
+    }
+
+  /* This command does not accept any argument.  Make sure the user
+     did not provide any.  */
+  if (oind != argc)
+    error (_("Invalid argument: %s"), argv[oind]);
+
+  setup_breakpoint_reporting ();
+  create_ada_exception_catchpoint (gdbarch, ada_catch_assert,
+				   NULL, condition, temp, enabled, 0);
+}
+
+/* Handler for the -catch-exception command.  */
+
+void
+mi_cmd_catch_exception (char *cmd, char *argv[], int argc)
+{
+  struct gdbarch *gdbarch = get_current_arch();
+  char *condition = NULL;
+  int enabled = 1;
+  char *exception_name = NULL;
+  int temp = 0;
+  enum ada_exception_catchpoint_kind ex_kind = ada_catch_exception;
+
+  int oind = 0;
+  char *oarg;
+
+  enum opt
+    {
+      OPT_CONDITION, OPT_DISABLED, OPT_EXCEPTION_NAME, OPT_TEMP,
+      OPT_UNHANDLED,
+    };
+  static const struct mi_opt opts[] =
+    {
+      { "c", OPT_CONDITION, 1},
+      { "d", OPT_DISABLED, 0 },
+      { "e", OPT_EXCEPTION_NAME, 1 },
+      { "t", OPT_TEMP, 0 },
+      { "u", OPT_UNHANDLED, 0},
+      { 0, 0, 0 }
+    };
+
+  for (;;)
+    {
+      int opt = mi_getopt ("-catch-exception", argc, argv, opts,
+			   &oind, &oarg);
+
+      if (opt < 0)
+        break;
+
+      switch ((enum opt) opt)
+        {
+	case OPT_CONDITION:
+	  condition = oarg;
+	  break;
+	case OPT_DISABLED:
+	  enabled = 0;
+	  break;
+	case OPT_EXCEPTION_NAME:
+	  exception_name = oarg;
+	  break;
+	case OPT_TEMP:
+	  temp = 1;
+	  break;
+	case OPT_UNHANDLED:
+	  ex_kind = ada_catch_exception_unhandled;
+	  break;
+        }
+    }
+
+  /* This command does not accept any argument.  Make sure the user
+     did not provide any.  */
+  if (oind != argc)
+    error (_("Invalid argument: %s"), argv[oind]);
+
+  /* Specifying an exception name does not make sense when requesting
+     an unhandled exception breakpoint.  */
+  if (ex_kind == ada_catch_exception_unhandled && exception_name != NULL)
+    error (_("\"-e\" and \"-u\" are mutually exclusive"));
+
+  setup_breakpoint_reporting ();
+  create_ada_exception_catchpoint (gdbarch, ex_kind,
+				   exception_name, condition,
+				   temp, enabled, 0);
+}
 
 /* Common path for the -catch-load and -catch-unload.  */
 
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 0768b2a..1b8ec92 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -68,6 +68,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-assert", mi_cmd_catch_assert,
+                   &mi_suppress_notification.breakpoint),
+  DEF_MI_CMD_MI_1 ("catch-exception", mi_cmd_catch_exception,
+                   &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,
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index a472582..bbca54d 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -39,6 +39,8 @@ extern mi_cmd_argv_ftype mi_cmd_dprintf_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_assert;
+extern mi_cmd_argv_ftype mi_cmd_catch_exception;
 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;
-- 
1.8.1.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]