This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
RFA: protect breakpoint commands from being freed
- From: Jim Blandy <jimb at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: 13 Dec 2003 00:56:39 -0500
- Subject: RFA: protect breakpoint commands from being freed
2003-12-02 Jim Blandy <jimb@redhat.com>
* breakpoint.c (bpstat_do_actions): To ensure that
clear_proceed_status doesn't free the command tree we're
evaluating out from under us, zero the bpstat's pointer to it, and
take care of freeing it ourselves.
* cli/cli-script.c (make_cleanup_free_command_lines): Make this
function externally visible.
* cli/cli-script.h (make_cleanup_free_command_lines): New
declaration.
Index: gdb/breakpoint.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/breakpoint.c,v
retrieving revision 1.361.2.1
diff -c -r1.361.2.1 breakpoint.c
*** gdb/breakpoint.c 22 Oct 2003 00:34:07 -0000 1.361.2.1
--- gdb/breakpoint.c 3 Dec 2003 04:31:28 -0000
***************
*** 1943,1949 ****
{
bpstat bs;
struct cleanup *old_chain;
- struct command_line *cmd;
/* Avoid endless recursion if a `source' command is contained
in bs->commands. */
--- 1943,1948 ----
***************
*** 1968,1974 ****
--- 1967,1989 ----
breakpoint_proceeded = 0;
for (; bs != NULL; bs = bs->next)
{
+ struct command_line *cmd;
+ struct cleanup *this_cmd_tree_chain;
+
+ /* Take ownership of the BSP's command tree, if it has one.
+
+ The command tree could legitimately contain commands like
+ 'step' and 'next', which call clear_proceed_status, which
+ frees stop_bpstat's command tree. To make sure this doesn't
+ free the tree we're executing out from under us, we need to
+ take ownership of the tree ourselves. Since a given bpstat's
+ commands are only executed once, we don't need to copy it; we
+ can clear the pointer in the bpstat, and make sure we free
+ the tree when we're done. */
cmd = bs->commands;
+ bs->commands = 0;
+ this_cmd_tree_chain = make_cleanup_free_command_lines (&cmd);
+
while (cmd != NULL)
{
execute_control_command (cmd);
***************
*** 1978,1991 ****
else
cmd = cmd->next;
}
if (breakpoint_proceeded)
/* The inferior is proceeded by the command; bomb out now.
The bpstat chain has been blown away by wait_for_inferior.
But since execution has stopped again, there is a new bpstat
to look at, so start over. */
goto top;
- else
- free_command_lines (&bs->commands);
}
do_cleanups (old_chain);
}
--- 1993,2008 ----
else
cmd = cmd->next;
}
+
+ /* We can free this command tree now. */
+ do_cleanups (this_cmd_tree_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.
But since execution has stopped again, there is a new bpstat
to look at, so start over. */
goto top;
}
do_cleanups (old_chain);
}
Index: gdb/cli/cli-script.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/cli/cli-script.c,v
retrieving revision 1.16
diff -c -r1.16 cli-script.c
*** gdb/cli/cli-script.c 15 Oct 2003 17:30:27 -0000 1.16
--- gdb/cli/cli-script.c 3 Dec 2003 04:31:31 -0000
***************
*** 36,44 ****
/* Prototypes for local functions */
- static struct cleanup *
- make_cleanup_free_command_lines (struct command_line **arg);
-
static enum command_control_type
recurse_read_control_structure (struct command_line *current_cmd);
--- 36,41 ----
***************
*** 1001,1007 ****
free_command_lines (arg);
}
! static struct cleanup *
make_cleanup_free_command_lines (struct command_line **arg)
{
return make_cleanup (do_free_command_lines_cleanup, arg);
--- 998,1004 ----
free_command_lines (arg);
}
! struct cleanup *
make_cleanup_free_command_lines (struct command_line **arg)
{
return make_cleanup (do_free_command_lines_cleanup, arg);
Index: gdb/cli/cli-script.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/cli/cli-script.h,v
retrieving revision 1.5
diff -c -r1.5 cli-script.h
*** gdb/cli/cli-script.h 16 Apr 2003 21:18:50 -0000 1.5
--- gdb/cli/cli-script.h 3 Dec 2003 04:31:31 -0000
***************
*** 47,52 ****
--- 47,54 ----
extern struct command_line * copy_command_lines (struct command_line *cmds);
+ struct cleanup *make_cleanup_free_command_lines (struct command_line **arg);
+
/* Exported to gdb/infrun.c */
extern void execute_user_command (struct cmd_list_element *c, char *args);