This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
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;