This is the mail archive of the mailing list for the Archer 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]

[type-refcount] [commit] Implement TYPEs reference counting forVAROBJs.

commit 79ec68e9e31e73cb97eb9832fbf41baea3acdacc

It fixes a regression for gdb.mi/mi-var-invalidate.exp on the both derived
branches [archer-jankratochvil-vla] and [archer-jankratochvil-python].

Types copying should not be needed in principle as VAROBJ in a file being
free_objfile()d should be also deleted.  This would mean varobj_invalidate()
should be called during each free_objfile().  Unfortunately varobj_invalidate()
deletes any non-global tracking VAROBJs now (even from unrelated OBJFILEs)
- that may be the reason why varobj_invalidate() is not called unconditionally
from free_objfile() as it should, there is even a notice about it in
  /* Not all our callers call clear_symtab_users (objfile_purge_solibs,
     for example), so we need to call this here.  */
  clear_pc_function_cache ();

Such call is for example present at syms_from_objfile() - the cleanup chain is
not executed anywhere soon creating the stale references state:
  if (mainline)
      /* We will modify the main symbol table, make sure that all its users
         will be cleaned up if an error occurs during symbol reading.  */
      make_cleanup (clear_symtab_users_cleanup, 0 /*ignore*/);

      /* Since no error yet, throw away the old symbol table.  */

      if (symfile_objfile != NULL)
          free_objfile (symfile_objfile);
          symfile_objfile = NULL;

Even with this patch free_objfile() without varobj_invalidate() still leaves
live VAROBJs with stale (pointing to the freed OBJFILE's obstack)
`varobj_root->valid_block'.  Although currently `varobj_root->valid_block' is
IMO always NULL as this feature does not look to be implemented (so such stale
reference cannot happen).

After the proper OBJFILE-specific VAROBJs invalidation gets implemented this
patch could be be reverted (although it still at least keeps the inter-object
referencing coherent).  VAROBJs having `varobj->root->valid_block != NULL'
should be invalidated/removed and global VAROBJs (having VALID_BLOCK == NULL)
get reevaluated from their expression string and thus their TYPEs get used from
other OBJFILEs or they get invalidated as no longer expression-parseable with
leftover OBJFILEs.

	Implement types reference counting for VAROBJs.
	* value.c: Include "varobj.h".
	(preserve_one_value): Remove `static'.
	(preserve_values): Call also preserve_variables.
	* value.h (preserve_one_value): New declaration.
	* varobj.c (varobj_create): Call type_incref on `var->type'.
	(preserve_variables): New function.
	(create_child): Call type_incref on `child->type'.
	(free_variable): Call type_decref.
	(varobj_invalidate): New FIXME comment.
	* varobj.h (preserve_variables): New declaration.
 gdb/value.c  |    5 ++++-
 gdb/value.h  |    3 +++
 gdb/varobj.c |   39 +++++++++++++++++++++++++++++++++++++++
 gdb/varobj.h |    2 ++
 4 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/gdb/value.c b/gdb/value.c
index fca7055..0002cf9 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -37,6 +37,7 @@
 #include "dfp.h"
 #include "objfiles.h"
 #include "valprint.h"
+#include "varobj.h"
 #include "python/python.h"
@@ -1086,7 +1087,7 @@ internalvar_name (struct internalvar *var)
 /* Update VALUE before discarding OBJFILE.  COPIED_TYPES is used to
    prevent cycles / duplicates.  */
-static void
 preserve_one_value (struct value *value, struct objfile *objfile,
 		    htab_t copied_types)
@@ -1139,6 +1140,8 @@ preserve_values (struct objfile *objfile)
   for (val = values_in_python; val; val = val->next)
     preserve_one_value (val, objfile, copied_types);
+  preserve_variables (objfile, copied_types);
   htab_delete (copied_types);
diff --git a/gdb/value.h b/gdb/value.h
index aa43365..6bfb1d9 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -636,6 +636,9 @@ extern void typedef_print (struct type *type, struct symbol *news,
 extern char *internalvar_name (struct internalvar *var);
+extern void preserve_one_value (struct value *value, struct objfile *objfile,
+				htab_t copied_types);
 extern void preserve_values (struct objfile *);
 /* From values.c */
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 0147ecb..27bcf24 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -541,6 +541,7 @@ varobj_create (char *objname,
 	var->type = value_type (value);
+      type_incref (var->type);
       install_new_value (var, value, 1 /* Initial assignment */);
@@ -1425,6 +1426,38 @@ uninstall_variable (struct varobj *var)
+/* Update GDB variable objects when OBJFILE is discarded; we must copy the
+   types out of the objfile.  Usually varobj_invalidate (by clear_symtab_users)
+   gets called which does not require this functionality.  But according to the
+   free_objfile comment this is not always the case.  */
+preserve_variables (struct objfile *objfile, htab_t copied_types)
+  unsigned int index;
+  for (index = 0; index < VAROBJ_TABLE_SIZE; index++)
+    {
+      struct vlist *vlist;
+      for (vlist = varobj_table[index]; vlist; vlist = vlist->next)
+	{
+	  struct varobj *var = vlist->var;
+	  if (var->value)
+	    preserve_one_value (var->value, objfile, copied_types);
+	  if (var->type && TYPE_OBJFILE (var->type) == objfile)
+	    {
+	      /* No need to decref the old type here, since we know it has no
+		 reference count.  */
+	      var->type = copy_type_recursive (var->type, copied_types);
+	      type_incref (var->type);
+	    }
+	}
+    }
 /* Create and install a child of the parent of the given name */
 static struct varobj *
 create_child (struct varobj *parent, int index, char *name)
@@ -1455,6 +1488,8 @@ create_child (struct varobj *parent, int index, char *name)
     /* Otherwise, we must compute the type. */
     child->type = (*child->root->lang->type_of_child) (child->parent, 
+  if (child->type)
+    type_incref (child->type);
   install_new_value (child, value, 1);
   return child;
@@ -1513,6 +1548,8 @@ static void
 free_variable (struct varobj *var)
   value_free (var->value);
+  if (var->type)
+    type_decref (var->type);
   /* Free the expression if this is a root variable. */
   if (is_root_p (var))
@@ -2784,6 +2821,8 @@ varobj_invalidate (void)
               (*varp)->root->is_valid = 0;
+	/* FIXME: If VALID_BLOCK does not belong to OBJFILE being removed we
+	   should keep this varobj valid.  */
         else /* locals must be invalidated.  */
           (*varp)->root->is_valid = 0;
diff --git a/gdb/varobj.h b/gdb/varobj.h
index f2cdcf8..14b978b 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -141,4 +141,6 @@ extern int varobj_editable_p (struct varobj *var);
 extern int varobj_floating_p (struct varobj *var);
+extern void preserve_variables (struct objfile *objfile, htab_t copied_types);
 #endif /* VAROBJ_H */

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