GDB SEGV while trying to print uninitialize variant record
authorJoel Brobecker <brobecker@gnat.com>
Tue, 23 Nov 2010 01:07:22 +0000 (01:07 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 23 Nov 2010 01:07:22 +0000 (01:07 +0000)
commit27f2a97baff4c840ed98027b7eab67d905fe93c8
tree937b7d68c6d702776eae25e4514a0133920ef607
parent1324a0d9b562a38f4ce23c8835e1dacbbe3b51b9
GDB SEGV while trying to print uninitialize variant record

We have a variant record whose value is defined as follow:

   type Discriminant_Record (Num1, Num2,
                             Num3, Num4 : Natural) is record
      Field1 : My_Record_Array (1 .. Num2);
      Field2 : My_Record_Array (Num1 .. 10);
      Field3 : My_Record_Array (Num1 .. Num2);
      Field4 : My_Record_Array (Num3 .. Num2);
      Field5 : My_Record_Array (Num4 .. Num2);
   end record;
   Dire : Discriminant_Record (1, 7, 3, 0);

However, we're trying to print "Dire" before it is elaborated.
This is common if one breaks on a function and then starts doing
"info locals" for instance.

What happens is that GDB reads bogus values for fields Num1 to
Num4, and deduces a bogus (ginormouos) size for component
"Field1".  The length is so large that it then later causes
an overflow in the overall record length computation. Things
go downhill from there, because length(field1) > length(record).
So, when after we've fetched the value of the record based on
the computed size, we crash trying to access unallocated memory
when accessing field1...

The first fix we can do is to check the size of the field
against the maximum object size.  If it exceeds that size,
then we know the record will also exceed that size...

gdb/ChangeLog:

        * ada-lang.c (ada_template_to_fixed_record_type_1):
        For dynamic fields, check the field size against the maximum
        object size.
gdb/ChangeLog
gdb/ada-lang.c