This is the mail archive of the gdb@sources.redhat.com 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]

Re: Changing the "enclosing_type" of a value structure


Also sprach Andrew Cagney:

> Jim Ingham wrote:
> 
>> /* If we have the full object, but for some reason the enclosing
>> type is wrong, set it *//* pai: FIXME -- sounds iffy */
> 
> I like the comment...

Yeah, this is the sort of thing that really warms your heart after you have
spent a couple of days chasing down memory corruption...

> 
>> return (value_ptr) xrealloc (val, sizeof (struct type)
>> + TYPE_LENGTH (new_type));
> 
> Should it simply refuse to expand a type?  That extra data becomes
> undefined in general?
> 


The sketch I sent in the last note was not right.  You have to change the
lazy flag - which will take care of your objection (though in all the code
paths I could see the data had not been read when this switch was done) -
and you have to stick the new value back into the value chain, or the old
value will get freed, which is BAD.  Here is another - better - version.
This one seems to work pretty well.

value_ptr
value_change_enclosing_type (value_ptr val, struct type *new_encl_type)
{

  /* If you follow the code, most of the time that this function
     is called, the types are the same...  So shortcut this case. */

  if (new_encl_type == VALUE_ENCLOSING_TYPE (val))
    {
      return val;
    }
  else if (TYPE_LENGTH (new_encl_type)
           > TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val)))
    {
       value_ptr old_val = val;
       register value_ptr prev;

       val = (value_ptr) xrealloc (old_val, sizeof (struct value)
                                       + TYPE_LENGTH (new_encl_type));

       /* We have to make sure this ends up in the same place in the value
         chain as the original copy, so it's clean-up behavior is the same.
          If the value has been released, this is a waste of time, but there
          is no way to tell that in advance, so... */

       if (old_val != all_values)
         {
           for (prev = all_values; prev != NULL; prev = prev->next)
             {
               if (prev->next == old_val)
                 {
                   prev->next = val;
                   break;
                 }
             }
         }
    }

  VALUE_ENCLOSING_TYPE (val) = new_encl_type;

  /* If we had to change the enclosing type, the data in the value
     is no longer good.  Setting lazy back to 1 will force it to be
     reread. */

  VALUE_LAZY (val) = 1;

  return val;
}


Jim
-- 
Jim Ingham                                 jingham@apple.com
Apple Computer


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