Re: [BUG:MI] -break-list doesn't list multiple breakpoints

Nick Roberts
2008-01-13T21:26:10Z

> > I'm not sure of the logic of committing an incomplete patch, but in any
> > case I think this needs to be fixed before the next release.
>
> I disagree. If someone needs this functionality in MI, they are
> invited to contribute it. Unless I'm completely mistaken, what
> happened previously in MI was even worse.

Here's a patch that fixes this but does much more. The 'fix' works by
removing the frame details in the MI output:

(gdb)
-break-insert 10
^done

this means that the condition:

&& !ui_out_is_mi_like_p (uiout))

can be removed from print_one_breakpoint so that -break-list prints
details of all the multiple breakpoint locations.

This may seem extreme but my reasoning is that a front end can keep an up-to
date breakpoint list by running -break-list behind the user's back, which is
presumably relatively inxepensive. With Emacs, I currently use "info break"
to do this as it easier than trying to parse the output of the breakpoint
commands. I would probably never use the output of -break-insert because
the user could set a breakpoint using the CLI "break" command from the
GUD buffer, and commands like "enable" and "disable" (and "-break-enable"/
"break-disable") provide no output.

By comparison, it's also interesting to note that frame details get printed
using "--fullname" whenever they change, i.e., when execution stops or with
commands like "up" and "frame", while in MI the details only get printed when
execution stops:

(gdb)
-stack-select-frame 1
^done
(gdb)

This necessitates running -stack-info-frame behind the user's back. Even if
-stack-select-frame did print frame details, Emacs would still have to use
-stack-info-frame because of the GUD buffer again.

This patch has the added attraction of removing the last use of
deprecated_set_gdb_event_hooks and clear_gdb_event_hooks, so they
could also be removed from gdb-events.sh/c.

--
Nick http://www.inet.net.nz/~nickrob

2008-01-14 Nick Roberts <nickrob@snap.net.nz>

* mi/mi-cmd-break.c (breakpoint_notify, breakpoint_hooks): Delete.
(mi_cmd_break_insert): Don't use deprecated_set_gdb_event_hooks.

* breakpoint.c (struct captured_breakpoint_query_args)
(do_captured_breakpoint_query, gdb_breakpoint_query): Delete.
(print_one_breakpoint): Call print_one_breakpoint_location from MI
too.

*** breakpoint.c.~1.296~ 2008-01-14 09:33:18.000000000 +1300
--- breakpoint.c 2008-01-14 09:33:38.000000000 +1300
*************** print_one_breakpoint (struct breakpoint
*** 3619,3626 ****
represent "breakpoint enabled, location disabled"
situation. */
if (b->loc
! && (b->loc->next || !b->loc->enabled)
! && !ui_out_is_mi_like_p (uiout))
{
struct bp_location *loc;
int n = 1;
--- 3619,3625 ----
represent "breakpoint enabled, location disabled"
situation. */
if (b->loc
! && (b->loc->next || !b->loc->enabled))
{
struct bp_location *loc;
int n = 1;
*************** print_one_breakpoint (struct breakpoint
*** 3631,3672 ****
}

- struct captured_breakpoint_query_args
- {
- int bnum;
- };
-
- static int
- do_captured_breakpoint_query (struct ui_out *uiout, void *data)
- {
- struct captured_breakpoint_query_args *args = data;
- struct breakpoint *b;
- CORE_ADDR dummy_addr = 0;
- ALL_BREAKPOINTS (b)
- {
- if (args->bnum == b->number)
- {
- print_one_breakpoint (b, &dummy_addr);
- return GDB_RC_OK;
- }
- }
- return GDB_RC_NONE;
- }
-
- enum gdb_rc
- gdb_breakpoint_query (struct ui_out *uiout, int bnum, char **error_message)
- {
- struct captured_breakpoint_query_args args;
- args.bnum = bnum;
- /* For the moment we don't trust print_one_breakpoint() to not throw
- an error. */
- if (catch_exceptions_with_msg (uiout, do_captured_breakpoint_query, &args,
- error_message, RETURN_MASK_ALL) < 0)
- return GDB_RC_FAIL;
- else
- return GDB_RC_OK;
- }
-
/* Return non-zero if B is user settable (breakpoints, watchpoints,
catchpoints, et.al.). */

--- 3630,3635 ----

*** mi-cmd-break.c.~1.18.~ 2008-01-04 10:24:34.000000000 +1300
--- mi-cmd-break.c 2008-01-13 23:30:11.000000000 +1300
*************** enum
*** 32,54 ****
FROM_TTY = 0
};

- /* Output a single breakpoint. */
-
- static void
- breakpoint_notify (int b)
- {
- gdb_breakpoint_query (uiout, b, NULL);
- }
-
-
- struct gdb_events breakpoint_hooks =
- {
- breakpoint_notify,
- breakpoint_notify,
- breakpoint_notify,
- };
-
-
enum bp_type
{
REG_BP,
--- 32,37 ----
*************** mi_cmd_break_insert (char *command, char
*** 70,76 ****
char *condition = NULL;
int pending = 0;
enum gdb_rc rc;
- struct gdb_events *old_hooks;
enum opt
{
HARDWARE_OPT, TEMP_OPT /*, REGEXP_OPT */ , CONDITION_OPT,
--- 53,58 ----
*************** mi_cmd_break_insert (char *command, char
*** 131,137 ****
address = argv[optind];

/* Now we have what we need, let's insert the breakpoint! */
- old_hooks = deprecated_set_gdb_event_hooks (&breakpoint_hooks);
switch (type)
{
case REG_BP:
--- 113,118 ----
*************** mi_cmd_break_insert (char *command, char
*** 161,167 ****
internal_error (__FILE__, __LINE__,
_("mi_cmd_break_insert: Bad switch."));
}
- deprecated_set_gdb_event_hooks (old_hooks);

if (rc == GDB_RC_FAIL)
return MI_CMD_ERROR;
--- 142,147 ----