This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA] deleting breakpoints inside of 'commands' (again)
- To: Fernando Nasser <fnasser at redhat dot com>
- Subject: Re: [RFA] deleting breakpoints inside of 'commands' (again)
- From: Michael Snyder <msnyder at cygnus dot com>
- Date: Mon, 05 Nov 2001 15:37:12 -0800
- CC: Don Howard <dhoward at redhat dot com>, gdb-patches at sources dot redhat dot com
- Organization: Red Hat
- References: <Pine.LNX.4.33.0110311345410.19444-100000@theotherone> <3BE213DF.8288375D@redhat.com>
Fernando Nasser wrote:
>
> Don Howard wrote:
> >
> > This implementation makes a copy of commands list that contain 'delete'
> > or 'clear' commands. It also attempts to clean up when an error in
> > encountered. Comments?
Don, I hesitate to say anything, because I know this has been beaten
to death already, but does this method account for the possibility that
the list might contain a call to another user command which in turn
calls "delete" or "clear"?
Michael
> >
>
> This is much nicer. Thanks!
>
> The cli part is approved.
>
> Fernando
>
> P.S.: An extra blank line slipped in at the end of your breakpoint.c
> patch.
>
> > 2001-10-31 Don Howard <dhoward@redhat.com>
> >
> > * breakpoint.c (bpstat_do_actions): Avoid deleting a 'commands'
> > list while executing that list. Thanks to Pierre Muller
> > <muller@ics.u-strasbg.fr> for suggesting this implementation.
> > (cleanup_dup_command_lines): New function.
> > * cli/cli-script.c (dup_command_lines): New function.
> > * defs.h: Added declaration of new function.
> >
> > Index: breakpoint.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/breakpoint.c,v
> > retrieving revision 1.55
> > diff -p -u -w -r1.55 breakpoint.c
> > --- breakpoint.c 2001/10/20 23:54:29 1.55
> > +++ breakpoint.c 2001/10/31 21:48:28
> > @@ -1790,6 +1790,12 @@ cleanup_executing_breakpoints (PTR ignor
> > executing_breakpoint_commands = 0;
> > }
> >
> > +static void
> > +cleanup_dup_command_lines (PTR cmds)
> > +{
> > + free_command_lines (cmds);
> > +}
> > +
> > /* Execute all the commands associated with all the breakpoints at this
> > location. Any of these commands could cause the process to proceed
> > beyond this point, etc. We look out for such changes by checking
> > @@ -1800,7 +1806,6 @@ bpstat_do_actions (bpstat *bsp)
> > {
> > bpstat bs;
> > struct cleanup *old_chain;
> > - struct command_line *cmd;
> >
> > /* Avoid endless recursion if a `source' command is contained
> > in bs->commands. */
> > @@ -1824,17 +1829,40 @@ top:
> >
> > breakpoint_proceeded = 0;
> > for (; bs != NULL; bs = bs->next)
> > + {
> > + struct command_line *cmd;
> > + struct cleanup *new_old_chain;
> > +
> > + cmd = 0;
> > + new_old_chain = 0;
> > +
> > + /* If the command list for this breakpoint includes a statement
> > + that deletes breakpoints, we assume that the target may be
> > + this breakpoint, so we make a copy of the command list to
> > + avoid walking a list that has been deleted. */
> > +
> > + for (cmd = bs->commands; cmd; cmd = cmd->next)
> > {
> > - cmd = bs->commands;
> > - while (cmd != NULL)
> > + if (!new_old_chain &&
> > + (strncmp (cmd->line, "dele", 4) == 0 ||
> > + strncmp (cmd->line, "clea", 4) == 0))
> > {
> > + cmd = dup_command_lines (cmd);
> > + new_old_chain = make_cleanup (cleanup_dup_command_lines, cmd);
> > + }
> > +
> > execute_control_command (cmd);
> >
> > if (breakpoint_proceeded)
> > break;
> > - else
> > - cmd = cmd->next;
> > }
> > +
> > + if (new_old_chain)
> > + {
> > + free_command_lines (&cmd);
> > + discard_cleanups (new_old_chain);
> > + }
> > +
> > if (breakpoint_proceeded)
> > /* The inferior is proceeded by the command; bomb out now.
> > The bpstat chain has been blown away by wait_for_inferior.
> > @@ -1844,6 +1872,7 @@ top:
> > else
> > bs->commands = NULL;
> > }
> > +
> >
> > executing_breakpoint_commands = 0;
> > discard_cleanups (old_chain);
> > Index: defs.h
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/defs.h,v
> > retrieving revision 1.64
> > diff -p -u -w -r1.64 defs.h
> > --- defs.h 2001/10/17 20:35:31 1.64
> > +++ defs.h 2001/10/31 21:48:28
> > @@ -843,6 +843,7 @@ struct command_line
> > extern struct command_line *read_command_lines (char *, int);
> >
> > extern void free_command_lines (struct command_line **);
> > +extern struct command_line * dup_command_lines (struct command_line *);
> >
> > /* To continue the execution commands when running gdb asynchronously.
> > A continuation structure contains a pointer to a function to be called
> > Index: cli/cli-script.c
> > ===================================================================
> > RCS file: /cvs/src/src/gdb/cli/cli-script.c,v
> > retrieving revision 1.7
> > diff -p -u -w -r1.7 cli-script.c
> > --- cli-script.c 2001/06/17 15:16:12 1.7
> > +++ cli-script.c 2001/10/31 21:48:29
> > @@ -1005,6 +1005,59 @@ read_command_lines (char *prompt_arg, in
> > return (head);
> > }
> >
> > +/* Duplicate a chain of struct command_line's */
> > +
> > +struct command_line *
> > +dup_command_lines (struct command_line *l)
> > +{
> > + struct command_line *dup = NULL;
> > + register struct command_line *next = NULL;
> > +
> > +
> > + for (; l ; l = l->next)
> > + {
> > + if (next == NULL)
> > + {
> > + dup = next = (struct command_line *)
> > + xmalloc (sizeof (struct command_line));
> > + }
> > + else
> > + {
> > + next->next = (struct command_line *)
> > + xmalloc (sizeof (struct command_line));
> > +
> > + next = next->next;
> > + }
> > +
> > +
> > + if (next == NULL)
> > + return NULL;
> > +
> > +
> > + next->next = NULL;
> > + next->line = xstrdup (l->line);
> > + next->control_type = l->control_type;
> > + next->body_count = l->body_count;
> > +
> > +
> > + if (l->body_count > 0)
> > + {
> > + int i;
> > + struct command_line **blist = l->body_list;
> > +
> > + next->body_list =
> > + (struct command_line **) xmalloc (sizeof (struct command_line *)
> > + * l->body_count);
> > +
> > + for (i = 0; i < l->body_count; i++, blist++)
> > + next->body_list[i] = dup_command_lines (*blist);
> > + }
> > + }
> > +
> > + return dup;
> > +}
> > +
> > +
> > /* Free a chain of struct command_line's. */
> >
> > void
> >
> > --
> > -Don
> > dhoward@redhat.com
> > gdb engineering
>
> --
> Fernando Nasser
> Red Hat Canada Ltd. E-Mail: fnasser@redhat.com
> 2323 Yonge Street, Suite #300
> Toronto, Ontario M4P 2C9