From 349774efe258cff6b365b72df07f6ce2eb76cbd6 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Fri, 11 Oct 2013 13:48:19 +0000 Subject: [PATCH] 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. 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. --- gdb/ChangeLog | 24 ++++++++ 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 + 8 files changed, 186 insertions(+), 15 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b07f1c5f478..b8f01c2547c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +2013-10-11 Joel Brobecker + + * 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. + 2013-10-11 Joel Brobecker * ada-lang.c (enum ada_exception_catchpoint_kind): Renames diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 3c7e4cfe9bc..9ff3ab91f01 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 4ea25b80ba9..151ced8bef1 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 f0da90a5ce7..5ce50defc11 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -11621,6 +11621,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) @@ -11643,7 +11644,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 faedb4a7eae..4a25fb7b80d 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 cd932fe999f..23e30d086e0 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 0768b2a135c..1b8ec9279ed 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 a472582f125..bbca54db7ba 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; -- 2.30.2