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] varobj deletion after the binary has changed


Daniel Jacobowitz wrote:
I haven't looked at the patch yet, just Nick's comments, which I
generally agree with :-)

On Fri, Jan 26, 2007 at 11:31:35AM +1300, Nick Roberts wrote:
Is xstrdup just a simpler version of savestring? i.e.
tmp_var->obj_name = xstrdup (*varp)->obj_name);

Yes - savestring is handy for saving only part of a string but xstrdup is clearer.

Attached is a new implementation, it takes care of more cases where seg fault occured.

I take Nick's suggestion into account, -var-update outputs the following for invalid variables:
changelist=[{name="linteger",in_scope="invalid"}]


About this last change, I'm wondering if frond-ends that expect "true" or "false" will handle this new outputs correctly, it's just a question of backward compatibility. Of course it will be better that the old behavior that crashes gdb !
If you're fine I'll write appropriate ChangeLogs.


I also wrote a new .exp file in gdb.mi testsuite, I'll propose it on this one approval.

--
Denis
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.180
diff -u -p -r1.180 symfile.c
--- symfile.c	21 Jan 2007 01:02:03 -0000	1.180
+++ symfile.c	29 Jan 2007 12:09:46 -0000
@@ -52,6 +52,7 @@
 #include "observer.h"
 #include "exec.h"
 #include "parser-defs.h"
+#include "varobj.h"
 
 #include <sys/types.h>
 #include <fcntl.h>
@@ -2602,6 +2603,10 @@ 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
Index: varobj.c
===================================================================
RCS file: /cvs/src/src/gdb/varobj.c,v
retrieving revision 1.82
diff -u -p -r1.82 varobj.c
--- varobj.c	24 Jan 2007 19:54:13 -0000	1.82
+++ varobj.c	29 Jan 2007 12:09:55 -0000
@@ -71,6 +71,10 @@ struct varobj_root
      using the currently selected frame. */
   int use_selected_frame;
 
+  /* Flag that indicates validity: set to 0 when this varobj_root refers 
+     to symbols that do not exist anymore.  */
+  int is_valid;
+
   /* Language info for this variable and its children */
   struct language_specific *lang;
 
@@ -742,8 +746,9 @@ varobj_get_type (struct varobj *var)
   long length;
 
   /* For the "fake" variables, do not return a type. (It's type is
-     NULL, too.) */
-  if (CPLUS_FAKE_CHILD (var))
+     NULL, too.)
+     Do not return a type for invalid variables as well.  */
+  if (CPLUS_FAKE_CHILD (var) || !var->root->is_valid)
     return NULL;
 
   stb = mem_fileopen ();
@@ -778,7 +783,7 @@ varobj_get_attributes (struct varobj *va
 {
   int attributes = 0;
 
-  if (variable_editable (var))
+  if (var->root->is_valid && variable_editable (var))
     /* FIXME: define masks for attributes */
     attributes |= 0x00000001;	/* Editable */
 
@@ -1021,6 +1026,7 @@ install_new_value (struct varobj *var, s
    Return value:
     -1 if there was an error updating the varobj
     -2 if the type changed
+    -3 if the varobj root is invalid
     Otherwise it is the number of children + parent changed
 
    Only root variables can be updated... 
@@ -1055,6 +1061,9 @@ varobj_update (struct varobj **varp, str
     /* Not a root var */
     return -1;
 
+  if (!(*varp)->root->is_valid)
+    return -3;
+
   /* Save the selected stack frame, since we will need to change it
      in order to evaluate expressions. */
   old_fid = get_frame_id (deprecated_selected_frame);
@@ -1409,6 +1418,7 @@ new_root_variable (void)
   var->root->frame = null_frame_id;
   var->root->use_selected_frame = 0;
   var->root->rootvar = NULL;
+  var->root->is_valid = 1;
 
   return var;
 }
@@ -1692,7 +1702,10 @@ variable_editable (struct varobj *var)
 static char *
 my_value_of_variable (struct varobj *var)
 {
-  return (*var->root->lang->value_of_variable) (var);
+  if (var->root->is_valid)
+    return (*var->root->lang->value_of_variable) (var);
+  else
+    return NULL;
 }
 
 static char *
@@ -2504,3 +2517,44 @@ When non-zero, varobj debugging is enabl
 			    show_varobjdebug,
 			    &setlist, &showlist);
 }
+
+/* Invalidate the varobjs that are tied to locals and re-create the ones that
+   are defined on globals.
+   Invalidated varobjs will be always printed in_scope="false".  */
+void 
+varobj_invalidate (void)
+{
+  struct varobj **all_rootvarobj;
+  struct varobj **varp;
+
+  if (varobj_list (&all_rootvarobj) > 0)
+  {
+    varp = all_rootvarobj;
+    while (*varp != NULL)
+      {
+        /* global var must be re-evaluated.  */     
+        if ((*varp)->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);
+          if (tmp_var != NULL) 
+            { 
+	      tmp_var->obj_name = xstrdup ((*varp)->obj_name);
+              varobj_delete (*varp, NULL, 0);
+              install_variable (tmp_var);
+            }
+          else
+              (*varp)->root->is_valid = 0;
+        }
+        else /* locals must be invalidated.  */
+          (*varp)->root->is_valid = 0;
+
+        varp++;
+      }
+    xfree (all_rootvarobj);
+  }
+  return;
+}
Index: varobj.h
===================================================================
RCS file: /cvs/src/src/gdb/varobj.h,v
retrieving revision 1.7
diff -u -p -r1.7 varobj.h
--- varobj.h	9 Jan 2007 17:58:59 -0000	1.7
+++ varobj.h	29 Jan 2007 12:09:56 -0000
@@ -99,4 +99,6 @@ extern int varobj_list (struct varobj **
 
 extern int varobj_update (struct varobj **varp, struct varobj ***changelist);
 
+extern void varobj_invalidate (void);
+
 #endif /* VAROBJ_H */
Index: mi/mi-cmd-var.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmd-var.c,v
retrieving revision 1.28
diff -u -p -r1.28 mi-cmd-var.c
--- mi/mi-cmd-var.c	9 Jan 2007 17:59:08 -0000	1.28
+++ mi/mi-cmd-var.c	29 Jan 2007 12:09:58 -0000
@@ -555,12 +555,12 @@ varobj_update_one (struct varobj *var, e
   
   if (nc == 0)
     return 1;
-  else if (nc == -1)
+  else if (nc == -1 || nc == -3)
     {
       if (mi_version (uiout) > 1)
         cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
       ui_out_field_string (uiout, "name", varobj_get_objname(var));
-      ui_out_field_string (uiout, "in_scope", "false");
+      ui_out_field_string (uiout, "in_scope", (nc == -3 ? "invalid" : "false"));
       if (mi_version (uiout) > 1)
         do_cleanups (cleanup);
       return -1;

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