aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2008-07-12 19:25:42 +0000
committerPedro Alves <palves@redhat.com>2008-07-12 19:25:42 +0000
commit604ead4a925d04413de72b61cfc3d39eeacf6fae (patch)
tree02ca148276a340cf7766b2a70f19718fbb1ede18
parentbfec99b27cdfd81789214ba9e7b648c9d0dccb77 (diff)
downloadgdb-604ead4a925d04413de72b61cfc3d39eeacf6fae.zip
gdb-604ead4a925d04413de72b61cfc3d39eeacf6fae.tar.gz
gdb-604ead4a925d04413de72b61cfc3d39eeacf6fae.tar.bz2
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.
-rw-r--r--gdb/ChangeLog51
-rw-r--r--gdb/breakpoint.c7
-rw-r--r--gdb/defs.h17
-rw-r--r--gdb/event-top.c1
-rw-r--r--gdb/inf-loop.c12
-rw-r--r--gdb/infcmd.c75
-rw-r--r--gdb/interps.c2
-rw-r--r--gdb/utils.c93
8 files changed, 150 insertions, 108 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 7b6f675..0815ca3 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,56 @@
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.
* top.c (execute_command): Remove unused arg1 and arg2 locals.
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index ecef7fd..55cd0d8 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -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);
diff --git a/gdb/defs.h b/gdb/defs.h
index 2be982a..6e6aa80 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -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). */
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 681dca8..722c28e 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -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);
}
diff --git a/gdb/inf-loop.c b/gdb/inf-loop.c
index 0572d8c..725b57c 100644
--- a/gdb/inf-loop.c
+++ b/gdb/inf-loop.c
@@ -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:
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 810ae91..8184cf0 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -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 ();
}
@@ -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;
}
diff --git a/gdb/interps.c b/gdb/interps.c
index 0ebc3f4..b4c804a 100644
--- a/gdb/interps.c
+++ b/gdb/interps.c
@@ -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->
diff --git a/gdb/utils.c b/gdb/utils.c
index 7f8446b..2b34d3e 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -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);
}