This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFC: introduce scoped cleanups


>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> This adds scoped cleanups to gdb.

Pedro said he was interested in general stack-based allocation of
cleanups, so I implemented that, following his plan.

This patch adds two new features to gdb.

First, it adds optional stack-allocation of cleanup structures.  There
is a convenience macro for this, which uses alloca, so stack-allocation
isn't generally suitable in loops.  However, most cleanups can be
converted to stack allocation.

Second, like the previous iteration of the patch, this adds a "scoped"
cleanup that can be used to do runtime error-checking of cleanup use.
This checking only works when gdb is compiled with gcc.

I converted linespec.c entirely to the new setup, just to show what it
looks like.


With the introduction of make_stack_cleanup, it is now better to write a
cleanup function and to use the generic make_cleanup than it is to write
a make_cleanup_something_special function.

There is an example of this in the patch as well.


Let me know what you think.  In the absence of comments I imagine I will
eventually put this in and slowly work on converting other parts of gdb.
I think it is worth doing both on efficiency and reliability grounds.

Tom

diff --git a/gdb/cleanups.c b/gdb/cleanups.c
index 898e526..398e0fc 100644
--- a/gdb/cleanups.c
+++ b/gdb/cleanups.c
@@ -20,29 +20,6 @@
 #include "defs.h"
 #include "gdb_assert.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,
@@ -53,7 +30,7 @@ struct cleanup
    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 };
+static const struct cleanup sentinel_cleanup = { 0, 0, 0, 0, 0, 0 };
 
 /* Handy macro to use when referring to sentinel_cleanup.  */
 #define SENTINEL_CLEANUP ((struct cleanup *) &sentinel_cleanup)
@@ -84,6 +61,7 @@ make_my_cleanup2 (struct cleanup **pmy_chain, make_cleanup_ftype *function,
   struct cleanup *old_chain = *pmy_chain;
 
   new->next = *pmy_chain;
+  new->stack = 0;
   new->function = function;
   new->free_arg = free_arg;
   new->arg = arg;
@@ -155,7 +133,10 @@ do_my_cleanups (struct cleanup **pmy_chain,
       (*ptr->function) (ptr->arg);
       if (ptr->free_arg)
 	(*ptr->free_arg) (ptr->arg);
-      xfree (ptr);
+      if (ptr->stack)
+	ptr->cleaned_up = 1;
+      else
+	xfree (ptr);
     }
 }
 
@@ -202,7 +183,10 @@ discard_my_cleanups (struct cleanup **pmy_chain,
       *pmy_chain = ptr->next;
       if (ptr->free_arg)
 	(*ptr->free_arg) (ptr->arg);
-      xfree (ptr);
+      if (ptr->stack)
+	ptr->cleaned_up = 1;
+      else
+	xfree (ptr);
     }
 }
 
@@ -295,3 +279,37 @@ void
 null_cleanup (void *arg)
 {
 }
+
+/* Initialize a scoped cleanup.  */
+
+struct cleanup *
+init_stack_cleanup (struct cleanup *cl, make_cleanup_ftype *func,
+		    void *datum, make_cleanup_dtor_ftype *dtor)
+{
+  struct cleanup *old_chain = cleanup_chain;
+
+  cl->next = cleanup_chain;
+  cleanup_chain = cl;
+
+  cl->function = func;
+  cl->free_arg = dtor;
+  cl->arg = datum;
+  cl->stack = 1;
+  cl->cleaned_up = 0;
+
+  return old_chain;
+}
+
+#ifdef SCOPED_CLEANUP_CHECKING
+
+/* Verify that a scoped cleanup was in fact handled.  */
+
+void
+cleanup_close_scope (struct cleanup *cl)
+{
+  gdb_assert (cl->stack);
+  if (!cl->cleaned_up)
+    internal_warning (__FILE__, __LINE__, "scoped cleanup leaked");
+}
+
+#endif /* SCOPED_CLEANUP_CHECKING */
diff --git a/gdb/cleanups.h b/gdb/cleanups.h
index 463b923..3f49e80 100644
--- a/gdb/cleanups.h
+++ b/gdb/cleanups.h
@@ -45,6 +45,15 @@ extern struct cleanup *make_cleanup_dtor (make_cleanup_ftype *, void *,
 
 extern struct cleanup *make_final_cleanup (make_cleanup_ftype *, void *);
 
+/* Allocate a cleanup on the stack, with alloca, and initialize
+   it.  Use like make_cleanup.  */
+
+#define make_stack_cleanup(FUNC, ARG) \
+  (init_stack_cleanup (alloca (sizeof (struct cleanup)), (FUNC), (ARG), NULL))
+
+#define make_stack_cleanup_dtor(FUNC, ARG, DTOR) \
+  (init_stack_cleanup (alloca (sizeof (struct cleanup)), (FUNC), (ARG), (DTOR)))
+
 /* 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);
@@ -66,4 +75,76 @@ extern void restore_final_cleanups (struct cleanup *);
    to pass to do_cleanups.  */
 extern void null_cleanup (void *);
 
+
+/* You should continue to treat this as opaque.  It is defined here so
+   that scoped cleanups can be stack-allocated and specially treated.
+
+   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
+{
+  void (*function) (void *);
+  void (*free_arg) (void *);
+  void *arg;
+  struct cleanup *next;
+
+  /* True if this is a stack-allocated cleanup.  */
+  unsigned stack : 1;
+
+  /* True if this is scoped cleanup has been cleaned up or discarded.
+     Not used for ordinary cleanups.  */
+
+  unsigned cleaned_up : 1;
+};
+
+extern struct cleanup *init_stack_cleanup (struct cleanup *,
+					   make_cleanup_ftype *,
+					   void *,
+					   make_cleanup_dtor_ftype *);
+
+#if defined (__GNUC__) && __GNUC__ >= 4
+
+/* Define this to consolidate #if checking with the
+   implementation.  */
+
+#define SCOPED_CLEANUP_CHECKING
+
+#define SCOPED_CLEANUP_ATTRIBUTE \
+  __attribute__ ((cleanup (cleanup_close_scope)))
+
+extern void cleanup_close_scope (struct cleanup *);
+
+#else
+
+#define SCOPED_CLEANUP_ATTRIBUTE
+
+#endif
+
+/* Use this to declare a scoped cleanup.  A scoped cleanup must be
+   cleaned up or discarded whenever the scope is exited.  When
+   possible, this is checked at runtime.  */
+
+#define SCOPED_CLEANUP_DTOR(NAME, FUNC, DATA, DTOR)			\
+  struct cleanup NAME ## __LINE__ SCOPED_CLEANUP_ATTRIBUTE;		\
+  struct cleanup *NAME = init_stack_cleanup (& (NAME ## __LINE__),	\
+					     (FUNC), (DATA), (DTOR))
+
+#define SCOPED_CLEANUP(NAME, FUNC, DATA)				\
+  SCOPED_CLEANUP_DTOR(NAME, (FUNC), (DATA), NULL)
+
+#define SCOPED_NULL_CLEANUP(NAME) SCOPED_CLEANUP (NAME, null_cleanup, NULL)
+
 #endif /* CLEANUPS_H */
diff --git a/gdb/contrib/cleanup_check.py b/gdb/contrib/cleanup_check.py
index 0dd149f..a93af4c 100644
--- a/gdb/contrib/cleanup_check.py
+++ b/gdb/contrib/cleanup_check.py
@@ -54,7 +54,7 @@ special_names = set(['do_final_cleanups', 'discard_final_cleanups',
                      'restore_cleanups', 'restore_final_cleanups',
                      'exceptions_state_mc_init',
                      'make_my_cleanup2', 'make_final_cleanup', 'all_cleanups',
-                     'save_my_cleanups', 'quit_target'])
+                     'save_my_cleanups', 'quit_target', 'init_stack_cleanup'])
 
 def needs_special_treatment(decl):
     return decl.name in special_names
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 61e5377..2b58618 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -1267,11 +1267,11 @@ filter_results (struct linespec_state *self,
 	{
 	  const struct linespec_canonical_name *canonical;
 	  char *fullform;
-	  struct cleanup *cleanup;
+	  SCOPED_NULL_CLEANUP (cleanup);
 
 	  canonical = &self->canonical_names[j];
 	  fullform = canonical_to_fullform (canonical);
-	  cleanup = make_cleanup (xfree, fullform);
+	  make_cleanup (xfree, fullform);
 
 	  if (strcmp (name, fullform) == 0)
 	    add_sal_to_sals_basic (&lsal.sals, &result->sals[j]);
@@ -1352,8 +1352,8 @@ decode_line_2 (struct linespec_state *self,
 {
   char *args, *prompt;
   int i;
-  struct cleanup *old_chain;
   VEC (const_char_ptr) *filters = NULL;
+  SCOPED_CLEANUP (old_chain, VEC_cleanup (const_char_ptr), &filters);
   struct get_number_or_range_state state;
   struct decode_line_2_item *items;
   int items_count;
@@ -1362,12 +1362,10 @@ decode_line_2 (struct linespec_state *self,
   gdb_assert (self->canonical != NULL);
   gdb_assert (result->nelts >= 1);
 
-  old_chain = make_cleanup (VEC_cleanup (const_char_ptr), &filters);
-
   /* Prepare ITEMS array.  */
   items_count = result->nelts;
   items = xmalloc (sizeof (*items) * items_count);
-  make_cleanup (xfree, items);
+  make_stack_cleanup (xfree, items);
   for (i = 0; i < items_count; ++i)
     {
       const struct linespec_canonical_name *canonical;
@@ -1545,10 +1543,9 @@ unexpected_linespec_error (linespec_parser *parser)
       || token.type == LSTOKEN_KEYWORD)
     {
       char *string;
-      struct cleanup *cleanup;
 
       string = copy_token_string (token);
-      cleanup = make_cleanup (xfree, string);
+      make_stack_cleanup (xfree, string);
       throw_error (GENERIC_ERROR,
 		   _("malformed linespec error: unexpected %s, \"%s\""),
 		   token_type_strings[token.type], string);
@@ -1604,7 +1601,7 @@ linespec_parse_basic (linespec_parser *parser)
     {
       /* Record the line offset and get the next token.  */
       name = copy_token_string (token);
-      cleanup = make_cleanup (xfree, name);
+      cleanup = make_stack_cleanup (xfree, name);
       PARSER_RESULT (parser)->line_offset = linespec_parse_line_offset (name);
       do_cleanups (cleanup);
 
@@ -1631,7 +1628,7 @@ linespec_parse_basic (linespec_parser *parser)
   /* The current token will contain the name of a function, method,
      or label.  */
   name  = copy_token_string (token);
-  cleanup = make_cleanup (xfree, name);
+  cleanup = make_stack_cleanup (xfree, name);
 
   /* Try looking it up as a function/method.  */
   find_linespec_symbols (PARSER_STATE (parser),
@@ -1685,7 +1682,7 @@ linespec_parse_basic (linespec_parser *parser)
 	  /* User specified an offset.  Record the line offset and
 	     get the next token.  */
 	  name = copy_token_string (token);
-	  cleanup = make_cleanup (xfree, name);
+	  cleanup = make_stack_cleanup (xfree, name);
 	  PARSER_RESULT (parser)->line_offset
 	    = linespec_parse_line_offset (name);
 	  do_cleanups (cleanup);
@@ -1697,7 +1694,7 @@ linespec_parse_basic (linespec_parser *parser)
 	{
 	  /* Grab a copy of the label's name and look it up.  */
 	  name = copy_token_string (token);
-	  cleanup = make_cleanup (xfree, name);
+	  cleanup = make_stack_cleanup (xfree, name);
 	  labels = find_label_symbols (PARSER_STATE (parser),
 				       PARSER_RESULT (parser)->function_symbols,
 				       &symbols, name);
@@ -1731,7 +1728,7 @@ linespec_parse_basic (linespec_parser *parser)
 
 	      /* Record the lione offset and get the next token.  */
 	      name = copy_token_string (token);
-	      cleanup = make_cleanup (xfree, name);
+	      cleanup = make_stack_cleanup (xfree, name);
 
 	      PARSER_RESULT (parser)->line_offset
 		= linespec_parse_line_offset (name);
@@ -1901,7 +1898,7 @@ create_sals_line_offset (struct linespec_state *self,
 	decode_digits_ordinary (self, ls, best_entry->line,
 				&intermediate_results, &best_entry);
 
-      cleanup = make_cleanup (xfree, intermediate_results.sals);
+      cleanup = make_stack_cleanup (xfree, intermediate_results.sals);
 
       /* For optimized code, the compiler can scatter one source line
 	 across disjoint ranges of PC values, even when no duplicate
@@ -1914,9 +1911,9 @@ create_sals_line_offset (struct linespec_state *self,
 	 block.  If yes, the other PCs are filtered out.  */
 
       filter = XNEWVEC (int, intermediate_results.nelts);
-      make_cleanup (xfree, filter);
+      make_stack_cleanup (xfree, filter);
       blocks = XNEWVEC (struct block *, intermediate_results.nelts);
-      make_cleanup (xfree, blocks);
+      make_stack_cleanup (xfree, blocks);
 
       for (i = 0; i < intermediate_results.nelts; ++i)
 	{
@@ -2190,7 +2187,7 @@ parse_linespec (linespec_parser *parser, char **argptr)
 
       /* User specified an expression, *EXPR.  */
       copy = expr = copy_token_string (token);
-      cleanup = make_cleanup (xfree, expr);
+      cleanup = make_stack_cleanup (xfree, expr);
       PARSER_RESULT (parser)->expr_pc = linespec_expression_to_pc (&copy);
       discard_cleanups (cleanup);
       PARSER_RESULT (parser)->expression = expr;
@@ -2218,7 +2215,7 @@ parse_linespec (linespec_parser *parser, char **argptr)
 
       /* User specified a convenience variable or history value.  */
       var = copy_token_string (token);
-      cleanup = make_cleanup (xfree, var);
+      cleanup = make_stack_cleanup (xfree, var);
       PARSER_RESULT (parser)->line_offset
 	= linespec_parse_variable (PARSER_STATE (parser), var);
       do_cleanups (cleanup);
@@ -2412,7 +2409,7 @@ decode_line_full (char **argptr, int flags,
 		  const char *filter)
 {
   struct symtabs_and_lines result;
-  struct cleanup *cleanups;
+  SCOPED_NULL_CLEANUP (cleanups);
   VEC (const_char_ptr) *filters = NULL;
   linespec_parser parser;
   struct linespec_state *state;
@@ -2428,7 +2425,7 @@ decode_line_full (char **argptr, int flags,
 
   linespec_parser_new (&parser, flags, current_language, default_symtab,
 		       default_line, canonical);
-  cleanups = make_cleanup (linespec_parser_delete, &parser);
+  make_stack_cleanup (linespec_parser_delete, &parser);
   save_current_program_space ();
 
   result = parse_linespec (&parser, argptr);
@@ -2443,7 +2440,7 @@ decode_line_full (char **argptr, int flags,
     {
       int i;
 
-      make_cleanup (xfree, state->canonical_names);
+      make_stack_cleanup (xfree, state->canonical_names);
       for (i = 0; i < result.nelts; ++i)
 	{
 	  gdb_assert (state->canonical_names[i].suffix != NULL);
@@ -2463,7 +2460,7 @@ decode_line_full (char **argptr, int flags,
     {
       if (filter != NULL)
 	{
-	  make_cleanup (VEC_cleanup (const_char_ptr), &filters);
+	  make_stack_cleanup (VEC_cleanup (const_char_ptr), &filters);
 	  VEC_safe_push (const_char_ptr, filters, filter);
 	  filter_results (state, &result, filters);
 	}
@@ -2485,11 +2482,11 @@ decode_line_1 (char **argptr, int flags,
 {
   struct symtabs_and_lines result;
   linespec_parser parser;
-  struct cleanup *cleanups;
+  SCOPED_NULL_CLEANUP (cleanups);
 
   linespec_parser_new (&parser, flags, current_language, default_symtab,
 		       default_line, NULL);
-  cleanups = make_cleanup (linespec_parser_delete, &parser);
+  make_stack_cleanup (linespec_parser_delete, &parser);
   save_current_program_space ();
 
   result = parse_linespec (&parser, argptr);
@@ -2598,13 +2595,12 @@ decode_objc (struct linespec_state *self, linespec_p ls, char **argptr)
   VEC (const_char_ptr) *symbol_names = NULL;
   struct symtabs_and_lines values;
   char *new_argptr;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-					  &symbol_names);
+  SCOPED_CLEANUP (cleanup, VEC_cleanup (const_char_ptr), &symbol_names);
 
   info.state = self;
   info.file_symtabs = NULL;
   VEC_safe_push (symtab_p, info.file_symtabs, NULL);
-  make_cleanup (VEC_cleanup (symtab_p), &info.file_symtabs);
+  make_stack_cleanup (VEC_cleanup (symtab_p), &info.file_symtabs);
   info.result.symbols = NULL;
   info.result.minimal_symbols = NULL;
   values.nelts = 0;
@@ -2703,16 +2699,14 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_p) *file_symtabs,
   int ix;
   struct symtab *elt;
   struct decode_compound_collector collector;
-  struct cleanup *outer;
+  SCOPED_CLEANUP (outer, VEC_cleanup (symbolp), &collector.symbols);
   struct cleanup *cleanup;
 
   collector.symbols = NULL;
-  outer = make_cleanup (VEC_cleanup (symbolp), &collector.symbols);
-
   collector.unique_syms = htab_create_alloc (1, htab_hash_pointer,
 					     htab_eq_pointer, NULL,
 					     xcalloc, xfree);
-  cleanup = make_cleanup_htab_delete (collector.unique_syms);
+  cleanup = make_stack_cleanup (htab_delete_cleanup, collector.unique_syms);
 
   for (ix = 0; VEC_iterate (symtab_p, file_symtabs, ix, elt); ++ix)
     {
@@ -2825,7 +2819,7 @@ find_superclass_methods (VEC (typep) *superclasses,
 {
   int old_len = VEC_length (const_char_ptr, *result_names);
   VEC (typep) *iter_classes;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  SCOPED_NULL_CLEANUP (cleanup);
 
   iter_classes = superclasses;
   while (1)
@@ -2859,7 +2853,7 @@ find_method (struct linespec_state *self, VEC (symtab_p) *file_symtabs,
 	     VEC (minsym_and_objfile_d) **minsyms)
 {
   struct symbol *sym;
-  struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
+  SCOPED_NULL_CLEANUP (cleanup);
   int ix;
   int last_result_len;
   VEC (typep) *superclass_vec;
@@ -2888,9 +2882,9 @@ find_method (struct linespec_state *self, VEC (symtab_p) *file_symtabs,
      because we collect data across the program space before deciding
      what to do.  */
   superclass_vec = NULL;
-  make_cleanup (VEC_cleanup (typep), &superclass_vec);
+  make_stack_cleanup (VEC_cleanup (typep), &superclass_vec);
   result_names = NULL;
-  make_cleanup (VEC_cleanup (const_char_ptr), &result_names);
+  make_stack_cleanup (VEC_cleanup (const_char_ptr), &result_names);
   last_result_len = 0;
   for (ix = 0; VEC_iterate (symbolp, sym_classes, ix, sym); ++ix)
     {
@@ -2979,13 +2973,13 @@ static VEC (symtab_p) *
 collect_symtabs_from_filename (const char *file)
 {
   struct symtab_collector collector;
-  struct cleanup *cleanups;
+  SCOPED_NULL_CLEANUP (cleanups);
   struct program_space *pspace;
 
   collector.symtabs = NULL;
   collector.symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
 					NULL);
-  cleanups = make_cleanup_htab_delete (collector.symtab_table);
+  make_stack_cleanup (htab_delete_cleanup, collector.symtab_table);
 
   /* Find that file's data.  */
   ALL_PSPACES (pspace)
@@ -3034,8 +3028,7 @@ find_function_symbols (struct linespec_state *state,
 {
   struct collect_info info;
   VEC (const_char_ptr) *symbol_names = NULL;
-  struct cleanup *cleanup = make_cleanup (VEC_cleanup (const_char_ptr),
-					  &symbol_names);
+  SCOPED_CLEANUP (cleanup, VEC_cleanup (const_char_ptr), &symbol_names);
 
   info.state = state;
   info.result.symbols = NULL;
@@ -3078,26 +3071,25 @@ find_linespec_symbols (struct linespec_state *state,
 		       VEC (symbolp) **symbols,
 		       VEC (minsym_and_objfile_d) **minsyms)
 {
-  struct cleanup *cleanup;
+  SCOPED_NULL_CLEANUP (cleanup);
   char *canon;
   const char *lookup_name;
   volatile struct gdb_exception except;
 
-  cleanup = demangle_for_lookup (name, state->language->la_language,
-				 &lookup_name);
+  demangle_for_lookup (name, state->language->la_language, &lookup_name);
   if (state->language->la_language == language_ada)
     {
       /* In Ada, the symbol lookups are performed using the encoded
          name rather than the demangled name.  */
       lookup_name = ada_name_for_lookup (name);
-      make_cleanup (xfree, (void *) lookup_name);
+      make_stack_cleanup (xfree, (void *) lookup_name);
     }
 
   canon = cp_canonicalize_string_no_typedefs (lookup_name);
   if (canon != NULL)
     {
       lookup_name = canon;
-      make_cleanup (xfree, canon);
+      make_stack_cleanup (xfree, canon);
     }
 
   /* It's important to not call expand_symtabs_matching unnecessarily
@@ -3152,19 +3144,19 @@ find_linespec_symbols (struct linespec_state *state,
       /* LOOKUP_NAME points to the class name.
 	 LAST points to the method name.  */
       klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
-      make_cleanup (xfree, klass);
+      make_stack_cleanup (xfree, klass);
       strncpy (klass, lookup_name, last - lookup_name);
       klass[last - lookup_name] = '\0';
 
       /* Skip past the scope operator.  */
       last += strlen (scope_op);
       method = xmalloc ((strlen (last) + 1) * sizeof (char));
-      make_cleanup (xfree, method);
+      make_stack_cleanup (xfree, method);
       strcpy (method, last);
 
       /* Find a list of classes named KLASS.  */
       classes = lookup_prefix_sym (state, file_symtabs, klass);
-      make_cleanup (VEC_cleanup (symbolp), &classes);
+      make_stack_cleanup (VEC_cleanup (symbolp), &classes);
 
       if (!VEC_empty (symbolp, classes))
 	{
@@ -3524,7 +3516,7 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
   ALL_PSPACES (pspace)
   {
     struct collect_minsyms local;
-    struct cleanup *cleanup;
+    SCOPED_NULL_CLEANUP (cleanup);
 
     if (search_pspace != NULL && search_pspace != pspace)
       continue;
@@ -3537,8 +3529,7 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
     local.funfirstline = info->state->funfirstline;
     local.list_mode = info->state->list_mode;
 
-    cleanup = make_cleanup (VEC_cleanup (minsym_and_objfile_d),
-			    &local.msyms);
+    make_cleanup (VEC_cleanup (minsym_and_objfile_d), &local.msyms);
 
     ALL_OBJFILES (objfile)
     {
diff --git a/gdb/utils.c b/gdb/utils.c
index 18ee9bb..d1609a3 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -403,10 +403,10 @@ make_cleanup_unpush_target (struct target_ops *ops)
   return make_cleanup (do_unpush_target, ops);
 }
 
-/* Helper for make_cleanup_htab_delete compile time checking the types.  */
+/* A cleanup function that deletes an htab_t.  */
 
-static void
-do_htab_delete_cleanup (void *htab_voidp)
+void
+htab_delete_cleanup (void *htab_voidp)
 {
   htab_t htab = htab_voidp;
 
@@ -418,7 +418,7 @@ do_htab_delete_cleanup (void *htab_voidp)
 struct cleanup *
 make_cleanup_htab_delete (htab_t htab)
 {
-  return make_cleanup (do_htab_delete_cleanup, htab);
+  return make_cleanup (htab_delete_cleanup, htab);
 }
 
 struct restore_ui_file_closure
diff --git a/gdb/utils.h b/gdb/utils.h
index 146a558..216278d 100644
--- a/gdb/utils.h
+++ b/gdb/utils.h
@@ -113,6 +113,8 @@ extern struct cleanup *make_cleanup_free_so (struct so_list *so);
 
 extern struct cleanup *make_cleanup_restore_current_language (void);
 
+extern void htab_delete_cleanup (void *htab);
+
 extern struct cleanup *make_cleanup_htab_delete (htab_t htab);
 
 extern void free_current_contents (void *);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]