* breakpoint.c (bpstat_do_actions): To ensure that
authorJim Blandy <jimb@codesourcery.com>
Mon, 22 Dec 2003 03:43:19 +0000 (03:43 +0000)
committerJim Blandy <jimb@codesourcery.com>
Mon, 22 Dec 2003 03:43:19 +0000 (03:43 +0000)
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.

gdb/ChangeLog
gdb/breakpoint.c
gdb/cli/cli-script.c
gdb/cli/cli-script.h

index a7c08e9..985ec69 100644 (file)
@@ -1,3 +1,14 @@
+2003-12-21  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.
+
 2003-12-20  Mark Kettenis  <kettenis@gnu.org>
 
        * x86-64-tdep.c (x86_64_dwarf_regmap): Map the Return Address to
index c535add..6a17368 100644 (file)
@@ -1992,7 +1992,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.  */
@@ -2017,7 +2016,23 @@ top:
   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);
@@ -2027,14 +2042,16 @@ top:
          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;
-      else
-       free_command_lines (&bs->commands);
     }
   do_cleanups (old_chain);
 }
index cac5408..a8375a3 100644 (file)
@@ -36,9 +36,6 @@
 
 /* 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);
 
@@ -1001,7 +998,7 @@ do_free_command_lines_cleanup (void *arg)
   free_command_lines (arg);
 }
 
-static struct cleanup *
+struct cleanup *
 make_cleanup_free_command_lines (struct command_line **arg)
 {
   return make_cleanup (do_free_command_lines_cleanup, arg);
index 03cb841..fc5c203 100644 (file)
@@ -47,6 +47,8 @@ extern void print_command_lines (struct ui_out *,
 
 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);