This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[RFA/dwarf-2] Avoid unnecessary subrange_type (3/3)


This the last of three patches. This is the patch that actually changes
GCC's dwarf2 output.

Here is a description of the problem. In GDB (modified to add support
for Ada debugging), we are trying to ask the debugger for the highest
value for type long_long_integer:

        (gdb) p Long_Long_Integer'Last
        $1 = -1

On x86-linux, long_long_integer is 64 bits. So the expected output
is: 9223372036854775807, not -1. This happens when dwarf2 is used.

The problem comes from the debug information generated by GCC
for type long_long_integer. It is defined as follow:

        .byte   0xf     # uleb128 0xf; (DIE (0x21a) DW_TAG_subrange_type)
        .long   .LC8    # DW_AT_name: "long_long_integer"
        .long   0x252   # DW_AT_type

And then, type 0x252 is:

        .byte   0x4     # uleb128 0x4; (DIE (0x252) DW_TAG_base_type)
        .long   .LC8    # DW_AT_name: "long_long_integer"
        .byte   0x8     # DW_AT_byte_size
        .byte   0x5     # DW_AT_encoding

As you see, we end up with 2 "long_long_integer" types, One of them
is the base type, and the other one is the subrange_type. When looking
up the long_long_integer type, GDB ends up finding the subrange_type
(but this is only pure "luck" as it stops the search after having found
on that matches the type name).

So when searching the max value, GDB looks for the upper bound.
Unfortunately, the subrange_type DIE does not include either bound.
According to the dwarf3 specs I have, this means that the lower bound
is "a language-dependent constant - the C/C++ default is 0. [...].
If the upper bound and count are missing, then the upper bound value
is unknown".

As a consequence, GDB interprets the above subrange_type DIE as a
range type which bounds are 0 and -1. And thus GDB ends up printing
the value of "Long_Long_Integer'Last" as -1.

I looked into the dwarf2out.c code, and found that the problem is
caused by the fact that the max value of long_long_integer is actually
too big to fit into an int (of the host), or said in gcc code parlance,
host_integer_p() applied to the long_long_integer bounds return zero.
So when we try to add the upper and lower bounds to the subrange type

          if (TYPE_MIN_VALUE (type) != NULL)
            add_bound_info (subrange_die, DW_AT_lower_bound,
                            TYPE_MIN_VALUE (type));

The add_bound_info operation gets aborted because GCC doesn't know
how to generate large integer values. Fixing this problem might need
a fair bit of work, I'm not sure :-/.

However, while I was looking at this type definition, I just realized
that it is wrong to generate a subrange type DIE for long_long_integer.
Same with type "integer" or "long_integer" actually. Here, we end up
with two type DIEs with the same name, same TREE_CODE, same size, same
min and max value, etc...  When we are using stabs, range types are
the method recommended by the document provided by GDB describing stabs,
but dwarf-2 provides a way to declare base types: DW_TAG_base_type! :-)

The attached patch avoids the generation of the subrange_type DIE in
such case. The nice side-effect of this change is that it avoids
the issue that we encountered at first, at least in the usual cases.
And hey, it even reduces the amount of dwarf-2 data! :-)

At some point, I thought that the check I am adding should go into
is_subrange_type(). This would also make sense, except that it would
make us recompute in is_subrange_type() a couple of values for both the
type and subtype which are already computed in subrange_type_die().
But maybe I'm wrong to be so cheap, and that is_subrange_type() is the
right place for that extra check? Let me know.

2004-03-15  J. Brobecker  <brobecker@gnat.com>

        * dwarf2out.c (subrange_type_die): Do not generate unnecessary
        subrange types.

Tested on x86-linux by bootstrapping, and using the GCC & GDB testsuites.
OK to apply?

Thanks,
-- 
Joel

Attachment: dw2-no_subtype.diff
Description: Text document


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