[PATCH] keep-variable command

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH] keep-variable command

Andrew Stubbs-2
Hi,

This patch adds a command 'keep-variable'. The command takes one single
parameter - a convenience variable.

This variable is then protected from being deleted by the symbol-file
command. In order to achieve this it must patch up the type information
after the symbol table has changed. If the type cannot be fixed up then
a warning is given and the value is lost. Lazy fixup means that this
only happens if the variable is actually accessed.

If the keep-variable is never used then variables work exactly as before.

I feel certain that there is something somebody will not like about this
implementation, but I hope we can sort it out.

The patch requires that my endian fixup patch has been applied first.
The context in the patch assumes the init-if-undefined has been applied
first, although the patch is not actually dependent.

Thanks

Andrew Stubbs

2005-11-16  Andrew Stubbs  <[hidden email]>

        * value.c: Include exceptions.h.
        (fixup_internalvar_endian): Don't fix the endian if the type
        needs fixing due to keep-variable.
        (keep_variable_command): New function.
        (fixup_internalvar_type_info): New function.
        (lookup_internalvar): Call fixup_internalvar_type_info() if needed.
        Initialise new 'temp' and 'type_needs_fixing' fields.
        (set_internalvar): Reset type_needs_fixing.
        (get_name_from_type): New function.
        (clear_internalvars): Rewrite to support keep-variable command.
        (show_convenience): Call fixup_internalvar_type_info() if needed.
        (_initialize_values): Add keep-variable command.
        * exec.c (exec_file_attach). Call clear_internalvars().
        * symfile.c (symbol_file_command). Call clear_internalvars().
        * value.h (struct internalvar): Add 'temp', 'type_needs_fixing',
        'type_name', and 'enclosing_type_name' fields.
        * Makefile.in (value.o): Add dependency on exceptions.h.

doc/
        * gdb.texinfo (Convenience variables): Add keep-variable command.

Index: src/gdb/value.c
===================================================================
--- src.orig/gdb/value.c 2005-11-07 18:27:03.000000000 +0000
+++ src/gdb/value.c 2005-11-07 18:27:04.000000000 +0000
@@ -37,6 +37,7 @@
 #include "gdb_assert.h"
 #include "regcache.h"
 #include "block.h"
+#include "exceptions.h"
 
 /* Prototypes for exported functions. */
 
@@ -779,10 +780,12 @@ fixup_internalvar_endian (struct interna
   gdb_byte temp;
   gdb_byte *array = value_contents_raw (var->value);
 
-  /* Don't do anything if the endian has not changed.
+  /* Don't do anything if the endian has not changed or if the type needs
+     fixing - the endian will be fixed with the type later.
      Also disregard FP types because they don't seem to vary with
      endian - at least, not on i686 Linux or sparc Solaris.  */
   if (var->endian != TARGET_BYTE_ORDER
+      && var->type_needs_fixing == 0
       && TYPE_CODE (value_type (var->value)) != TYPE_CODE_FLT)
     {
       /* Reverse the bytes.
@@ -811,6 +814,92 @@ fixup_all_internalvars_endian (void)
 }
 
 
+/* Ensure that the specified internal variable will not be destroyed
+   when new symtabs are loaded. The argument 'name', must
+   be an internal variable name, prefixed with a dollar character.  */
+static void
+keep_variable_command (char* name, int from_tty)
+{
+  struct internalvar* intvar;
+  char* str;
+
+  if (name == NULL || name[0] != '$')
+    {
+      printf_unfiltered( "usage: keep-variable $<var>\n" );
+      return;
+    }
+
+  str = ++name;            /* Remove $ character, i.e. "$var" ==> "var"  */
+  intvar = lookup_internalvar(str);
+  intvar->temp = 0;        /* Preserve variable by clearing 'temp' attribute */
+}
+
+/* If the symbol table is reloaded then permanent variables will lose
+   their type info. clear_internalvars() makes a note of the name of
+   any such types in the variable.
+   This function is called whenever the variable is next required to
+   get the new type info. It also fixes the endianess if required.  */
+
+static void
+fixup_internalvar_type_info (struct internalvar *var)
+{
+  int i, error=0;
+
+  /* For each in type and enclosing type ...  */
+  for (i=0; i<2; i++)
+    {
+      char *type_name = i==0 ? var->type_name
+     : var->enclosing_type_name;
+      struct type **var_type = i==0 ? &var->value->type
+    : &var->value->enclosing_type;
+
+      if (type_name != NULL)
+ {
+  /* Get the typename using parse expression - it can cope
+     with builtin types even when there is no symbol table.  */
+  struct expression *expr = (struct expression *)
+    catch_errors ((catch_errors_ftype *)parse_expression,
+  type_name, NULL, RETURN_MASK_ALL);
+  register struct cleanup *old_chain =
+    make_cleanup (free_current_contents, &expr);
+
+  if (expr != NULL && expr->nelts >= 2
+      && expr->elts[0].opcode == OP_TYPE)
+    /* Overwite the old (now broken) type with the shiny new one.  */
+    *var_type = expr->elts[1].type;
+  else
+    error=1;
+
+  do_cleanups (old_chain);
+ }
+    }
+
+
+  if (error)
+    {
+      /* Types no longer exist.
+ The only thing to do is wipe the value.  */
+      xfree (var->value);
+      var->value = allocate_value (builtin_type_void);
+      release_value (var->value);
+
+      /* Tell the user we have had to do this.
+ The message will occur when they are accessing the variable.  */
+      printf_unfiltered (
+ "The type of '$%s' was lost when the symbol table was updated.\n",
+ var->name);
+    }
+
+  /* Return the internal variable to its normal state.  */
+  xfree (var->type_name);
+  xfree (var->enclosing_type_name);
+  var->type_needs_fixing = 0;
+
+  /* Fix up the endianess.  */
+  fixup_internalvar_endian (var);
+}
+
+
 /* Look up an internal variable with name NAME.  NAME should not
    normally include a dollar sign.
 
@@ -824,12 +913,18 @@ lookup_internalvar (char *name)
 
   for (var = internalvars; var; var = var->next)
     if (strcmp (var->name, name) == 0)
-      return var;
+      {
+ if (var->type_needs_fixing)
+  fixup_internalvar_type_info (var);
+ return var;
+      }
 
   var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
   var->name = concat (name, (char *)NULL);
   var->value = allocate_value (builtin_type_void);
   var->endian = TARGET_BYTE_ORDER;
+  var->temp = 1;
+  var->type_needs_fixing = 0;
   release_value (var->value);
   var->next = internalvars;
   internalvars = var;
@@ -885,6 +980,7 @@ set_internalvar (struct internalvar *var
   xfree (var->value);
   var->value = newval;
   var->endian = TARGET_BYTE_ORDER;
+  var->type_needs_fixing = 0;
   release_value (newval);
   /* End code which must not call error().  */
 }
@@ -895,21 +991,136 @@ internalvar_name (struct internalvar *va
   return var->name;
 }
 
-/* Free all internalvars.  Done when new symtabs are loaded,
-   because that makes the values invalid.  */
+
+/* Get the typename from a struct type.
+   Returns the name of type as parse_expresion will understand.
+   Returns NULL if the type is unsupported.  */
+
+static char *
+get_name_from_type (const struct type *type)
+{
+  char *result;
+  char *prefix = NULL, pointers=0;
+
+  /* Follow the pointer types until the base type is discovered.  */
+  while (TYPE_CODE (type) == TYPE_CODE_PTR)
+    {
+      pointers++;
+      type = TYPE_TARGET_TYPE (type);
+    }
+
+  /* Find the appropriate string for the type.
+     If we can't find one then return NULL and fixup_internalvar_type_info()
+     will replace the variable with void.  If this is a problem then this
+     table will have to be extended to support the relavent type.  */
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_STRUCT:
+      prefix = "struct";
+      /* Fall through.  */
+    case TYPE_CODE_UNION:
+      if (prefix == NULL)
+ prefix = "union";
+      /* Fall through.  */
+    case TYPE_CODE_ENUM:
+      if (prefix == NULL)
+ prefix = "enum";
+
+      /* Note that these types do not have names, but do have tag names.  */
+
+      if (TYPE_TAG_NAME(type) == NULL)
+ return NULL;
+
+      result = xmalloc (strlen (prefix)
+ + 1 /* space */
+ + strlen (TYPE_TAG_NAME(type))
+ + 1 /* space */
+ + pointers
+ + 1 /* terminator */);
+      sprintf( result, "%s %s ", prefix, TYPE_TAG_NAME(type));
+
+      break;
+    default:
+      /* Other types all (?) have names.  */
+
+      if ( TYPE_NAME(type) == NULL )
+ return NULL;
+
+      result = xmalloc (strlen (TYPE_NAME(type))
+ + 1 /* space */
+ + pointers
+ + 1 /* terminator */);
+      sprintf (result, "%s ", TYPE_NAME(type));
+    }
+
+  /* Add stars for pointer types.  */
+  while ( pointers-- > 0 )
+    strcat (result, "*");
+
+  return result;
+}
+
+
+/* Traverse list of intervalvars.  If an internalvar's 'temp'
+   attribute is set, then free it - otherwise ignore it and check
+   the next member of the list.  Ensure that 'internalvars' points
+   to the head of the list.
+
+   Although the variables are kept, the type information is not.
+   Therefore take a note of the textual names.  The types will then
+   be patched up later when they are referenced.  The function that
+   does this is fixup_internalvars_type_info().
+
+   In order to take the notes BEFORE the types vanish a few extra
+   calls to this function have been inserted elsewhere.
+
+   The majority of internalvar's will be cleared when new symtabs are
+   loaded, because at this point they become invalid.  */
 
 void
 clear_internalvars (void)
 {
   struct internalvar *var;
+  struct internalvar *next, **prev;
 
-  while (internalvars)
+  var = internalvars;
+  prev = &internalvars;
+
+  while (var)
     {
-      var = internalvars;
-      internalvars = var->next;
-      xfree (var->name);
-      xfree (var->value);
-      xfree (var);
+      next = var->next;
+
+      /* Is this a temporary variable? If so - free it.  */
+      if (var->temp)
+ {
+  /* Move the next variable up the list - we may want to keep it.  */
+  *prev = next;
+
+  xfree (var->name);
+  xfree (var->value);
+  xfree (var);
+ }
+      else
+ {
+  /* This is a permanent variable so it will not be removed from
+     the list.  Mark it as the current tail of the list.  */
+  prev = &var->next;
+
+  /* Note down the values of the types.
+     This ensures that they can be fixed up after the symbol
+     tables are rebuilt.
+     Don't do it twice - the lazy fixup means it may not have been
+     fixed since the last time we were here.  */
+  if ( var->type_needs_fixing == 0 )
+    {
+      var->type_needs_fixing = 1;
+      var->type_name = get_name_from_type (var->value->type);
+      var->enclosing_type_name =
+ get_name_from_type (var->value->enclosing_type);
+    }
+ }
+
+      var = next;
     }
 }
 
@@ -921,6 +1132,9 @@ show_convenience (char *ignore, int from
 
   for (var = internalvars; var; var = var->next)
     {
+      if (var->type_needs_fixing)
+ fixup_internalvar_type_info (var);
+
       if (!varseen)
  {
   varseen = 1;
@@ -1730,4 +1944,7 @@ A few convenience variables are given va
 init-if-undefined <var> = <expr>\n\
 Ensure that an internal variable exists and set it to\n\
 a given value if it does not."));
+
+  add_com("keep-variable", class_vars, keep_variable_command,
+  _("Ensures that specified internal variable will not be removed"));
 }
Index: src/gdb/exec.c
===================================================================
--- src.orig/gdb/exec.c 2005-11-07 17:22:56.000000000 +0000
+++ src/gdb/exec.c 2005-11-07 18:27:04.000000000 +0000
@@ -266,6 +266,11 @@ exec_file_attach (char *filename, int fr
 
       validate_files ();
 
+      /* Delete convenience variables BEFORE their types become invalid.
+ This way a note can be made of what the types of the permanent
+ variables were and they can recover later. */
+      clear_internalvars ();
+
       set_gdbarch_from_file (exec_bfd);
 
       push_target (&exec_ops);
Index: src/gdb/symfile.c
===================================================================
--- src.orig/gdb/symfile.c 2005-11-07 17:22:56.000000000 +0000
+++ src/gdb/symfile.c 2005-11-07 18:27:04.000000000 +0000
@@ -1268,6 +1268,11 @@ symbol_file_command (char *args, int fro
 {
   dont_repeat ();
 
+  /* Delete convenience variables BEFORE their types become invalid.
+     This way a note can be made of what the types of the permanent
+     variables were and they can recover later. */
+  clear_internalvars ();
+
   if (args == NULL)
     {
       symbol_file_clear (from_tty);
Index: src/gdb/value.h
===================================================================
--- src.orig/gdb/value.h 2005-11-07 18:27:03.000000000 +0000
+++ src/gdb/value.h 2005-11-07 18:27:04.000000000 +0000
@@ -246,6 +246,15 @@ struct internalvar
   char *name;
   struct value *value;
   int endian;
+
+  /* 'temp' determines whether the variable will be destroyed when
+     new symtabs are loaded.  */
+  int temp;
+  /* These are used to fixup the type pointers after the symbol tables
+     are reloaded.  */
+  char type_needs_fixing;
+  char *type_name;
+  char *enclosing_type_name;
 };
 
 
Index: src/gdb/Makefile.in
===================================================================
--- src.orig/gdb/Makefile.in 2005-11-07 18:27:03.000000000 +0000
+++ src/gdb/Makefile.in 2005-11-07 18:27:04.000000000 +0000
@@ -2735,7 +2735,7 @@ valprint.o: valprint.c $(defs_h) $(gdb_s
 value.o: value.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
  $(value_h) $(gdbcore_h) $(command_h) $(gdbcmd_h) $(target_h) \
  $(language_h) $(scm_lang_h) $(demangle_h) $(doublest_h) \
- $(gdb_assert_h) $(regcache_h) $(block_h)
+ $(gdb_assert_h) $(regcache_h) $(block_h) $(exceptions_h)
 varobj.o: varobj.c $(defs_h) $(value_h) $(expression_h) $(frame_h) \
  $(language_h) $(wrapper_h) $(gdbcmd_h) $(gdb_string_h) $(varobj_h)
 vaxbsd-nat.o: vaxbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) $(target_h) \
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2005-11-07 18:27:03.000000000 +0000
+++ src/gdb/doc/gdb.texinfo 2005-11-07 19:01:11.000000000 +0000
@@ -6120,6 +6120,11 @@ Using a convenience variable for the fir
 value is @code{void} until you assign a new value.  You can alter the
 value with another assignment at any time.
 
+@value{GDBN} commands that wipe the symbol table, such as @samp{file} and
+@samp{symbol-file}, cause all convenience variables to be deleted - their
+types are lost so their value would become meaningless.  This can be avoided
+using the @samp{keep-variable} command below.
+
 Convenience variables have no fixed types.  You can assign a convenience
 variable any type of value, including structures and arrays, even if
 that variable already has a value of a different type.  The convenience
@@ -6143,6 +6148,24 @@ override default values used in a comman
 
 If the variable is already defined then the expression is not evaluated so
 any side-effects do not occur.
+
+@kindex keep-variable
+@cindex convenience variables, keeping
+@item keep-variable $@var{variable}
+Mark the variable to be preserved across commands which destroy the symbol
+table, such as @samp{symbol-file}.
+
+The next time the variable is accessed (by whatever means) @value{GDBN} will
+attempt to find a type, in the current symbol table, with the same name as
+the type used previously.  It does not check whether the new type is in any
+way compatible with the old type.
+
+If a suitable type does not exist (at the time the variable is accessed) then
+@value{GDBN} will print a message and reset the value to @code{void}.
+
+If the symbol table is destroyed and recreated multiple times, the content
+of the intermediate tables has no effect, @emph{provided that the variable
+is not accessed while they are loaded}.
 @end table
 
 One of the ways to use a convenience variable is as a counter to be
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Eli Zaretskii
> Date: Wed, 16 Nov 2005 14:40:33 +0000
> From: Andrew STUBBS <[hidden email]>
>
> +@value{GDBN} commands that wipe the symbol table, such as @samp{file} and
> +@samp{symbol-file}, cause all convenience variables to be deleted - their
                                                                    ^^^
Please use "---" (3 dashes in a row) to produce a dash (as opposed to
the minus sign).

> +types are lost so their value would become meaningless.  This can be avoided
> +using the @samp{keep-variable} command below.

It's possible this is something I never knew about: is it actually
correct that _all_ convenience variables are deleted when `file' is
used?  The explanation above about their types being lost doesn't make
sense to me; can you explain?  For example, if I define a variable
that holds an integer number, why would its type become meaningless?

> +The next time the variable is accessed (by whatever means) @value{GDBN} will
> +attempt to find a type, in the current symbol table, with the same name as
> +the type used previously.  It does not check whether the new type is in any
> +way compatible with the old type.
> +
> +If a suitable type does not exist (at the time the variable is accessed) then
> +@value{GDBN} will print a message and reset the value to @code{void}.
> +
> +If the symbol table is destroyed and recreated multiple times, the content
> +of the intermediate tables has no effect, @emph{provided that the variable
> +is not accessed while they are loaded}.

Does this description assume that convenience variables point, or are
somehow related, to the symbol table?  If so, why does this assumption
hold for every convenience variable?  I can think of a convenience
variable that has no relation whatsoever to the symbol table; how does
such a variable fit into the above scheme?
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

jimb (Bugzilla)
On 11/16/05, Andrew STUBBS <[hidden email]> wrote:
> I feel certain that there is something somebody will not like about this
> implementation, but I hope we can sort it out.

How did you know?  :)

Let me answer Eli's questions first:

On 11/16/05, Eli Zaretskii <[hidden email]> wrote:
> > +types are lost so their value would become meaningless.  This can be avoided
> > +using the @samp{keep-variable} command below.
>
> It's possible this is something I never knew about: is it actually
> correct that _all_ convenience variables are deleted when `file' is
> used?  The explanation above about their types being lost doesn't make
> sense to me; can you explain?  For example, if I define a variable
> that holds an integer number, why would its type become meaningless?

It wouldn't, necessarily; certainly GDB still knows the meaning of
'int' given only the current architecture and the current language.  I
don't see any reason we couldn't keep a convenience variable if all
its types belonged to objfiles (according to type->objfile) that we
were going to keep around.

I believe if you say "set var $foo = 1", then $foo's type is one of
the builtin type objects, whose objfile is NULL.  There's no reason to
throw away convenience variables all of whose types were like this.

But Andrew's going way farther than that: he's actually trying to keep
convenience variables whose types definitely belong to the symfile
that's being reloaded.  Very ambitious.

Okay, back to Andrew's patch.

- Converting types to strings needs to be done in a
  language-independent manner.  It's a shame that types don't seem to
  point to a language.  But it would be better to use LA_PRINT_TYPE
  than to build the name by hand.

- Types can be local to some scope.  Even if you print out a type's
  name, how can you discover what scope to re-parse it in?  Right now
  you're just getting whatever happens to be in
  expression_context_block, right?

Do you really need all this?  Can you tell us more about the situation?
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Daniel Jacobowitz-2
On Wed, Nov 16, 2005 at 03:28:27PM -0800, Jim Blandy wrote:
> On 11/16/05, Andrew STUBBS <[hidden email]> wrote:
> > I feel certain that there is something somebody will not like about this
> > implementation, but I hope we can sort it out.
>
> How did you know?  :)

I haven't even looked at the implementation yet; I'd like to talk about
the concept first.

For one thing, why is this a command at all?  If we support keeping
convenience variables across symbol file reloads, then why not do it by
default for all convenience variables?  I doubt having them disappear
has ever been considered a feature.

> It wouldn't, necessarily; certainly GDB still knows the meaning of
> 'int' given only the current architecture and the current language.  I
> don't see any reason we couldn't keep a convenience variable if all
> its types belonged to objfiles (according to type->objfile) that we
> were going to keep around.

This is a bit complicated by the fact that the objfile may define a
type named "int", so some care is in order...

> I believe if you say "set var $foo = 1", then $foo's type is one of
> the builtin type objects, whose objfile is NULL.  There's no reason to
> throw away convenience variables all of whose types were like this.

If true, this does improve things a bit.  Of course, pointers are just
as much of a problem.

> - Converting types to strings needs to be done in a
>   language-independent manner.  It's a shame that types don't seem to
>   point to a language.  But it would be better to use LA_PRINT_TYPE
>   than to build the name by hand.

Alternatively, we could add code to duplicate the types recursively
onto a convenience variable obstack.  GDB doesn't have much of a notion
of "type compatibility".  It might not work 100% right for things like
C++ operator overloading, but for that we'd need to do type merging
anyway.

> - Types can be local to some scope.  Even if you print out a type's
>   name, how can you discover what scope to re-parse it in?  Right now
>   you're just getting whatever happens to be in
>   expression_context_block, right?

This is a pre-existing disaster zone.  We have similar problems for
resetting breakpoints, IIRC (or else will eventually).

--
Daniel Jacobowitz
CodeSourcery, LLC
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Andrew Stubbs-2
In reply to this post by Eli Zaretskii
Eli Zaretskii wrote:
> It's possible this is something I never knew about: is it actually
> correct that _all_ convenience variables are deleted when `file' is
> used?  The explanation above about their types being lost doesn't make
> sense to me; can you explain?  For example, if I define a variable
> that holds an integer number, why would its type become meaningless?

Currently _all_ convenience variables are deleted when the symbol-file
command is used. The file command also uses symbol-file.

The explanation I gave refers to the situation after my patch has been
applied and the debugger is attempting to keep some variables. You are
correct when you say that basic types will always exist. However, I did
not want to assume that they will be kept in the same place. Our initial
implementation did not attempt to fix this up at all and worked for
quite a while before anybody noticed it didn't work (badly) with unusual
types. Investigation showed that it was only working with basic types by
chance - the new types just happened to be at the same addresses, so I
fixed it up properly as you see it now. There is always the possibility
of a file redefining any type, of course, so you may not be using the
int you thought you were using.

> Does this description assume that convenience variables point, or are
> somehow related, to the symbol table?  If so, why does this assumption
> hold for every convenience variable?  I can think of a convenience
> variable that has no relation whatsoever to the symbol table; how does
> such a variable fit into the above scheme?

All variables must have a type, even void ones, as far as I can tell.
The type is recorded in terms of a reference into a table of types which
is related to the symbol table in some way I do not claim to fully
understand. What is certain is that symbol-file wipes the type table.

Please give your example of a convenience variable with no relation to
the symbol table.

Andrew
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Andrew Stubbs-2
In reply to this post by jimb (Bugzilla)
Jim Blandy wrote:
> - Converting types to strings needs to be done in a
>   language-independent manner.  It's a shame that types don't seem to
>   point to a language.  But it would be better to use LA_PRINT_TYPE
>   than to build the name by hand.

That prints to a stream. Is there a way to make it 'print' to a buffer?
I haven't studied it in depth.

> - Types can be local to some scope.  Even if you print out a type's
>   name, how can you discover what scope to re-parse it in?  Right now
>   you're just getting whatever happens to be in
>   expression_context_block, right?

Yes, but the variables are fixed up lazily. In theory, if the user
doesn't access it until it makes sense then there will be no problem. Of
course, if they just say 'show conv' then some variables may well not
find types.

> Do you really need all this?  Can you tell us more about the situation?

We have a number of scripts which want to keep values regardless of what
happens to the symbol tables - they mostly describe the configuration of
the target (location of memory mapped registers, that kind of thing). I
think they are all just char, int or pointer variants of those.

This worked OK for a while without anything special (we just didn't
delete them), but the type fixing was in response to some evil crashing
bugs we had. I discovered it had been working more by chance than design
and did something about it - it is always wrong to make assumptions
about pointers into tables that are being rebuilt. The fact that made it
work for other types was something of a freebie.

Regardless of whether I really _need_ all of it I rather _like_ the fact
that it Just Works ... mostly.

Andrew
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Andrew Stubbs-2
In reply to this post by Daniel Jacobowitz-2
Daniel Jacobowitz wrote:
> For one thing, why is this a command at all?  If we support keeping
> convenience variables across symbol file reloads, then why not do it by
> default for all convenience variables?  I doubt having them disappear
> has ever been considered a feature.

If it doesn't find a type for the variable it gives a message and sets
the value to void. This would be irritating with a large number of
variables you no longer care about. Otherwise I would agree with you.

Perhaps instead of the message the value could somehow be shown as
'<type lost>', in which case it wouldn't matter so much. I was
considering the possibility of keeping the value around on the off
chance the type has come back the next time the variable is accessed.

> Alternatively, we could add code to duplicate the types recursively
> onto a convenience variable obstack.  GDB doesn't have much of a notion
> of "type compatibility".  It might not work 100% right for things like
> C++ operator overloading, but for that we'd need to do type merging
> anyway.

I have no idea what you just said, but if it avoids type fixup problems
then that would be a good thing all round. Is it worth whatever effort
it would take though? Is it instead of textual type remembering or
instead of replacing the type at all?

Andrew
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Eli Zaretskii
In reply to this post by Andrew Stubbs-2
> Date: Thu, 17 Nov 2005 11:26:07 +0000
> From: Andrew STUBBS <[hidden email]>
> Cc: [hidden email]
>
> Currently _all_ convenience variables are deleted when the symbol-file
> command is used. The file command also uses symbol-file.

I think this is a terrible misfeature that we need to fix ASAP,
regardless of what we do with variables which depend on the symbol
table.

> Please give your example of a convenience variable with no relation to
> the symbol table.

Others gave such an example:

  (gdb) set $foo = 1
Reply | Threaded
Open this post in threaded view
|

Re: [PATCH] keep-variable command

Daniel Jacobowitz-2
On Thu, Nov 17, 2005 at 09:22:02PM +0200, Eli Zaretskii wrote:

> > Date: Thu, 17 Nov 2005 11:26:07 +0000
> > From: Andrew STUBBS <[hidden email]>
> > Cc: [hidden email]
> >
> > Currently _all_ convenience variables are deleted when the symbol-file
> > command is used. The file command also uses symbol-file.
>
> I think this is a terrible misfeature that we need to fix ASAP,
> regardless of what we do with variables which depend on the symbol
> table.

Lord knows it drives me bonkers.  I didn't know exactly when it
happened (never bothered to look it up).  I seem to recall that you can
also crash GDB a number of different ways with this, which are probably
separate bugs.  This is a bit garbled of a report, I realize; I'm
always neck-deep in something else when it happens...

I have found that GDB will unreliably segfault when I set a watchpoint
using a convenience (or history; are those handled the same way?) variable
and then recompile and rerun the program, causing it to be reloaded.

--
Daniel Jacobowitz
CodeSourcery, LLC