public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-jankratochvil-misc: Fix crashes due to (missing) varobj revalidation, for VLA [2/2]
@ 2009-05-11 21:46 jkratoch
  0 siblings, 0 replies; only message in thread
From: jkratoch @ 2009-05-11 21:46 UTC (permalink / raw)
  To: archer-commits

The branch, archer-jankratochvil-misc has been updated
       via  378e1f1c9d0d03b33e30fa6a5a20cc0c8336a219 (commit)
       via  9f9993b2892b1067098ea26aa9895808592122cd (commit)
      from  89932f29d9bcb05c1cb74fc91856adb7b771d4a8 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 378e1f1c9d0d03b33e30fa6a5a20cc0c8336a219
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon May 11 23:40:15 2009 +0200

    Fix crashes due to (missing) varobj revalidation, for VLA [2/2]
    
    gdb-varobj-revalidate-core.patch
    Re: [patch] [4/5] Types reference counting [varobj-validation]
    http://sourceware.org/ml/gdb-patches/2009-04/msg00610.html
    
    gdb/
    2009-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>
    
    	Split varobj_invalidate into a two-phased operation.
    	* objfiles.c: Include varobj.h
    	(free_objfile): Call varobj_invalidate.
    	* parser-defs.h (exp_uses_objfile): New prototype.
    	* printcmd.c (display_uses_objfile): Move the EXP checking part to ...
    	* parse.c (exp_uses_objfile): ... a new function here.
    	* symfile.c (new_symfile_objfile): Call varobj_revalidate.
    	(reread_symbols): Call varobj_invalidate and varobj_revalidate.
    	(clear_symtab_users): No longer call varobj_invalidate.
    	* varobj.c: New includes objfiles.h and parser-defs.h.
    	(varobj_invalidate): New parameter `objfile', comment it.
    	New variable `var'.  Invalidate any varobj related to `objfile'.
    	Remove unconditional invalidation of local varobjs.  Move global
    	varobjs revalidation to ...
    	(varobj_revalidate): ... a new function.
    	* varobj.h (varobj_invalidate): Update the prototype.
    	(varobj_revalidate): New prototype.
    
    [ Cut the printcmd.c simplification/change.  ]

commit 9f9993b2892b1067098ea26aa9895808592122cd
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Mon May 11 23:38:35 2009 +0200

    Fix crashes due to (missing) varobj revalidation, for VLA [1/2]
    
    gdb-varobj-revalidate-prep.patch
    Re: [patch] Make a function for block->objfile lookups
    http://sourceware.org/ml/gdb-patches/2009-04/msg00609.html
    
    gdb/
    2009-04-22  Jan Kratochvil  <jan.kratochvil@redhat.com>
    
    	* block.c (block_objfile): New function.
    	* block.h (block_objfile): New prototype.
    	* objfiles.c (matching_objfiles): New function.
    	* objfiles.h (matching_objfiles): New prototype.
    	* printcmd.c: Remove include solib.h.
    	(display_uses_solib_p): Rename to ...
    	(display_uses_objfile): ... a new function name.  Change the SOLIB
    	parameter to OBJFILE parameter.  Use now a matching_objfiles call.
    	(clear_dangling_display_expressions): Update the caller.
    
    [ Cut the printcmd.c simplification/change.  ]

-----------------------------------------------------------------------

Summary of changes:
 gdb/block.c       |   18 ++++++++++
 gdb/block.h       |    2 +
 gdb/objfiles.c    |   20 +++++++++++
 gdb/objfiles.h    |    2 +
 gdb/parse.c       |   39 ++++++++++++++++++++++
 gdb/parser-defs.h |    2 +
 gdb/symfile.c     |    8 ++--
 gdb/varobj.c      |   94 +++++++++++++++++++++++++++++++++++++++++++++-------
 gdb/varobj.h      |    4 ++-
 9 files changed, 171 insertions(+), 18 deletions(-)

First 500 lines of diff:
diff --git a/gdb/block.c b/gdb/block.c
index 8f0140c..2290663 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -309,3 +309,21 @@ allocate_block (struct obstack *obstack)
 
   return bl;
 }
+
+/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for
+   whatever reason.  */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+  struct symbol *func;
+
+  if (block == NULL)
+    return NULL;
+
+  func = block_linkage_function (block);
+  if (func == NULL)
+    return NULL;
+
+  return SYMBOL_SYMTAB (func)->objfile;
+}
diff --git a/gdb/block.h b/gdb/block.h
index 9b43144..ec0aa16 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -164,4 +164,6 @@ extern const struct block *block_global_block (const struct block *block);
 
 extern struct block *allocate_block (struct obstack *obstack);
 
+extern struct objfile *block_objfile (const struct block *block);
+
 #endif /* BLOCK_H */
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 795d53b..0b42c6c 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -50,6 +50,7 @@
 #include "addrmap.h"
 #include "arch-utils.h"
 #include "exec.h"
+#include "varobj.h"
 
 /* Prototypes for local functions */
 
@@ -409,6 +410,7 @@ free_objfile (struct objfile *objfile)
   /* Remove any references to this objfile in the global value
      lists.  */
   preserve_values (objfile);
+  varobj_invalidate (objfile);
 
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
@@ -891,3 +893,21 @@ objfile_data (struct objfile *objfile, const struct objfile_data *data)
   gdb_assert (data->index < objfile->num_data);
   return objfile->data[data->index];
 }
+
+/* Return non-zero if A and B point to the same OBJFILE, ignoring any binary
+   vs. debuginfo variants of the pointers.  If either A or B is NULL return
+   zero as not a match.  */
+
+int
+matching_objfiles (struct objfile *a, struct objfile *b)
+{
+  if (a == NULL || b == NULL)
+    return 0;
+
+  if (a->separate_debug_objfile_backlink)
+    a = a->separate_debug_objfile_backlink;
+  if (b->separate_debug_objfile_backlink)
+    b = b->separate_debug_objfile_backlink;
+
+  return a == b;
+}
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 60d3143..61d61a5 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -497,6 +497,8 @@ extern struct obj_section *find_pc_section (CORE_ADDR pc);
 
 extern int in_plt_section (CORE_ADDR, char *);
 
+extern int matching_objfiles (struct objfile *a, struct objfile *b);
+
 /* Keep a registry of per-objfile data-pointers required by other GDB
    modules.  */
 
diff --git a/gdb/parse.c b/gdb/parse.c
index 96dc1c5..d45ace9 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -1359,6 +1359,45 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
+/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
+   is unloaded), otherwise return 0.  */
+
+int
+exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+{
+  int endpos;
+  const union exp_element *const elts = exp->elts;
+
+  for (endpos = exp->nelts; endpos > 0; )
+    {
+      int i, args, oplen = 0;
+
+      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
+							&oplen, &args);
+      gdb_assert (oplen > 0);
+
+      i = endpos - oplen;
+      if (elts[i].opcode == OP_VAR_VALUE)
+	{
+	  const struct block *const block = elts[i + 1].block;
+	  const struct symbol *const symbol = elts[i + 2].symbol;
+	  const struct obj_section *const section =
+	    SYMBOL_OBJ_SECTION (symbol);
+
+	  /* Check objfile where is placed the code touching the variable.  */
+	  if (matching_objfiles (block_objfile (block), objfile))
+	    return 1;
+
+	  /* Check objfile where the variable itself is placed.  */
+	  if (section && section->objfile == objfile)
+	    return 1;
+	}
+      endpos -= oplen;
+    }
+
+  return 0;
+}
+
 void
 _initialize_parse (void)
 {
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index cbda9c3..3159a21 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -299,4 +299,6 @@ extern void print_subexp_standard (struct expression *, int *,
 
 extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3);
 
+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
 #endif /* PARSER_DEFS_H */
diff --git a/gdb/symfile.c b/gdb/symfile.c
index af1ab74..54d2bad 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -927,6 +927,8 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
 
   /* We're done reading the symbol file; finish off complaints.  */
   clear_complaints (&symfile_complaints, 0, verbo);
+
+  varobj_revalidate ();
 }
 
 /* Process a symbol file, as either the main file or as a dynamically
@@ -2341,6 +2343,7 @@ reread_symbols (void)
 	      /* Remove any references to this objfile in the global
 		 value lists.  */
 	      preserve_values (objfile);
+	      varobj_invalidate (objfile);
 
 	      /* Nuke all the state that we will re-read.  Much of the following
 	         code which sets things to NULL really is necessary to tell
@@ -2437,6 +2440,7 @@ reread_symbols (void)
 	         frameless.  */
 
 	      reinit_frame_cache ();
+	      varobj_revalidate ();
 
 	      /* Discard cleanups as symbol reading was successful.  */
 	      discard_cleanups (old_cleanups);
@@ -2817,10 +2821,6 @@ clear_symtab_users (void)
      between expressions and which ought to be reset each time.  */
   expression_context_block = NULL;
   innermost_block = NULL;
-
-  /* Varobj may refer to old symbols, perform a cleanup.  */
-  varobj_invalidate ();
-
 }
 
 static void
diff --git a/gdb/varobj.c b/gdb/varobj.c
index 6c228d0..8b4c2e0 100644
--- a/gdb/varobj.c
+++ b/gdb/varobj.c
@@ -26,6 +26,8 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "valprint.h"
+#include "objfiles.h"
+#include "parser-defs.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -2763,12 +2765,15 @@ When non-zero, varobj debugging is enabled."),
 			    &setlist, &showlist);
 }
 
-/* Invalidate the varobjs that are tied to locals and re-create the ones that
-   are defined on globals.
+/* Invalidate the varobjs that are tied to the specified OBJFILE.  Call this
+   function before you start removing OBJFILE.
+
+   Call varobj_revalidate after the OBJFILEs updates get finished.
+
    Invalidated varobjs will be always printed in_scope="invalid".  */
 
 void 
-varobj_invalidate (void)
+varobj_invalidate (struct objfile *objfile)
 {
   struct varobj **all_rootvarobj;
   struct varobj **varp;
@@ -2778,36 +2783,99 @@ varobj_invalidate (void)
       varp = all_rootvarobj;
       while (*varp != NULL)
 	{
+	  struct varobj *var = *varp;
+
+	  /* Floating varobjs are reparsed on each stop, so we don't care if
+	     the presently parsed expression refers to something that's gone.
+	     */
+	  if (var->root->floating)
+	    continue;
+
+	  if (var->root->is_valid
+	      && matching_objfiles (block_objfile (var->root->valid_block),
+	                            objfile))
+	    var->root->is_valid = 0;
+	  
+	  if (var->root->is_valid
+	      && exp_uses_objfile (var->root->exp, objfile))
+	    {
+	      var->root->is_valid = 0;
+
+	      /* No one touches EXP for !IS_VALID varobj.  */
+	      xfree (var->root->exp);
+	      var->root->exp = NULL;
+	    }
+	  
+	  if (var->type && TYPE_OBJFILE (var->type) == objfile)
+	    {
+	      if (!var->root->valid_block)
+		var->root->is_valid = 0;
+	      else
+		gdb_assert (!var->root->is_valid);
+
+	      var->type = NULL;
+	    }
+
+	  if (var->value
+	      && TYPE_OBJFILE (value_type (var->value)) == objfile)
+	    {
+	      if (!var->root->valid_block)
+		var->root->is_valid = 0;
+	      else
+		gdb_assert (!var->root->is_valid);
+
+	      value_free (var->value);
+	      var->value = NULL;
+	    }
+
+	  varp++;
+	}
+    }
+  xfree (all_rootvarobj);
+}
+
+/* Recreate any global varobjs possibly previously invalidated.  If the
+   expressions are no longer evaluatable set/keep the varobj invalid.  */
+
+void 
+varobj_revalidate (void)
+{
+  struct varobj **all_rootvarobj;
+  struct varobj **varp;
+
+  if (varobj_list (&all_rootvarobj) > 0)
+    {
+      varp = all_rootvarobj;
+      while (*varp != NULL)
+	{
+	  struct varobj *var = *varp;
+
 	  /* Floating varobjs are reparsed on each stop, so we don't care if
 	     the presently parsed expression refers to something that's gone.
 	     */
-	  if ((*varp)->root->floating)
+	  if (var->root->floating)
 	    continue;
 
 	  /* global var must be re-evaluated.  */     
-	  if ((*varp)->root->valid_block == NULL)
+	  if (var->root->valid_block == NULL)
 	    {
 	      struct varobj *tmp_var;
 
 	      /* Try to create a varobj with same expression.  If we succeed
 		 replace the old varobj, otherwise invalidate it.  */
-	      tmp_var = varobj_create (NULL, (*varp)->name, (CORE_ADDR) 0,
-				       USE_CURRENT_FRAME);
+	      tmp_var = varobj_create (NULL, var->name, 0, USE_CURRENT_FRAME);
 	      if (tmp_var != NULL) 
 		{ 
-		  tmp_var->obj_name = xstrdup ((*varp)->obj_name);
-		  varobj_delete (*varp, NULL, 0);
+		  tmp_var->obj_name = xstrdup (var->obj_name);
+		  varobj_delete (var, NULL, 0);
 		  install_variable (tmp_var);
 		}
 	      else
-		(*varp)->root->is_valid = 0;
+		var->root->is_valid = 0;
 	    }
-	  else /* locals must be invalidated.  */
-	    (*varp)->root->is_valid = 0;
 
 	  varp++;
 	}
     }
   xfree (all_rootvarobj);
-  return;
 }
diff --git a/gdb/varobj.h b/gdb/varobj.h
index f2cdcf8..85f2890 100644
--- a/gdb/varobj.h
+++ b/gdb/varobj.h
@@ -135,7 +135,9 @@ extern int varobj_list (struct varobj ***rootlist);
 extern VEC(varobj_update_result) *varobj_update (struct varobj **varp, 
 						 int explicit);
 
-extern void varobj_invalidate (void);
+extern void varobj_invalidate (struct objfile *objfile);
+
+extern void varobj_revalidate (void);
 
 extern int varobj_editable_p (struct varobj *var);
 


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-05-11 21:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-11 21:46 [SCM] archer-jankratochvil-misc: Fix crashes due to (missing) varobj revalidation, for VLA [2/2] jkratoch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).