Re: [patch/MI] Implementation for break-catch command

Aleksandar Ristovski
2008-05-28T17:49:40Z

[-- Attachment #1: Type: text/plain, Size: 1482 bytes --]

Vladimir Prus wrote:
>> * mi/mi-cmd-break.c (mi_cmd_break_catch): New function.
>
> This one accepts and parses a lot of options, and then ignores them. Some
> options, like -f, will never make any sense for -break-catch. Can you
> please only leave necessary code there?

Yes, I wasn't sure what to do about them. -f doesn't apply, but -p for example should apply but has not been implemented (yet). I put a warning for now for each valid unimplemented option.

>
> Also note that the condition is actually meaningful for catchpoints
> and catch_exception_command_1/handle_gnu_v3_exceptions actually
> tries to set condition. Should setting a condition via MI work too?

Definitely.

>
>> * mi/mi-cmds.c (build_table): Add function for break-catch.
>
> It's not build_table, it's mi_cmds. "diff -p" sometimes lies.

Yep, and I sometimes just blindly type what diff says. Thanks.

New diff attached. Cc-ing Eli for doc. changes review.

New ChangeLog:

2008-05-28 Aleksandar Ristovski <aristovski@qnx.com>

* breakpoint.c (catch_command_1): Remove static declaration.
(print_mention_exception_catchpoint): Output information only
when non-MI protocol is active.
* breakpoint.h (catch_command_1): New declaration.
* doc/gdb.texinfo (break-catch): Remove @ignore and add text for
break-catch command.
* mi/mi-cmd-break.c (mi_cmd_break_catch): New function.
* mi/mi-cmds.c (mi_cmds): Add function for break-catch.
* mi/mi-cmds.h (mi_cmd_break_catch): New declaration.

[-- Attachment #2: break-catch-200805281309.diff --]
[-- Type: text/plain, Size: 8135 bytes --]

Index: gdb/breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.322
diff -u -p -r1.322 breakpoint.c
--- gdb/breakpoint.c 28 May 2008 14:04:21 -0000 1.322
+++ gdb/breakpoint.c 28 May 2008 17:08:19 -0000
@@ -67,8 +67,6 @@
static void until_break_command_continuation (struct continuation_arg *arg,
int error);

-static void catch_command_1 (char *, int, int);
-
static void enable_delete_command (char *, int);

static void enable_delete_breakpoint (struct breakpoint *);
@@ -6549,13 +6547,16 @@ print_mention_exception_catchpoint (stru
int bp_temp;
int bp_throw;

- bp_temp = b->loc->owner->disposition == disp_del;
- bp_throw = strstr (b->addr_string, "throw") != NULL;
- ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
- : _("Catchpoint "));
- ui_out_field_int (uiout, "bkptno", b->number);
- ui_out_text (uiout, bp_throw ? _(" (throw)")
- : _(" (catch)"));
+ if (!ui_out_is_mi_like_p (uiout))
+ {
+ bp_temp = b->loc->owner->disposition == disp_del;
+ bp_throw = strstr (b->addr_string, "throw") != NULL;
+ ui_out_text (uiout, bp_temp ? _("Temporary catchpoint ")
+ : _("Catchpoint "));
+ ui_out_field_int (uiout, "bkptno", b->number);
+ ui_out_text (uiout, bp_throw ? _(" (throw)")
+ : _(" (catch)"));
+ }
}

static struct breakpoint_ops gnu_v3_exception_catchpoint_ops = {
@@ -6691,7 +6692,7 @@ catch_assert_command (char *arg, int tem
tempflag, from_tty);
}

-static void
+void
catch_command_1 (char *arg, int tempflag, int from_tty)
{

Index: gdb/breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.72
diff -u -p -r1.72 breakpoint.h
--- gdb/breakpoint.h 4 May 2008 19:38:59 -0000 1.72
+++ gdb/breakpoint.h 28 May 2008 17:08:21 -0000
@@ -865,4 +865,6 @@ void breakpoint_restore_shadows (gdb_byt

extern int breakpoints_always_inserted_mode (void);

+extern void catch_command_1 (char *arg, int tempflag, int from_tty);
+
#endif /* !defined (BREAKPOINT_H) */
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.498
diff -u -p -r1.498 gdb.texinfo
--- gdb/doc/gdb.texinfo 22 May 2008 21:21:41 -0000 1.498
+++ gdb/doc/gdb.texinfo 28 May 2008 17:08:25 -0000
@@ -18486,10 +18486,50 @@ line="5",times="0",ignore="3"@}]@}
(gdb)
@end smallexample

-@ignore
@subheading The @code{-break-catch} Command
@findex -break-catch

+@subsubheading Synopsis
+
+@smallexample
+ -break-catch [ -t ] [ @var{event} ]
+@end smallexample
+
+@noindent
+Where @var{event} can be one of:
+
+@itemize @bullet
+@item catch
+@item throw
+@end itemize
+
+The possible optional parameters of this command are:
+
+@table @samp
+@item -t
+Insert a temporary catchpoint.
+@end table
+
+@subsubheading Result
+
+The result is in the form:
+
+@smallexample
+^done,bkpt=@{number="@var{number}",type="@var{type}",disp="del"|"keep",
+enabled="y"|"n",addr="@var{hex}",what="exception catch"|"exception throw",
+times="@var{times}",original-location="@var{funcname}"@}
+@end smallexample
+
+@noindent
+where @var{number} is the @value{GDBN} number for this breakpoint,
+@var{funcname} is the name of the function where the catchpoint was
+inserted (target specific) and @var{times} the number of times that
+the breakpoint has been hit (always 0 for -break-catch but may be
+greater for -break-info or -break-list which use the same output).
+
+Note: this format is open to change.
+
+@ignore
@subheading The @code{-break-commands} Command
@findex -break-commands
@end ignore
Index: gdb/mi/mi-cmd-break.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-break.c,v
retrieving revision 1.19
diff -u -p -r1.19 mi-cmd-break.c
--- gdb/mi/mi-cmd-break.c 1 Feb 2008 16:24:46 -0000 1.19
+++ gdb/mi/mi-cmd-break.c 28 May 2008 17:08:26 -0000
@@ -241,3 +241,104 @@ mi_cmd_break_watch (char *command, char
}
return MI_CMD_DONE;
}
+
+/* Implements the -break-catch command.
+ See the MI manual for the list of possible options. */
+
+enum mi_cmd_result
+mi_cmd_break_catch (char *command, char **argv, int argc)
+{
+ char *event_name = NULL;
+ enum bp_type type = REG_BP;
+ int temp_p = 0;
+ int thread = -1;
+ int ignore_count = 0;
+ char *condition = NULL;
+ int pending = 0;
+ struct gdb_exception e;
+ struct gdb_events *old_hooks;
+ char argument[250];
+ enum opt
+ {
+ HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
+ IGNORE_COUNT_OPT, THREAD_OPT, PENDING_OPT
+ };
+ static struct mi_opt opts[] =
+ {
+ {"h", HARDWARE_OPT, 0},
+ {"t", TEMP_OPT, 0},
+ {"c", CONDITION_OPT, 1},
+ {"i", IGNORE_COUNT_OPT, 1},
+ {"p", THREAD_OPT, 1},
+ { 0, 0, 0 }
+ };
+
+ /* Parse arguments. It could be -r or -h or -t, <location> or ``--''
+ to denote the end of the option list. */
+ int optind = 0;
+ char *optarg;
+ while (1)
+ {
+ int opt = mi_getopt ("mi_cmd_break_catch", argc, argv, opts, &optind, &optarg);
+ if (opt < 0)
+ break;
+ switch ((enum opt) opt)
+ {
+ case TEMP_OPT:
+ temp_p = 1;
+ break;
+ case HARDWARE_OPT:
+ warning (_("Hardware flag ignored for catchpoints"));
+ break;
+#if 0
+ case REGEXP_OPT:
+ type = REGEXP_BP;
+ break;
+#endif
+ case CONDITION_OPT:
+ condition = optarg;
+ break;
+ case IGNORE_COUNT_OPT:
+ ignore_count = atol (optarg);
+ warning (_("Ignore count not yet implemented for catchpoints"));
+ break;
+ case THREAD_OPT:
+ thread = atol (optarg);
+ warning (_("Thread option not yet implemented for catchpoints"));
+ break;
+ }
+ }
+
+ if (optind >= argc)
+ error (_("mi_cmd_break_catch: Missing <event name>"));
+ if (optind < argc - 1)
+ error (_("mi_cmd_break_catch: Garbage following <event name>"));
+ event_name = argv[optind];
+
+ if (condition != NULL)
+ snprintf (argument, sizeof (argument), "%s %s", event_name, condition);
+ else
+ strcpy (argument, event_name);
+ /* Now we have what we need, let's insert the breakpoint! */
+ old_hooks = deprecated_set_gdb_event_hooks (&breakpoint_hooks);
+ /* Make sure we restore hooks even if exception is thrown. */
+ TRY_CATCH (e, RETURN_MASK_ALL)
+ {
+ switch (type)
+ {
+ case REG_BP:
+ catch_command_1 (argument, temp_p, 0);
+ break;
+ default:
+ internal_error (__FILE__, __LINE__,
+ _("mi_cmd_break_catch: Bad switch."));
+ }
+ }
+ deprecated_set_gdb_event_hooks (old_hooks);
+ if (e.reason < 0)
+ throw_exception (e);
+
+ return MI_CMD_DONE;
+}
+
+
Index: gdb/mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.32
diff -u -p -r1.32 mi-cmds.c
--- gdb/mi/mi-cmds.c 24 Apr 2008 13:28:06 -0000 1.32
+++ gdb/mi/mi-cmds.c 28 May 2008 17:08:26 -0000
@@ -33,7 +33,7 @@ static void build_table (struct mi_cmd *
struct mi_cmd mi_cmds[] =
{
{ "break-after", { "ignore", 1 }, NULL },
- { "break-catch", { NULL, 0 }, NULL },
+ { "break-catch", { NULL, 0 }, mi_cmd_break_catch},
{ "break-commands", { NULL, 0 }, NULL },
{ "break-condition", { "cond", 1 }, NULL },
{ "break-delete", { "delete breakpoint", 1 }, NULL },
Index: gdb/mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.30
diff -u -p -r1.30 mi-cmds.h
--- gdb/mi/mi-cmds.h 24 Apr 2008 13:28:06 -0000 1.30
+++ gdb/mi/mi-cmds.h 28 May 2008 17:08:26 -0000
@@ -54,6 +54,7 @@ typedef enum mi_cmd_result (mi_cmd_argv_
/* Function implementing each command */
extern mi_cmd_argv_ftype mi_cmd_break_insert;
extern mi_cmd_argv_ftype mi_cmd_break_watch;
+extern mi_cmd_argv_ftype mi_cmd_break_catch;
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;