1 /* Cleanup routines for GDB, the GNU debugger.
3 Copyright (C) 1986, 1988-2012 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
22 /* Chain of cleanup actions established with make_cleanup,
23 to be executed if an error happens. */
25 /* Cleaned up after a failed command. */
26 static struct cleanup
*cleanup_chain
;
28 /* Cleaned up when gdb exits. */
29 static struct cleanup
*final_cleanup_chain
;
31 /* Main worker routine to create a cleanup.
32 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
33 FUNCTION is the function to call to perform the cleanup.
34 ARG is passed to FUNCTION when called.
35 FREE_ARG, if non-NULL, is called after the cleanup is performed.
37 The result is a pointer to the previous chain pointer
38 to be passed later to do_cleanups or discard_cleanups. */
41 make_my_cleanup2 (struct cleanup
**pmy_chain
, make_cleanup_ftype
*function
,
42 void *arg
, void (*free_arg
) (void *))
45 = (struct cleanup
*) xmalloc (sizeof (struct cleanup
));
46 struct cleanup
*old_chain
= *pmy_chain
;
48 new->next
= *pmy_chain
;
49 new->function
= function
;
50 new->free_arg
= free_arg
;
57 /* Worker routine to create a cleanup without a destructor.
58 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
59 FUNCTION is the function to call to perform the cleanup.
60 ARG is passed to FUNCTION when called.
62 The result is a pointer to the previous chain pointer
63 to be passed later to do_cleanups or discard_cleanups. */
66 make_my_cleanup (struct cleanup
**pmy_chain
, make_cleanup_ftype
*function
,
69 return make_my_cleanup2 (pmy_chain
, function
, arg
, NULL
);
72 /* Add a new cleanup to the cleanup_chain,
73 and return the previous chain pointer
74 to be passed later to do_cleanups or discard_cleanups.
75 Args are FUNCTION to clean up with, and ARG to pass to it. */
78 make_cleanup (make_cleanup_ftype
*function
, void *arg
)
80 return make_my_cleanup (&cleanup_chain
, function
, arg
);
83 /* Same as make_cleanup except also includes TDOR, a destructor to free ARG.
84 DTOR is invoked when the cleanup is performed or when it is discarded. */
87 make_cleanup_dtor (make_cleanup_ftype
*function
, void *arg
,
88 void (*dtor
) (void *))
90 return make_my_cleanup2 (&cleanup_chain
,
94 /* Same as make_cleanup except the cleanup is added to final_cleanup_chain. */
97 make_final_cleanup (make_cleanup_ftype
*function
, void *arg
)
99 return make_my_cleanup (&final_cleanup_chain
, function
, arg
);
102 /* Worker routine to perform cleanups.
103 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
104 OLD_CHAIN is the result of a "make" cleanup routine.
105 Cleanups are performed until we get back to the old end of the chain. */
108 do_my_cleanups (struct cleanup
**pmy_chain
,
109 struct cleanup
*old_chain
)
113 while ((ptr
= *pmy_chain
) != old_chain
)
115 *pmy_chain
= ptr
->next
; /* Do this first in case of recursion. */
116 (*ptr
->function
) (ptr
->arg
);
118 (*ptr
->free_arg
) (ptr
->arg
);
123 /* Discard cleanups and do the actions they describe
124 until we get back to the point OLD_CHAIN in the cleanup_chain. */
127 do_cleanups (struct cleanup
*old_chain
)
129 do_my_cleanups (&cleanup_chain
, old_chain
);
132 /* Discard cleanups and do the actions they describe
133 until we get back to the point OLD_CHAIN in the final_cleanup_chain. */
136 do_final_cleanups (struct cleanup
*old_chain
)
138 do_my_cleanups (&final_cleanup_chain
, old_chain
);
141 /* Main worker routine to discard cleanups.
142 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
143 OLD_CHAIN is the result of a "make" cleanup routine.
144 Cleanups are discarded until we get back to the old end of the chain. */
147 discard_my_cleanups (struct cleanup
**pmy_chain
,
148 struct cleanup
*old_chain
)
152 while ((ptr
= *pmy_chain
) != old_chain
)
154 *pmy_chain
= ptr
->next
;
156 (*ptr
->free_arg
) (ptr
->arg
);
161 /* Discard cleanups, not doing the actions they describe,
162 until we get back to the point OLD_CHAIN in the cleanup chain. */
165 discard_cleanups (struct cleanup
*old_chain
)
167 discard_my_cleanups (&cleanup_chain
, old_chain
);
170 /* Discard final cleanups, not doing the actions they describe,
171 until we get back to the point OLD_CHAIN in the final cleanup chain. */
174 discard_final_cleanups (struct cleanup
*old_chain
)
176 discard_my_cleanups (&final_cleanup_chain
, old_chain
);
179 /* Main worker routine to save cleanups.
180 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
181 The chain is emptied and the result is a pointer to the old chain. */
184 save_my_cleanups (struct cleanup
**pmy_chain
)
186 struct cleanup
*old_chain
= *pmy_chain
;
192 /* Set the cleanup_chain to 0, and return the old cleanup_chain. */
197 return save_my_cleanups (&cleanup_chain
);
200 /* Set the final_cleanup_chain to 0, and return the old
201 final_cleanup_chain. */
204 save_final_cleanups (void)
206 return save_my_cleanups (&final_cleanup_chain
);
209 /* Main worker routine to save cleanups.
210 PMY_CHAIN is a pointer to either cleanup_chain or final_cleanup_chain.
211 The chain is restored from CHAIN. */
214 restore_my_cleanups (struct cleanup
**pmy_chain
, struct cleanup
*chain
)
219 /* Restore the cleanup chain from a previously saved chain. */
222 restore_cleanups (struct cleanup
*chain
)
224 restore_my_cleanups (&cleanup_chain
, chain
);
227 /* Restore the final cleanup chain from a previously saved chain. */
230 restore_final_cleanups (struct cleanup
*chain
)
232 restore_my_cleanups (&final_cleanup_chain
, chain
);
235 /* Provide a known function that does nothing, to use as a base for
236 a possibly long chain of cleanups. This is useful where we
237 use the cleanup chain for handling normal cleanups as well as dealing
238 with cleanups that need to be done as a result of a call to error().
239 In such cases, we may not be certain where the first cleanup is, unless
240 we have a do-nothing one to always use as the base. */
243 null_cleanup (void *arg
)
This page took 0.037419 seconds and 5 git commands to generate.