From: Pedro Alves Date: Sat, 12 Jul 2008 19:25:42 +0000 (+0000) Subject: 2008-07-12 Pedro Alves X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=604ead4a925d04413de72b61cfc3d39eeacf6fae;p=binutils-gdb.git 2008-07-12 Pedro Alves 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 7b6f6755cbc..0815ca3327b 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,54 @@ +2008-07-12 Pedro Alves + + 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 Replace struct continuation_args by void* and per command structs. diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ecef7fd5945..55cd0d86a82 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 2be982aff54..6e6aa807bdb 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 681dca8a64d..722c28e1792 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 0572d8ce016..725b57cf901 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 810ae91009b..8184cf04c51 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 0ebc3f48e2b..b4c804afd02 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 7f8446bc572..2b34d3e0200 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); }