From patchwork Mon Aug 18 08:46:55 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gary Benson X-Patchwork-Id: 2412 Received: (qmail 16356 invoked by alias); 18 Aug 2014 08:47:13 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 16328 invoked by uid 89); 18 Aug 2014 08:47:13 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 18 Aug 2014 08:47:06 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s7I8l3w9011652 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 18 Aug 2014 04:47:04 -0400 Received: from blade.nx (ovpn-116-90.ams2.redhat.com [10.36.116.90]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s7I8l07o029725 for ; Mon, 18 Aug 2014 04:47:01 -0400 Received: from blade.nx (localhost [127.0.0.1]) by blade.nx (Postfix) with ESMTP id 7E9EB2640DA for ; Mon, 18 Aug 2014 09:47:00 +0100 (BST) From: Gary Benson To: gdb-patches@sourceware.org Subject: [PATCH 2/5] Move cleanups.[ch] to common Date: Mon, 18 Aug 2014 09:46:55 +0100 Message-Id: <1408351618-21013-3-git-send-email-gbenson@redhat.com> In-Reply-To: <1408351618-21013-1-git-send-email-gbenson@redhat.com> References: <1408351618-21013-1-git-send-email-gbenson@redhat.com> X-IsSubscribed: yes This commit moves cleanups.[ch] into gdb/common/. The only change to the content of the files is that cleanups.c's include list was altered to match its new location. gdb/ 2014-08-18 Gary Benson * cleanups.h: Moved to... * common/cleanups.h: New file. * cleanups.c: Moved to... * common/cleanups.c: New file. * Makefile.in (SFILES): Replace cleanups.c with common/cleanups.c. (HFILES_NO_SRCDIR): Replace cleanups.h with common/cleanups.h. (cleanups.o): New rule. gdb/gdbserver/ 2014-08-18 Gary Benson * Makefile.in (SFILES): Add common/cleanups.c. (OBS): cleanups.o. (cleanups.o): New rule. --- gdb/ChangeLog | 10 ++ gdb/Makefile.in | 10 ++- gdb/cleanups.c | 296 -------------------------------------------- gdb/cleanups.h | 69 ----------- gdb/common/cleanups.c | 297 +++++++++++++++++++++++++++++++++++++++++++++ gdb/common/cleanups.h | 69 +++++++++++ gdb/gdbserver/ChangeLog | 6 + gdb/gdbserver/Makefile.in | 7 +- 8 files changed, 395 insertions(+), 369 deletions(-) delete mode 100644 gdb/cleanups.c delete mode 100644 gdb/cleanups.h create mode 100644 gdb/common/cleanups.c create mode 100644 gdb/common/cleanups.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index e68798d..1840ce7 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -794,7 +794,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \ breakpoint.c break-catch-sig.c break-catch-throw.c \ build-id.c buildsym.c \ c-exp.y c-lang.c c-typeprint.c c-valprint.c c-varobj.c \ - charset.c cleanups.c cli-out.c coffread.c coff-pe-read.c \ + charset.c common/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-exp.y d-lang.c d-support.c d-valprint.c \ @@ -885,7 +885,7 @@ objfiles.h common/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 cleanups.h addrmap.h command.h solist.h source.h \ +m2-lang.h stack.h charset.h addrmap.h command.h solist.h source.h \ target.h target-dcache.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 \ @@ -938,6 +938,8 @@ target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \ common/print-utils.h common/rsp-low.h nat/i386-dregs.h x86-linux-nat.h \ i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \ common/common-debug.h target/target.h target/symbol.h common/common-regcache.h +common/common-debug.h target/target.h target/symbol.h common/common-regcache.h \ +common/cleanups.h # Header files that already have srcdir in them, or which are in objdir. @@ -2154,6 +2156,10 @@ common-debug.o: ${srcdir}/common/common-debug.c $(COMPILE) $(srcdir)/common/common-debug.c $(POSTCOMPILE) +cleanups.o: ${srcdir}/common/cleanups.c + $(COMPILE) $(srcdir)/common/cleanups.c + $(POSTCOMPILE) + # # gdb/target/ dependencies # diff --git a/gdb/cleanups.c b/gdb/cleanups.c deleted file mode 100644 index ddf8e5b..0000000 --- a/gdb/cleanups.c +++ /dev/null @@ -1,296 +0,0 @@ -/* Cleanup routines for GDB, the GNU debugger. - - Copyright (C) 1986-2014 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 . */ - -#include "defs.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; -}; - -/* Used to mark the end of a cleanup chain. - The value is chosen so that it: - - is non-NULL so that make_cleanup never returns NULL, - - causes a segv if dereferenced - [though this won't catch errors that a value of, say, - ((struct cleanup *) -1) will] - - displays as something useful when printed in gdb. - This is const for a bit of extra robustness. - It is initialized to coax gcc into putting it into .rodata. - All fields are initialized to survive -Wextra. */ -static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 }; - -/* Handy macro to use when referring to sentinel_cleanup. */ -#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup) - -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ -static struct cleanup *cleanup_chain = SENTINEL_CLEANUP; - -/* Chain of cleanup actions established with make_final_cleanup, - to be executed when gdb exits. */ -static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP; - -/* 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. */ - -static 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; - - gdb_assert (old_chain != NULL); - 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. */ - -static 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); - } -} - -/* Return a value that can be passed to do_cleanups, do_final_cleanups to - indicate perform all cleanups. */ - -struct cleanup * -all_cleanups (void) -{ - return SENTINEL_CLEANUP; -} - -/* 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. */ - -static 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. */ - -static struct cleanup * -save_my_cleanups (struct cleanup **pmy_chain) -{ - struct cleanup *old_chain = *pmy_chain; - - *pmy_chain = SENTINEL_CLEANUP; - 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. */ - -static void -restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) -{ - if (*pmy_chain != SENTINEL_CLEANUP) - internal_warning (__FILE__, __LINE__, - _("restore_my_cleanups has found a stale cleanup")); - - *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 deleted file mode 100644 index aad5add..0000000 --- a/gdb/cleanups.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Cleanups. - Copyright (C) 1986-2014 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 . */ - -#ifndef CLEANUPS_H -#define CLEANUPS_H - -/* Outside of cleanups.c, this is an opaque type. */ -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 *); - -/* Function type for the dtor in make_cleanup_dtor. */ -typedef void (make_cleanup_dtor_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. - The result is guaranteed to be non-NULL though. */ - -extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); - -extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, - make_cleanup_dtor_ftype *); - -extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); - -/* A special value to pass to do_cleanups and do_final_cleanups - to tell them to do all cleanups. */ -extern struct cleanup *all_cleanups (void); - -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 struct cleanup *save_cleanups (void); -extern struct cleanup *save_final_cleanups (void); - -extern void restore_cleanups (struct cleanup *); -extern void restore_final_cleanups (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 */ diff --git a/gdb/common/cleanups.c b/gdb/common/cleanups.c new file mode 100644 index 0000000..49b643b --- /dev/null +++ b/gdb/common/cleanups.c @@ -0,0 +1,297 @@ +/* Cleanup routines for GDB, the GNU debugger. + + Copyright (C) 1986-2014 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 . */ + +#include "common-defs.h" +#include "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; +}; + +/* Used to mark the end of a cleanup chain. + The value is chosen so that it: + - is non-NULL so that make_cleanup never returns NULL, + - causes a segv if dereferenced + [though this won't catch errors that a value of, say, + ((struct cleanup *) -1) will] + - displays as something useful when printed in gdb. + This is const for a bit of extra robustness. + It is initialized to coax gcc into putting it into .rodata. + All fields are initialized to survive -Wextra. */ +static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0 }; + +/* Handy macro to use when referring to sentinel_cleanup. */ +#define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup) + +/* Chain of cleanup actions established with make_cleanup, + to be executed if an error happens. */ +static struct cleanup *cleanup_chain = SENTINEL_CLEANUP; + +/* Chain of cleanup actions established with make_final_cleanup, + to be executed when gdb exits. */ +static struct cleanup *final_cleanup_chain = SENTINEL_CLEANUP; + +/* 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. */ + +static 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; + + gdb_assert (old_chain != NULL); + 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. */ + +static 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); + } +} + +/* Return a value that can be passed to do_cleanups, do_final_cleanups to + indicate perform all cleanups. */ + +struct cleanup * +all_cleanups (void) +{ + return SENTINEL_CLEANUP; +} + +/* 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. */ + +static 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. */ + +static struct cleanup * +save_my_cleanups (struct cleanup **pmy_chain) +{ + struct cleanup *old_chain = *pmy_chain; + + *pmy_chain = SENTINEL_CLEANUP; + 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. */ + +static void +restore_my_cleanups (struct cleanup **pmy_chain, struct cleanup *chain) +{ + if (*pmy_chain != SENTINEL_CLEANUP) + internal_warning (__FILE__, __LINE__, + _("restore_my_cleanups has found a stale cleanup")); + + *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/common/cleanups.h b/gdb/common/cleanups.h new file mode 100644 index 0000000..aad5add --- /dev/null +++ b/gdb/common/cleanups.h @@ -0,0 +1,69 @@ +/* Cleanups. + Copyright (C) 1986-2014 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 . */ + +#ifndef CLEANUPS_H +#define CLEANUPS_H + +/* Outside of cleanups.c, this is an opaque type. */ +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 *); + +/* Function type for the dtor in make_cleanup_dtor. */ +typedef void (make_cleanup_dtor_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. + The result is guaranteed to be non-NULL though. */ + +extern struct cleanup *make_cleanup (make_cleanup_ftype *, void *); + +extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *, + make_cleanup_dtor_ftype *); + +extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *); + +/* A special value to pass to do_cleanups and do_final_cleanups + to tell them to do all cleanups. */ +extern struct cleanup *all_cleanups (void); + +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 struct cleanup *save_cleanups (void); +extern struct cleanup *save_final_cleanups (void); + +extern void restore_cleanups (struct cleanup *); +extern void restore_final_cleanups (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 */ diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index 18486c6..f130082 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -170,7 +170,7 @@ SFILES= $(srcdir)/gdbreplay.c $(srcdir)/inferiors.c $(srcdir)/dll.c \ $(srcdir)/common/filestuff.c $(srcdir)/target/waitstatus.c \ $(srcdir)/nat/mips-linux-watch.c $(srcdir)/common/print-utils.c \ $(srcdir)/common/rsp-low.c $(srcdir)/common/errors.c \ - $(srcdir)/common/common-debug.c + $(srcdir)/common/common-debug.c $(srcdir)/common/cleanups.c DEPFILES = @GDBSERVER_DEPFILES@ @@ -183,7 +183,7 @@ OBS = agent.o ax.o inferiors.o regcache.o remote-utils.o server.o signals.o \ target.o waitstatus.o utils.o debug.o version.o vec.o gdb_vecs.o \ mem-break.o hostio.o event-loop.o tracepoint.o xml-utils.o \ common-utils.o ptid.o buffer.o format.o filestuff.o dll.o notif.o \ - tdesc.o print-utils.o rsp-low.o errors.o common-debug.o \ + tdesc.o print-utils.o rsp-low.o errors.o common-debug.o cleanups.o \ $(XML_BUILTIN) $(DEPFILES) $(LIBOBJS) GDBREPLAY_OBS = gdbreplay.o version.o GDBSERVER_LIBS = @GDBSERVER_LIBS@ @@ -544,6 +544,9 @@ errors.o: ../common/errors.c common-debug.o: ../common/common-debug.c $(COMPILE) $< $(POSTCOMPILE) +cleanups.o: ../common/cleanups.c + $(COMPILE) $< + $(POSTCOMPILE) waitstatus.o: ../target/waitstatus.c $(COMPILE) $< $(POSTCOMPILE)