2008-07-12 Pedro Alves <pedro@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Sat, 12 Jul 2008 19:25:42 +0000 (19:25 +0000)
committerPedro Alves <palves@redhat.com>
Sat, 12 Jul 2008 19:25:42 +0000 (19:25 +0000)
Rewrite continuations internals on top of cleanups and plug
continuation arguments leaks.

* defs.h (struct continuation): Make it opaque.
(add_continuation, add_intermediate_continuation): Drop the int
argument of the continuation hook argument.  Add
continuation_free_args argument.
(do_all_continuations, do_all_intermediate_continuations): Drop
the error_p argument.

* utils.c (add_continuation): Drop the int argument of the
continuation hook argument.  Add continuation_free_args argument.
Reimplement on top of cleanups.
(do_all_continuations): Drop error argument.  Reimplement on top
of cleanups.
(discard_all_continuations): Reimplement on top of cleanups.
(add_intermediate_continuation): Drop the int argument of the
continuation hook argument.  Add continuation_free_args argument.
Reimplement on top of cleanups.
(do_all_intermediate_continuations): Drop error argument.
Reimplement on top of cleanups.
(discard_all_intermediate_continuations): Reimplement on top of
cleanups.

* breakpoint.c (until_break_command_continuation): Drop error
argument.  Add xfree as continuation argument deleter.

* inf-loop.c (inferior_event_handler): On error, discard all
continuations.  Adjust to new do_all_intermediate_continuations
and do_all_continuations interfaces.

* infcmd.c (step_1_continuation): Drop error_p argument.  Adjust.
Pass xfree as continuation argument deleter.
(finish_command_continuation): Drop error_p argument.  Adjust.
(finish_command_continuation_free_arg): New.
(finish_command): Pass finish_command_continuation_free_arg as
continuation argument deleter.  Adjust to new do_all_continuations
interfaces.
(attach_command_continuation): Drop error_p argument.
(attach_command_continuation_free_args): New.
(attach_command): Pass attach_command_continuation_free_args as
continuation argument deleter.

* interps.c (interp_set): Adjust to new do_all_continuations
interfaces.

* event-top.c (stdin_event_handler): In error, also discard the
intermediate continuations.

gdb/ChangeLog
gdb/breakpoint.c
gdb/defs.h
gdb/event-top.c
gdb/inf-loop.c
gdb/infcmd.c
gdb/interps.c
gdb/utils.c

index 7b6f6755cbc8ccbfbc6a6ab11616ca5470ab04f2..0815ca3327b82aef51f3ecfb3367772343be2574 100644 (file)
@@ -1,3 +1,54 @@
+2008-07-12  Pedro Alves  <pedro@codesourcery.com>
+
+       Rewrite continuations internals on top of cleanups and plug
+       continuation arguments leaks.
+
+       * defs.h (struct continuation): Make it opaque.
+       (add_continuation, add_intermediate_continuation): Drop the int
+       argument of the continuation hook argument.  Add
+       continuation_free_args argument.
+       (do_all_continuations, do_all_intermediate_continuations): Drop
+       the error_p argument.
+
+       * utils.c (add_continuation): Drop the int argument of the
+       continuation hook argument.  Add continuation_free_args argument.
+       Reimplement on top of cleanups.
+       (do_all_continuations): Drop error argument.  Reimplement on top
+       of cleanups.
+       (discard_all_continuations): Reimplement on top of cleanups.
+       (add_intermediate_continuation): Drop the int argument of the
+       continuation hook argument.  Add continuation_free_args argument.
+       Reimplement on top of cleanups.
+       (do_all_intermediate_continuations): Drop error argument.
+       Reimplement on top of cleanups.
+       (discard_all_intermediate_continuations): Reimplement on top of
+       cleanups.
+
+       * breakpoint.c (until_break_command_continuation): Drop error
+       argument.  Add xfree as continuation argument deleter.
+
+       * inf-loop.c (inferior_event_handler): On error, discard all
+       continuations.  Adjust to new do_all_intermediate_continuations
+       and do_all_continuations interfaces.
+
+       * infcmd.c (step_1_continuation): Drop error_p argument.  Adjust.
+       Pass xfree as continuation argument deleter.
+       (finish_command_continuation): Drop error_p argument.  Adjust.
+       (finish_command_continuation_free_arg): New.
+       (finish_command): Pass finish_command_continuation_free_arg as
+       continuation argument deleter.  Adjust to new do_all_continuations
+       interfaces.
+       (attach_command_continuation): Drop error_p argument.
+       (attach_command_continuation_free_args): New.
+       (attach_command): Pass attach_command_continuation_free_args as
+       continuation argument deleter.
+
+       * interps.c (interp_set): Adjust to new do_all_continuations
+       interfaces.
+
+       * event-top.c (stdin_event_handler): In error, also discard the
+       intermediate continuations.
+
 2008-07-12  Pedro Alves  <pedro@codesourcery.com>
 
        Replace struct continuation_args by void* and per command structs.
index ecef7fd59452258ea24af9248f9149c4366cc95b..55cd0d86a8234bf9e1734b8a0ed477e6233c4766 100644 (file)
@@ -62,8 +62,6 @@
 
 /* Prototypes for local functions. */
 
-static void until_break_command_continuation (void *arg, int error);
-
 static void catch_command_1 (char *, int, int);
 
 static void enable_delete_command (char *, int);
@@ -6161,7 +6159,7 @@ struct until_break_command_continuation_args
    care of cleaning up the temporary breakpoints set up by the until
    command. */
 static void
-until_break_command_continuation (void *arg, int error)
+until_break_command_continuation (void *arg)
 {
   struct until_break_command_continuation_args *a = arg;
 
@@ -6243,7 +6241,8 @@ until_break_command (char *arg, int from_tty, int anywhere)
       args->breakpoint2 = breakpoint2;
 
       discard_cleanups (old_chain);
-      add_continuation (until_break_command_continuation, args);
+      add_continuation (until_break_command_continuation, args,
+                       xfree);
     }
   else
     do_cleanups (old_chain);
index 2be982aff54ea51faa3094bcdccbb911b332cbb5..6e6aa807bdbbe2ec49b6bbc43cb4cd75b45efbb7 100644 (file)
@@ -677,12 +677,7 @@ extern void free_command_lines (struct command_line **);
    used by the finish and until commands, and in the remote protocol
    when opening an extended-remote connection. */
 
-struct continuation
-  {
-    void (*continuation_hook) (void *, int);
-    void *args;
-    struct continuation *next;
-  };
+struct continuation;
 
 /* In infrun.c. */
 extern struct continuation *cmd_continuation;
@@ -690,12 +685,14 @@ extern struct continuation *cmd_continuation;
 extern struct continuation *intermediate_continuation;
 
 /* From utils.c */
-extern void add_continuation (void (*)(void *, int), void *);
-extern void do_all_continuations (int error);
+extern void add_continuation (void (*)(void *), void *,
+                             void (*)(void *));
+extern void do_all_continuations (void);
 extern void discard_all_continuations (void);
 
-extern void add_intermediate_continuation (void (*)(void *, int), void *);
-extern void do_all_intermediate_continuations (int error);
+extern void add_intermediate_continuation (void (*)(void *), void *,
+                                          void (*)(void *));
+extern void do_all_intermediate_continuations (void);
 extern void discard_all_intermediate_continuations (void);
 
 /* String containing the current directory (what getwd would return).  */
index 681dca8a64da00034e192f55d6799ad9ef115c98..722c28e1792ce0b2a609deaa7c91aa7a85252057 100644 (file)
@@ -425,6 +425,7 @@ stdin_event_handler (int error, gdb_client_data client_data)
       printf_unfiltered (_("error detected on stdin\n"));
       delete_file_handler (input_fd);
       discard_all_continuations ();
+      discard_all_intermediate_continuations ();
       /* If stdin died, we may as well kill gdb. */
       quit_command ((char *) 0, stdin == instream);
     }
index 0572d8ce016b08a58da55009e9639fec35e91a4a..725b57cf901fcbfcd6920d43dbebc346a53ac9da 100644 (file)
@@ -52,7 +52,8 @@ inferior_event_handler (enum inferior_event_type event_type,
       printf_unfiltered (_("error detected from target.\n"));
       target_async (NULL, 0);
       pop_target ();
-      do_all_continuations (1);
+      discard_all_intermediate_continuations ();
+      discard_all_continuations ();
       async_enable_stdin ();
       break;
 
@@ -66,7 +67,8 @@ inferior_event_handler (enum inferior_event_type event_type,
        {
          target_async (NULL, 0);
          pop_target ();
-         do_all_continuations (1);
+         discard_all_intermediate_continuations ();
+         discard_all_continuations ();
          async_enable_stdin ();
          display_gdb_prompt (0);
        }
@@ -96,13 +98,13 @@ inferior_event_handler (enum inferior_event_type event_type,
         touch the inferior memory, e.g. to remove breakpoints, so run
         them before running breakpoint commands, which may resume the
         target.  */
-      do_all_intermediate_continuations (0);
+      do_all_intermediate_continuations ();
 
       /* Always finish the previous command before running any
         breakpoint commands.  Any stop cancels the previous command.
         E.g. a "finish" or "step-n" command interrupted by an
         unrelated breakpoint is canceled.  */
-      do_all_continuations (0);
+      do_all_continuations ();
 
       if (current_language != expected_language
          && language_mode == language_mode_auto)
@@ -123,7 +125,7 @@ inferior_event_handler (enum inferior_event_type event_type,
     case INF_EXEC_CONTINUE:
       /* Is there anything left to do for the command issued to
          complete? */
-      do_all_intermediate_continuations (0);
+      do_all_intermediate_continuations ();
       break;
 
     case INF_QUIT_REQ: 
index 810ae91009b880c573b4bd94310b99d40f1b544f..8184cf04c51a0cdeac60eb11bb8347f13956aa63 100644 (file)
@@ -73,8 +73,6 @@ static void nofp_registers_info (char *, int);
 static void print_return_value (struct type *func_type,
                                struct type *value_type);
 
-static void finish_command_continuation (void *args, int error_p);
-
 static void until_next_command (int);
 
 static void until_command (char *, int);
@@ -107,7 +105,6 @@ static void jump_command (char *, int);
 
 static void step_1 (int, int, char *);
 static void step_once (int skip_subroutines, int single_inst, int count, int thread);
-static void step_1_continuation (void *args, int error_p);
 
 static void next_command (char *, int);
 
@@ -877,15 +874,14 @@ struct step_1_continuation_args
    proceed(), via step_once(). Basically it is like step_once and
    step_1_continuation are co-recursive. */
 static void
-step_1_continuation (void *args, int error_p)
+step_1_continuation (void *args)
 {
   struct step_1_continuation_args *a = args;
 
-  if (error_p || !step_multi || !stop_step)
+  if (!step_multi || !stop_step)
     {
-      /* We either hit an error, or stopped for some reason
-        that is not stepping, or there are no further steps
-        to make.  Cleanup.  */
+      /* If we stopped for some reason that is not stepping there are
+        no further steps to make.  Cleanup.  */
       if (!a->single_inst || a->skip_subroutines)
        delete_longjmp_breakpoint (a->thread);
       step_multi = 0;
@@ -960,7 +956,7 @@ which has no line number information.\n"), name);
       args->single_inst = single_inst;
       args->count = count;
       args->thread = thread;
-      add_intermediate_continuation (step_1_continuation, args);
+      add_intermediate_continuation (step_1_continuation, args, xfree);
     }
 }
 
@@ -1325,35 +1321,44 @@ struct finish_command_continuation_args
 };
 
 static void
-finish_command_continuation (void *arg, int error_p)
+finish_command_continuation (void *arg)
 {
   struct finish_command_continuation_args *a = arg;
 
-  if (!error_p)
+  if (bpstat_find_breakpoint (stop_bpstat, a->breakpoint) != NULL
+      && a->function != NULL)
     {
-      if (bpstat_find_breakpoint (stop_bpstat, a->breakpoint) != NULL
-         && a->function != NULL)
-       {
-         struct type *value_type;
+      struct type *value_type;
 
-         value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
-         if (!value_type)
-           internal_error (__FILE__, __LINE__,
-                           _("finish_command: function has no target type"));
-
-         if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
-           print_return_value (SYMBOL_TYPE (a->function), value_type);
-       }
+      value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (a->function));
+      if (!value_type)
+       internal_error (__FILE__, __LINE__,
+                       _("finish_command: function has no target type"));
 
-      /* We suppress normal call of normal_stop observer and do it here so that
-        that *stopped notification includes the return value.  */
-      observer_notify_normal_stop (stop_bpstat);
+      if (TYPE_CODE (value_type) != TYPE_CODE_VOID)
+       print_return_value (SYMBOL_TYPE (a->function), value_type);
     }
 
+  /* We suppress normal call of normal_stop observer and do it here so
+     that that *stopped notification includes the return value.  */
+  /* NOTE: This is broken in non-stop mode.  There is no guarantee the
+     next stop will be in the same thread that we started doing a
+     finish on.  This suppressing (or some other replacement means)
+     should be a thread property.  */
+  observer_notify_normal_stop (stop_bpstat);
   suppress_stop_observer = 0;
   delete_breakpoint (a->breakpoint);
 }
 
+static void
+finish_command_continuation_free_arg (void *arg)
+{
+  /* NOTE: See finish_command_continuation.  This would go away, if
+     this suppressing is made a thread property.  */
+  suppress_stop_observer = 0;
+  xfree (arg);
+}
+
 /* "finish": Set a temporary breakpoint at the place the selected
    frame will return to, then continue.  */
 
@@ -1425,11 +1430,12 @@ finish_command (char *arg, int from_tty)
 
   cargs->breakpoint = breakpoint;
   cargs->function = function;
-  add_continuation (finish_command_continuation, cargs);
+  add_continuation (finish_command_continuation, cargs,
+                   finish_command_continuation_free_arg);
 
   discard_cleanups (old_chain);
   if (!target_can_async_p ())
-    do_all_continuations (0);
+    do_all_continuations ();
 }
 \f
 
@@ -1982,12 +1988,20 @@ struct attach_command_continuation_args
 };
 
 static void
-attach_command_continuation (void *args, int error_p)
+attach_command_continuation (void *args)
 {
   struct attach_command_continuation_args *a = args;
   attach_command_post_wait (a->args, a->from_tty, a->async_exec);
 }
 
+static void
+attach_command_continuation_free_args (void *args)
+{
+  struct attach_command_continuation_args *a = args;
+  xfree (a->args);
+  xfree (a);
+}
+
 void
 attach_command (char *args, int from_tty)
 {
@@ -2076,7 +2090,8 @@ attach_command (char *args, int from_tty)
          a->args = xstrdup (args);
          a->from_tty = from_tty;
          a->async_exec = async_exec;
-         add_continuation (attach_command_continuation, a);
+         add_continuation (attach_command_continuation, a,
+                           attach_command_continuation_free_args);
          return;
        }
 
index 0ebc3f48e2b1972605a0672ddb6eb1f91e1e4269..b4c804afd02dd0cfb96ca6f6bf554e0d3441f19a 100644 (file)
@@ -148,7 +148,7 @@ interp_set (struct interp *interp, int top_level)
 
   if (current_interpreter != NULL)
     {
-      do_all_continuations (0);
+      do_all_continuations ();
       ui_out_flush (uiout);
       if (current_interpreter->procs->suspend_proc
          && !current_interpreter->procs->suspend_proc (current_interpreter->
index 7f8446bc5726b0024746308e22c11510d38c971b..2b34d3e02004352c187aeef0c7cf453fb544ea70 100644 (file)
@@ -473,16 +473,16 @@ null_cleanup (void *arg)
 /* Add a continuation to the continuation list, the global list
    cmd_continuation. The new continuation will be added at the front.*/
 void
-add_continuation (void (*continuation_hook) (void *, int), void *args)
+add_continuation (void (*continuation_hook) (void *), void *args,
+                 void (*continuation_free_args) (void *))
 {
-  struct continuation *continuation_ptr;
+  struct cleanup **as_cleanup_p = (struct cleanup **) &cmd_continuation;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
 
-  continuation_ptr =
-    (struct continuation *) xmalloc (sizeof (struct continuation));
-  continuation_ptr->continuation_hook = continuation_hook;
-  continuation_ptr->args = args;
-  continuation_ptr->next = cmd_continuation;
-  cmd_continuation = continuation_ptr;
+  make_my_cleanup2 (as_cleanup_p,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
 }
 
 /* Walk down the cmd_continuation list, and execute all the
@@ -494,26 +494,20 @@ add_continuation (void (*continuation_hook) (void *, int), void *args)
    and do the continuations from there on, instead of using the
    global beginning of list as our iteration pointer.  */
 void
-do_all_continuations (int error)
+do_all_continuations (void)
 {
-  struct continuation *continuation_ptr;
-  struct continuation *saved_continuation;
+  struct cleanup *continuation_ptr;
 
   /* Copy the list header into another pointer, and set the global
      list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of
-     the preexisting continuations will not be affected. */
-  continuation_ptr = cmd_continuation;
+     effect of invoking the continuations and the processing of the
+     preexisting continuations will not be affected.  */
+
+  continuation_ptr = (struct cleanup *) cmd_continuation;
   cmd_continuation = NULL;
 
   /* Work now on the list we have set aside.  */
-  while (continuation_ptr)
-    {
-      (continuation_ptr->continuation_hook) (continuation_ptr->args, error);
-      saved_continuation = continuation_ptr;
-      continuation_ptr = continuation_ptr->next;
-      xfree (saved_continuation);
-    }
+  do_my_cleanups (&continuation_ptr, NULL);
 }
 
 /* Walk down the cmd_continuation list, and get rid of all the
@@ -521,14 +515,8 @@ do_all_continuations (int error)
 void
 discard_all_continuations (void)
 {
-  struct continuation *continuation_ptr;
-
-  while (cmd_continuation)
-    {
-      continuation_ptr = cmd_continuation;
-      cmd_continuation = continuation_ptr->next;
-      xfree (continuation_ptr);
-    }
+  struct cleanup **continuation_ptr = (struct cleanup **) &cmd_continuation;
+  discard_my_cleanups (continuation_ptr, NULL);
 }
 
 /* Add a continuation to the continuation list, the global list
@@ -536,16 +524,16 @@ discard_all_continuations (void)
    the front.  */
 void
 add_intermediate_continuation (void (*continuation_hook)
-                              (void *, int), void *args)
+                              (void *), void *args,
+                              void (*continuation_free_args) (void *))
 {
-  struct continuation *continuation_ptr;
+  struct cleanup **as_cleanup_p = (struct cleanup **) &intermediate_continuation;
+  make_cleanup_ftype *continuation_hook_fn = continuation_hook;
 
-  continuation_ptr =
-    (struct continuation *) xmalloc (sizeof (struct continuation));
-  continuation_ptr->continuation_hook = continuation_hook;
-  continuation_ptr->args = args;
-  continuation_ptr->next = intermediate_continuation;
-  intermediate_continuation = continuation_ptr;
+  make_my_cleanup2 (as_cleanup_p,
+                   continuation_hook_fn,
+                   args,
+                   continuation_free_args);
 }
 
 /* Walk down the cmd_continuation list, and execute all the
@@ -557,26 +545,20 @@ add_intermediate_continuation (void (*continuation_hook)
    and do the continuations from there on, instead of using the
    global beginning of list as our iteration pointer.*/
 void
-do_all_intermediate_continuations (int error)
+do_all_intermediate_continuations (void)
 {
-  struct continuation *continuation_ptr;
-  struct continuation *saved_continuation;
+  struct cleanup *continuation_ptr;
 
   /* Copy the list header into another pointer, and set the global
      list header to null, so that the global list can change as a side
-     effect of invoking the continuations and the processing of
-     the preexisting continuations will not be affected. */
-  continuation_ptr = intermediate_continuation;
+     effect of invoking the continuations and the processing of the
+     preexisting continuations will not be affected.  */
+
+  continuation_ptr = (struct cleanup *) intermediate_continuation;
   intermediate_continuation = NULL;
 
   /* Work now on the list we have set aside.  */
-  while (continuation_ptr)
-    {
-      (continuation_ptr->continuation_hook) (continuation_ptr->args, error);
-      saved_continuation = continuation_ptr;
-      continuation_ptr = continuation_ptr->next;
-      xfree (saved_continuation);
-    }
+  do_my_cleanups (&continuation_ptr, NULL);
 }
 
 /* Walk down the cmd_continuation list, and get rid of all the
@@ -584,14 +566,9 @@ do_all_intermediate_continuations (int error)
 void
 discard_all_intermediate_continuations (void)
 {
-  struct continuation *continuation_ptr;
-
-  while (intermediate_continuation)
-    {
-      continuation_ptr = intermediate_continuation;
-      intermediate_continuation = continuation_ptr->next;
-      xfree (continuation_ptr);
-    }
+  struct cleanup **continuation_ptr
+    = (struct cleanup **) &intermediate_continuation;
+  discard_my_cleanups (continuation_ptr, NULL);
 }
 \f