diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 24 | ||||
-rw-r--r-- | gdb/Makefile.in | 6 | ||||
-rw-r--r-- | gdb/cleanups.c | 245 | ||||
-rw-r--r-- | gdb/cleanups.h | 94 | ||||
-rw-r--r-- | gdb/defs.h | 63 | ||||
-rw-r--r-- | gdb/utils.c | 174 |
6 files changed, 372 insertions, 234 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8746d78..d6a4daa 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,29 @@ 2012-04-17 Doug Evans <dje@google.com> + * cleanups.h: New file. + * cleanups.c: New file. + * Makefile.in (SFILES): Add cleanups.c. + (HFILES_NO_SRCDIR): Add cleanups.h. + (COMMON_OBS): Add cleanups.o. + * defs.h (struct cleanup): Moved to cleanups.h. + (do_cleanups,do_final_cleanups): Ditto. + (discard_cleanups,discard_final_cleanups): Ditto + (make_cleanup,make_cleanup_dtor,make_final_cleanup): Ditto. + (save_cleanups,save_final_cleanups): Ditto. + (restore_cleanups,restore_final_cleanups): Ditto. + (null_cleanup): Ditto. + (make_my_cleanup,make_my_cleanup2): Ditto. + (discard_my_cleanups,save_my_cleanups,restore_my_cleanups): Ditto. + * utils.c (cleanup_chain,final_cleanup_chain): Moved to cleanups.c. + (do_cleanups,do_final_cleanups): Ditto. + (discard_cleanups,discard_final_cleanups): Ditto + (make_cleanup,make_cleanup_dtor,make_final_cleanup): Ditto. + (save_cleanups,save_final_cleanups): Ditto. + (restore_cleanups,restore_final_cleanups): Ditto. + (null_cleanup): Ditto. + (make_my_cleanup,make_my_cleanup2): Ditto. + (discard_my_cleanups,save_my_cleanups,restore_my_cleanups): Ditto. + * utils.c (make_cleanup_freeargv): Use make_cleanup instead of make_my_cleanup. (make_cleanup_dyn_string_delete): Ditto. diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 21fe3a7..8958acd 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -690,7 +690,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ bfd-target.c \ block.c blockframe.c breakpoint.c buildsym.c \ c-exp.y c-lang.c c-typeprint.c c-valprint.c \ - charset.c cli-out.c coffread.c coff-pe-read.c \ + charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \ complaints.c completer.c continuations.c corefile.c corelow.c \ cp-abi.c cp-support.c cp-namespace.c cp-valprint.c \ d-lang.c d-valprint.c \ @@ -783,7 +783,7 @@ objfiles.h vec.h disasm.h mips-tdep.h ser-base.h \ gdb_curses.h bfd-target.h memattr.h inferior.h ax.h dummy-frame.h \ inflow.h fbsd-nat.h ia64-libunwind-tdep.h completer.h inf-ttrace.h \ solib-target.h gdb_vfork.h alpha-tdep.h dwarf2expr.h \ -m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \ +m2-lang.h stack.h charset.h cleanups.h addrmap.h command.h solist.h source.h \ target.h prologue-value.h cp-abi.h tui/tui-hooks.h tui/tui.h \ tui/tui-file.h tui/tui-command.h tui/tui-disasm.h tui/tui-wingeneral.h \ tui/tui-windata.h tui/tui-data.h tui/tui-win.h tui/tui-stack.h \ @@ -858,7 +858,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \ auto-load.o auxv.o \ agent.o \ bfd-target.o \ - blockframe.o breakpoint.o findvar.o regcache.o \ + blockframe.o breakpoint.o findvar.o regcache.o cleanups.o \ charset.o continuations.o corelow.o disasm.o dummy-frame.o dfp.o \ source.o value.o eval.o valops.o valarith.o valprint.o printcmd.o \ block.o symtab.o psymtab.o symfile.o symmisc.o linespec.o dictionary.o \ diff --git a/gdb/cleanups.c b/gdb/cleanups.c new file mode 100644 index 0000000..9d893ac --- /dev/null +++ b/gdb/cleanups.c @@ -0,0 +1,245 @@ +/* Cleanup routines for GDB, the GNU debugger. + + Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#include "defs.h" + +/* Chain of cleanup actions established with make_cleanup, + to be executed if an error happens. */ + +/* Cleaned up after a failed command. */ +static struct cleanup *cleanup_chain; + +/* Cleaned up when gdb exits. */ +static struct cleanup *final_cleanup_chain; + +/* Main worker routine to create a cleanup. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + FUNCTION is the function to call to perform the cleanup. + ARG is passed to FUNCTION when called. + FREE_ARG, if non-NULL, is called after the cleanup is performed. + + The result is a pointer to the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. */ + +struct cleanup * +make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg, void (*free_arg) (void *)) +{ + struct cleanup *new + = (struct cleanup *) xmalloc (sizeof (struct cleanup)); + struct cleanup *old_chain = *pmy_chain; + + new->next = *pmy_chain; + new->function = function; + new->free_arg = free_arg; + new->arg = arg; + *pmy_chain = new; + + return old_chain; +} + +/* Worker routine to create a cleanup without a destructor. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + FUNCTION is the function to call to perform the cleanup. + ARG is passed to FUNCTION when called. + + The result is a pointer to the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. */ + +struct cleanup * +make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, + void *arg) +{ + return make_my_cleanup2 (pmy_chain, function, arg, NULL); +} + +/* Add a new cleanup to the cleanup_chain, + and return the previous chain pointer + to be passed later to do_cleanups or discard_cleanups. + Args are FUNCTION to clean up with, and ARG to pass to it. */ + +struct cleanup * +make_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&cleanup_chain, function, arg); +} + +/* Same as make_cleanup except also includes TDOR, a destructor to free ARG. + DTOR is invoked when the cleanup is performed or when it is discarded. */ + +struct cleanup * +make_cleanup_dtor (make_cleanup_ftype *function, void *arg, + void (*dtor) (void *)) +{ + return make_my_cleanup2 (&cleanup_chain, + function, arg, dtor); +} + +/* Same as make_cleanup except the cleanup is added to final_cleanup_chain. */ + +struct cleanup * +make_final_cleanup (make_cleanup_ftype *function, void *arg) +{ + return make_my_cleanup (&final_cleanup_chain, function, arg); +} + +/* Worker routine to perform cleanups. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + OLD_CHAIN is the result of a "make" cleanup routine. + Cleanups are performed until we get back to the old end of the chain. */ + +static void +do_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) +{ + struct cleanup *ptr; + + while ((ptr = *pmy_chain) != old_chain) + { + *pmy_chain = ptr->next; /* Do this first in case of recursion. */ + (*ptr->function) (ptr->arg); + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); + xfree (ptr); + } +} + +/* Discard cleanups and do the actions they describe + until we get back to the point OLD_CHAIN in the cleanup_chain. */ + +void +do_cleanups (struct cleanup *old_chain) +{ + do_my_cleanups (&cleanup_chain, old_chain); +} + +/* Discard cleanups and do the actions they describe + until we get back to the point OLD_CHAIN in the final_cleanup_chain. */ + +void +do_final_cleanups (struct cleanup *old_chain) +{ + do_my_cleanups (&final_cleanup_chain, old_chain); +} + +/* Main worker routine to discard cleanups. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + OLD_CHAIN is the result of a "make" cleanup routine. + Cleanups are discarded until we get back to the old end of the chain. */ + +void +discard_my_cleanups (struct cleanup **pmy_chain, + struct cleanup *old_chain) +{ + struct cleanup *ptr; + + while ((ptr = *pmy_chain) != old_chain) + { + *pmy_chain = ptr->next; + if (ptr->free_arg) + (*ptr->free_arg) (ptr->arg); + xfree (ptr); + } +} + +/* Discard cleanups, not doing the actions they describe, + until we get back to the point OLD_CHAIN in the cleanup chain. */ + +void +discard_cleanups (struct cleanup *old_chain) +{ + discard_my_cleanups (&cleanup_chain, old_chain); +} + +/* Discard final cleanups, not doing the actions they describe, + until we get back to the point OLD_CHAIN in the final cleanup chain. */ + +void +discard_final_cleanups (struct cleanup *old_chain) +{ + discard_my_cleanups (&final_cleanup_chain, old_chain); +} + +/* Main worker routine to save cleanups. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + The chain is emptied and the result is a pointer to the old chain. */ + +struct cleanup * +save_my_cleanups (struct cleanup **pmy_chain) +{ + struct cleanup *old_chain = *pmy_chain; + + *pmy_chain = 0; + return old_chain; +} + +/* Set the cleanup_chain to 0, and return the old cleanup_chain. */ + +struct cleanup * +save_cleanups (void) +{ + return save_my_cleanups (&cleanup_chain); +} + +/* Set the final_cleanup_chain to 0, and return the old + final_cleanup_chain. */ + +struct cleanup * +save_final_cleanups (void) +{ + return save_my_cleanups (&final_cleanup_chain); +} + +/* Main worker routine to save cleanups. + PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain. + The chain is restored from CHAIN. */ + +void +restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) +{ + *pmy_chain = chain; +} + +/* Restore the cleanup chain from a previously saved chain. */ + +void +restore_cleanups (struct cleanup *chain) +{ + restore_my_cleanups (&cleanup_chain, chain); +} + +/* Restore the final cleanup chain from a previously saved chain. */ + +void +restore_final_cleanups (struct cleanup *chain) +{ + restore_my_cleanups (&final_cleanup_chain, chain); +} + +/* Provide a known function that does nothing, to use as a base for + a possibly long chain of cleanups. This is useful where we + use the cleanup chain for handling normal cleanups as well as dealing + with cleanups that need to be done as a result of a call to error(). + In such cases, we may not be certain where the first cleanup is, unless + we have a do-nothing one to always use as the base. */ + +void +null_cleanup (void *arg) +{ +} diff --git a/gdb/cleanups.h b/gdb/cleanups.h new file mode 100644 index 0000000..80cbada --- /dev/null +++ b/gdb/cleanups.h @@ -0,0 +1,94 @@ +/* Cleanups. + Copyright (C) 1986, 1988-2005, 2007-2012 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef CLEANUPS_H +#define CLEANUPS_H + +/* The cleanup list records things that have to be undone + if an error happens (descriptors to be closed, memory to be freed, etc.) + Each link in the chain records a function to call and an + argument to give it. + + Use make_cleanup to add an element to the cleanup chain. + Use do_cleanups to do all cleanup actions back to a given + point in the chain. Use discard_cleanups to remove cleanups + from the chain back to a given point, not doing them. + + If the argument is pointer to allocated memory, then you need + to additionally set the 'free_arg' member to a function that will + free that memory. This function will be called both when the cleanup + is executed and when it's discarded. */ + +struct cleanup + { + struct cleanup *next; + void (*function) (void *); + void (*free_arg) (void *); + void *arg; + }; + +/* NOTE: cagney/2000-03-04: This typedef is strictly for the + make_cleanup function declarations below. Do not use this typedef + as a cast when passing functions into the make_cleanup() code. + Instead either use a bounce function or add a wrapper function. + Calling a f(char*) function with f(void*) is non-portable. */ +typedef void (make_cleanup_ftype) (void *); + +/* WARNING: The result of the "make cleanup" routines is not the intuitive + choice of being a handle on the just-created cleanup. Instead it is an + opaque handle of the cleanup mechanism and represents all cleanups created + from that point onwards. */ + +extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); + +extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, + void (*dtor) (void *)); + +extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); + +extern struct cleanup *make_my_cleanup (struct cleanup **, + make_cleanup_ftype *, void *); +extern struct cleanup *make_my_cleanup2 (struct cleanup **, + make_cleanup_ftype *, void *, + void (*free_arg) (void *)); + +/* A special value to pass to do_cleanups and do_final_cleanups + to tell them to do all cleanups. */ +#define ALL_CLEANUPS ((struct cleanup *)0) + +extern void do_cleanups (struct cleanup *); +extern void do_final_cleanups (struct cleanup *); + +extern void discard_cleanups (struct cleanup *); +extern void discard_final_cleanups (struct cleanup *); +extern void discard_my_cleanups (struct cleanup **, struct cleanup *); + +extern struct cleanup *save_cleanups (void); +extern struct cleanup *save_final_cleanups (void); +extern struct cleanup *save_my_cleanups (struct cleanup **); + +extern void restore_cleanups (struct cleanup *); +extern void restore_final_cleanups (struct cleanup *); +extern void restore_my_cleanups (struct cleanup **, struct cleanup *); + +/* A no-op cleanup. + This is useful when you want to establish a known reference point + to pass to do_cleanups. */ +extern void null_cleanup (void *); + +#endif /* CLEANUPS_H */ @@ -251,29 +251,6 @@ enum return_value_convention RETURN_VALUE_ABI_PRESERVES_ADDRESS, }; -/* the cleanup list records things that have to be undone - if an error happens (descriptors to be closed, memory to be freed, etc.) - Each link in the chain records a function to call and an - argument to give it. - - Use make_cleanup to add an element to the cleanup chain. - Use do_cleanups to do all cleanup actions back to a given - point in the chain. Use discard_cleanups to remove cleanups - from the chain back to a given point, not doing them. - - If the argument is pointer to allocated memory, then you need - to additionally set the 'free_arg' member to a function that will - free that memory. This function will be called both when the cleanup - is executed and when it's discarded. */ - -struct cleanup - { - struct cleanup *next; - void (*function) (void *); - void (*free_arg) (void *); - void *arg; - }; - /* vec.h-style vectors of strings want a typedef for char * or const char *. */ typedef char * char_ptr; @@ -313,26 +290,9 @@ extern void set_display_time (int); extern void set_display_space (int); -#define ALL_CLEANUPS ((struct cleanup *)0) - -extern void do_cleanups (struct cleanup *); -extern void do_final_cleanups (struct cleanup *); - -extern void discard_cleanups (struct cleanup *); -extern void discard_final_cleanups (struct cleanup *); -extern void discard_my_cleanups (struct cleanup **, struct cleanup *); - -/* NOTE: cagney/2000-03-04: This typedef is strictly for the - make_cleanup function declarations below. Do not use this typedef - as a cast when passing functions into the make_cleanup() code. - Instead either use a bounce function or add a wrapper function. - Calling a f(char*) function with f(void*) is non-portable. */ -typedef void (make_cleanup_ftype) (void *); - -extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); +/* Cleanup utilities. */ -extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, - void (*dtor) (void *)); +#include "cleanups.h" extern struct cleanup *make_cleanup_freeargv (char **); @@ -374,29 +334,10 @@ extern struct cleanup *make_cleanup_value_free (struct value *); struct so_list; extern struct cleanup *make_cleanup_free_so (struct so_list *so); -extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); - -extern struct cleanup *make_my_cleanup (struct cleanup **, - make_cleanup_ftype *, void *); - extern struct cleanup *make_cleanup_htab_delete (htab_t htab); -extern struct cleanup *make_my_cleanup2 (struct cleanup **, - make_cleanup_ftype *, void *, - void (*free_arg) (void *)); - -extern struct cleanup *save_cleanups (void); -extern struct cleanup *save_final_cleanups (void); -extern struct cleanup *save_my_cleanups (struct cleanup **); - -extern void restore_cleanups (struct cleanup *); -extern void restore_final_cleanups (struct cleanup *); -extern void restore_my_cleanups (struct cleanup **, struct cleanup *); - extern void free_current_contents (void *); -extern void null_cleanup (void *); - extern struct cleanup *make_command_stats_cleanup (int); extern int myread (int, char *, int); diff --git a/gdb/utils.c b/gdb/utils.c index a8f9e4f..b70edd8 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -99,8 +99,6 @@ static void vfprintf_maybe_filtered (struct ui_file *, const char *, static void fputs_maybe_filtered (const char *, struct ui_file *, int); -static void do_my_cleanups (struct cleanup **, struct cleanup *); - static void prompt_for_continue (void); static void set_screen_size (void); @@ -110,12 +108,6 @@ static void set_width (void); static int debug_timestamp = 0; -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; /* cleaned up after a failed command */ -static struct cleanup *final_cleanup_chain; /* cleaned up when gdb exits */ - /* Nonzero if we have job control. */ int job_control; @@ -172,31 +164,11 @@ show_pagination_enabled (struct ui_file *file, int from_tty, } +/* Cleanup utilities. -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&cleanup_chain, function, arg); -} - -struct cleanup * -make_cleanup_dtor (make_cleanup_ftype *function, void *arg, - void (*dtor) (void *)) -{ - return make_my_cleanup2 (&cleanup_chain, - function, arg, dtor); -} - -struct cleanup * -make_final_cleanup (make_cleanup_ftype *function, void *arg) -{ - return make_my_cleanup (&final_cleanup_chain, function, arg); -} + These are not defined in cleanups.c (nor declared in cleanups.h) + because while they use the "cleanup API" they are not part of the + "cleanup API". */ static void do_freeargv (void *arg) @@ -484,132 +456,6 @@ make_cleanup_free_so (struct so_list *so) return make_cleanup (do_free_so, so); } -struct cleanup * -make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg, void (*free_arg) (void *)) -{ - struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - struct cleanup *old_chain = *pmy_chain; - - new->next = *pmy_chain; - new->function = function; - new->free_arg = free_arg; - new->arg = arg; - *pmy_chain = new; - - return old_chain; -} - -struct cleanup * -make_my_cleanup (struct cleanup **pmy_chain, make_cleanup_ftype *function, - void *arg) -{ - return make_my_cleanup2 (pmy_chain, function, arg, NULL); -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (struct cleanup *old_chain) -{ - do_my_cleanups (&cleanup_chain, old_chain); -} - -void -do_final_cleanups (struct cleanup *old_chain) -{ - do_my_cleanups (&final_cleanup_chain, old_chain); -} - -static void -do_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) -{ - struct cleanup *ptr; - - while ((ptr = *pmy_chain) != old_chain) - { - *pmy_chain = ptr->next; /* Do this first in case of recursion. */ - (*ptr->function) (ptr->arg); - if (ptr->free_arg) - (*ptr->free_arg) (ptr->arg); - xfree (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (struct cleanup *old_chain) -{ - discard_my_cleanups (&cleanup_chain, old_chain); -} - -void -discard_final_cleanups (struct cleanup *old_chain) -{ - discard_my_cleanups (&final_cleanup_chain, old_chain); -} - -void -discard_my_cleanups (struct cleanup **pmy_chain, - struct cleanup *old_chain) -{ - struct cleanup *ptr; - - while ((ptr = *pmy_chain) != old_chain) - { - *pmy_chain = ptr->next; - if (ptr->free_arg) - (*ptr->free_arg) (ptr->arg); - xfree (ptr); - } -} - -/* Set the cleanup_chain to 0, and return the old cleanup chain. */ -struct cleanup * -save_cleanups (void) -{ - return save_my_cleanups (&cleanup_chain); -} - -struct cleanup * -save_final_cleanups (void) -{ - return save_my_cleanups (&final_cleanup_chain); -} - -struct cleanup * -save_my_cleanups (struct cleanup **pmy_chain) -{ - struct cleanup *old_chain = *pmy_chain; - - *pmy_chain = 0; - return old_chain; -} - -/* Restore the cleanup chain from a previously saved chain. */ -void -restore_cleanups (struct cleanup *chain) -{ - restore_my_cleanups (&cleanup_chain, chain); -} - -void -restore_final_cleanups (struct cleanup *chain) -{ - restore_my_cleanups (&final_cleanup_chain, chain); -} - -void -restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) -{ - *pmy_chain = chain; -} - /* This function is useful for cleanups. Do @@ -633,18 +479,6 @@ free_current_contents (void *ptr) } } -/* Provide a known function that does nothing, to use as a base for - a possibly long chain of cleanups. This is useful where we - use the cleanup chain for handling normal cleanups as well as dealing - with cleanups that need to be done as a result of a call to error(). - In such cases, we may not be certain where the first cleanup is, unless - we have a do-nothing one to always use as the base. */ - -void -null_cleanup (void *arg) -{ -} - /* If nonzero, display time usage both at startup and for each command. */ static int display_time; |