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

Aleksandar Ristovski
2008-07-31T14:06:43Z

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

Vladimir Prus wrote:
>
> Seems OK to me.
>
> - Volodya
>

I completely forgot about this patch (and then I don't believe my wife when she says I am always forgetting things...)

In any case... the code has changed meanwhile so the attached patch takes care of that (removed deprecated_set_gdb_event_hooks).

Eli - you have already said this was OK for the docs, but maybe you want to re-check (the doc part has not changed).

Thanks,

Aleksandar Ristovski
QNX Software Systems

[-- Attachment #2: break-catch-200807311000.diff.ChangeLog --]
[-- Type: text/plain, Size: 523 bytes --]

2008-07-31 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 #3: break-catch-200807311000.diff --]
[-- Type: text/plain, Size: 8269 bytes --]

Index: gdb/breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.338
diff -u -p -r1.338 breakpoint.c
--- gdb/breakpoint.c 28 Jul 2008 17:53:52 -0000 1.338
+++ gdb/breakpoint.c 31 Jul 2008 13:56:00 -0000
@@ -61,8 +61,6 @@

/* Prototypes for local functions. */

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

static void enable_delete_breakpoint (struct breakpoint *);
@@ -6556,13 +6554,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 = {
@@ -6698,7 +6699,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.76
diff -u -p -r1.76 breakpoint.h
--- gdb/breakpoint.h 25 Jul 2008 16:12:03 -0000 1.76
+++ gdb/breakpoint.h 31 Jul 2008 13:56:00 -0000
@@ -882,4 +882,6 @@ extern int breakpoints_always_inserted_m
in our opinion won't ever trigger. */
extern void breakpoint_retire_moribund (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.509
diff -u -p -r1.509 gdb.texinfo
--- gdb/doc/gdb.texinfo 18 Jul 2008 20:55:33 -0000 1.509
+++ gdb/doc/gdb.texinfo 31 Jul 2008 13:56:11 -0000
@@ -18610,10 +18610,52 @@ 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 catchpoint,
+@var{funcname} is the name of the function where the catchpoint
+was inserted (target specific) and @var{times} the number of times
+that the catchpoint has been hit (always 0 for @code{-break-catch}
+but may be greater for @code{-break-info} or @code{-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.21
diff -u -p -r1.21 mi-cmd-break.c
--- gdb/mi/mi-cmd-break.c 25 Jul 2008 16:12:03 -0000 1.21
+++ gdb/mi/mi-cmd-break.c 31 Jul 2008 13:56:11 -0000
@@ -245,3 +245,105 @@ mi_cmd_break_watch (char *command, char
error (_("mi_cmd_break_watch: Unknown watchpoint type."));
}
}
+
+/* Implements the -break-catch command.
+ See the MI manual for the list of possible options. */
+
+void
+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;
+ struct gdb_exception e;
+ struct gdb_events *old_hooks;
+ char argument[250];
+ enum opt
+ {
+ HARDWARE_OPT, TEMP_OPT, CONDITION_OPT,
+ IGNORE_COUNT_OPT, THREAD_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;
+ 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! */
+ if (! mi_breakpoint_observers_installed)
+ {
+ observer_attach_breakpoint_created (breakpoint_notify);
+ observer_attach_breakpoint_modified (breakpoint_notify);
+ observer_attach_breakpoint_deleted (breakpoint_notify);
+ mi_breakpoint_observers_installed = 1;
+ }
+
+ mi_can_breakpoint_notify = 1;
+ /* 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."));
+ }
+ }
+ mi_can_breakpoint_notify = 0;
+ if (e.reason < 0)
+ throw_exception (e);
+}
+
+
Index: gdb/mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.34
diff -u -p -r1.34 mi-cmds.c
--- gdb/mi/mi-cmds.c 4 Jul 2008 09:04:36 -0000 1.34
+++ gdb/mi/mi-cmds.c 31 Jul 2008 13:56:11 -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.32
diff -u -p -r1.32 mi-cmds.h
--- gdb/mi/mi-cmds.h 29 Jun 2008 17:36:36 -0000 1.32
+++ gdb/mi/mi-cmds.h 31 Jul 2008 13:56:11 -0000
@@ -38,6 +38,7 @@ typedef void (mi_cmd_argv_ftype) (char *
/* 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;