OS-7700: GCC7-derived CTF can double qualifiers on arrays


Issue Type:Bug
Priority:4 - Normal
Created at:2019-04-04T09:28:50.716Z
Updated at:2019-05-03T13:28:29.623Z


Created by:Former user
Reported by:Former user
Assigned to:Former user


Fixed: A fix for this issue is checked into the tree and tested.
(Resolution Date: 2019-04-17T16:00:38.168Z)

Fix Versions

2019-04-25 Queen of Jordan (Release Date: 2019-04-25)



static const union regress {
	unsigned int i[3];
	long double e;
} regress[9];

built with GCC7 and through a DWARF->CTF->ctfdump-c pass, we get:

union regress { /* 0xc bytes */
	unsigned int i[3]; /* offset: 0 bytes */
	long double e; /* offset: 0 bytes */

extern const const union regress regress[9];

Note the "const const". This breaks the CTF tests under a GCC7 build.


Comment by Former user
Created at 2019-04-04T11:42:14.288Z

This is the generated DWARF:

 <1><10a>: Abbrev Number: 11 (DW_TAG_variable)
    <10b>   DW_AT_name        : (indirect string, offset: 0x129): regress
    <10f>   DW_AT_decl_file   : 2
    <110>   DW_AT_decl_line   : 249
    <111>   DW_AT_type        : <0x105>
    <115>   DW_AT_location    : 5 byte block: 3 0 0 0 0         (DW_OP_addr: 0)


 <1><105>: Abbrev Number: 10 (DW_TAG_const_type)
    <106>   DW_AT_type        : <0xf5>


 <1><f5>: Abbrev Number: 5 (DW_TAG_array_type)
    <f6>   DW_AT_type        : <0xe0>
    <fa>   DW_AT_sibling     : <0x105>


 <1><e0>: Abbrev Number: 10 (DW_TAG_const_type)
    <e1>   DW_AT_type        : <0xc1>


 <1><c1>: Abbrev Number: 8 (DW_TAG_union_type)
    <c2>   DW_AT_name        : (indirect string, offset: 0x129): regress
    <c6>   DW_AT_byte_size   : 12
    <c7>   DW_AT_decl_file   : 2
    <c8>   DW_AT_decl_line   : 246
    <c9>   DW_AT_sibling     : <0xe0>

Informally, this says "A variable called regress, that is a const array of const unions".

Comment by Former user
Created at 2019-04-04T13:30:07.696Z

So far, it looks like this only happens with arrays, but can happen with const or volatile.

I've been testing a change that removes the extraneous qualifier in this case. It works, but
as the CTF tests are very strict, we still fall over while descending. We also fail another test under GCC7 due to a re-ordered const volatile qualifier, which is somewhat related here. We might need to loosen how those checks work.

Comment by Former user
Created at 2019-04-11T12:38:14.166Z

To fix this specific bug, I modified the DWARF parsing code so that if we see a qualifier that would end up duplicated, we do not add it. As this changes the specific descent order between GCC4 and GCC7, we need to modify the CTF tests to accept either form (but at least one of them!).

Comment by Former user
Created at 2019-04-11T13:31:56.779Z
Updated at 2019-04-12T09:49:46.727Z

As part of this, I looked through CTF -c dumps of a full proto area gcc4 versus gcc7 with these changes.


Although it's huge enough to not be able to be fully confident, the changes spotted fall into a few buckets:

1) OS-7713 - for example, snoop's cb_procnames_long - not new in GCC7

2) types that were just missing in the GCC4 DWARF (GCC7 generation seems to be more complete). For example, FONT_FLAGS - this is the bulk

3) __builtin_va_list now showing up

4) static globals no longer considered const such as zonecfg's helptab[]. It's unclear why GCC4 marked them as const exactly, but GCC7's seem a better reflection. Applies to arrays and basic ints etc.

5) non-static global automatically-sized arrays where GCC7 decided it can't have a fixed size, such as zonecfg's prop_types[].

6) non-stable orderings for two struct definitions. For example, many objects can see two versions of struct __FILE, and ctfdump -c doesn't order them stably between two runs. This is complete noise.

7) slightly random elisions. For example GCC7 doesn't include typedef proc_graph_t, marking pgraph as the underlying struct. It's not clear why, but I confirmed this is how the DWARF looks.

8) OS-7733 (now fixed)

9) inlined functions - GCC7 won't emit a full definition if it doesn't need to. Some of smartos-live isn't compiled with options to disable inlining so this is more prevalent

Comment by Former user
Created at 2019-04-12T13:18:31.525Z

With the changes in the above gerrit in place, I ran a full proto comparison with GCC4 as well. The only CTF changes were those from libctf changes itself.

Comment by Former user
Created at 2019-04-17T00:52:38.703Z

In addition to the above comparisons, I spot-checked dtrace and MDB, and ran the CTF unit tests with both GCC 4 and GCC 7.

Comment by Jira Bot
Created at 2019-04-17T15:55:45.661Z

illumos-joyent commit adeaa2b6918d69fe48c140f0ca1779a3275f195f (branch master, by John Levon)

OS-7689 ctfdump -c goes off the rails with a missing parent
OS-7694 ctfdump -c drops last type
OS-7700 GCC7-derived CTF can double qualifiers on arrays
OS-7733 should ignore DW_TAG_subprogram with DW_AT_declaration tags
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Jason King <jason.king@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>