https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78100

            Bug ID: 78100
           Summary: DWARF symbols for an array sometimes missing the array
                    length
           Product: gcc
           Version: 6.2.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: debug
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gccbugs at dima dot secretsauce.net
  Target Milestone: ---

Hi.

I'm using gcc 6.2 from Debian on an amd64 machine:

    dima@fatty:/tmp$ gcc --version

    gcc (Debian 6.2.0-9) 6.2.0 20161019
    Copyright (C) 2016 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Let's say I have the attached tiny C program: tst.c. I build and run it:

    dima@fatty:/tmp$ gcc -g -o tst tst.c

    dima@fatty:/tmp$ ./tst
    12

This is correct output: s has 3 32-bit integers in it for a total of 12 bytes.
Let me load this program in gdb, and see what gdb thinks sizeof(s) is:

    dima@fatty:/tmp$ gdb tst

    ...
    Reading symbols from tst...done.
    (gdb) p sizeof(s)
    $1 = 0

This is wrong. As stated before, the correct answer is 12, not 0. The problem
is
that the DWARF data generated by gcc is incorrect:

    dima@fatty:/tmp$ readelf -wi tst

    Contents of the .debug_info section:

    ...
     <1><62>: Abbrev Number: 4 (DW_TAG_base_type)
        <63>   DW_AT_byte_size   : 4
        <64>   DW_AT_encoding    : 5    (signed)
        <65>   DW_AT_name        : int

     <1><303>: Abbrev Number: 12 (DW_TAG_array_type)
        <304>   DW_AT_type        : <0x62>
        <308>   DW_AT_sibling     : <0x30e>
     <2><30c>: Abbrev Number: 17 (DW_TAG_subrange_type)
     <2><30d>: Abbrev Number: 0

     <1><30e>: Abbrev Number: 18 (DW_TAG_variable)
        <30f>   DW_AT_name        : s
        <311>   DW_AT_decl_file   : 1
        <312>   DW_AT_decl_line   : 3
        <313>   DW_AT_type        : <0x303>
        <317>   DW_AT_external    : 1
        <317>   DW_AT_declaration : 1

     <1><317>: Abbrev Number: 19 (DW_TAG_variable)
        <318>   DW_AT_specification: <0x30e>
        <31c>   DW_AT_decl_line   : 4
        <31d>   DW_AT_location    : 9 byte block: 3 10 10 20 0 0 0 0 0 
(DW_OP_addr: 201010)

Here the 'extern' declaration appears in DIE 0x30e with the type in DIE 0x303.
This type die is an array of an unknown number of elements, which isn't wrong.

The instantiation is in DIE 0x317. This isn't extern, so we actually have a
location for this object. But instead of declaring the full type, we simply
reference the already-seen DIE 0x30e; this DIE doesn't know how many elements
we
have, so this information doesn't appear in the DWARF data at all. Thus gdb
doesn't know we have 3 integers.

Removing the 'extern' declaration makes it work. Clang works as well.

For completeness, the code that reads this DWARF lives in array_size() in
elfutils/libdw/dwarf_aggregate_size.c. Given a DW_TAG_subrange_type it expects
either an DW_AT_count attribute or a DW_AT_upper_bound attribute, neither of
which we have here.

Thanks

Reply via email to