Bug 78320 - Excess debug info -fdebug-types-section
Summary: Excess debug info -fdebug-types-section
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: debug (show other bugs)
Version: 6.1.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-11-11 18:18 UTC by David Blaikie
Modified: 2017-08-03 15:43 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description David Blaikie 2016-11-11 18:18:02 UTC
Enabling -fdebug-types-section causes nested type declarations and definitions to be emitted by GCC, producing substantially more debug info than without this option.

Consider:

  struct a {
    struct inner { };
  } x;
  struct b {
    struct inner;
  } y;
  struct b::inner { };
  struct c {
    struct inner;
  } z;

without -fdebug-types-section the DWARF contains 3 structures (a, b, c) and no mention of nested types. With -fdebug-types-section the DWARF contains type units for all 5 types. (& 'c's definition contains a declaration of 'inner', where it did not in the baseline/no-type-units case)

At least it should be reasonable to argue that case (b) and (c) could/should be treated similarly - if 'c' is valid DWARF, containing only the declaration of inner, then the same representation should be used for 'b', since its inner type is unused.

Beyond that, I'd argue 'a' could be represented this way too, even if it's not precisely accurate to the source - it allows the DWARF to be smaller (& is already what's done in the non-type-unit case).

And beyond /that/, I'd argue to be even closer to the original DWARF, and not even emit the member type declarations: The set of members is unbounded and a debugger/DWARF consumer is going to have to check all the definitions anyway (check out how the DWARF looks for this:

  struct foo {
    template<typename T>
    void f() { }
  };
  ... foo().f<int>(); ...

- the type unit contains no mention of 'f' (which is right and proper, in my opinion) - and the declaration that references the type unit, contains a declaration of f<int>)

Ultimately, I'd argue that member function templates, implicit special members, and nested types all be treated in this way - omitted from the type unit, and included only in the nested declaration. (FWIW, I'm partly arguing from this perspective because it's how I implemented it in Clang and it seems tidy/terse/simple to reason about, etc - but I can see some counter arguments)

Including types that are otherwise unreferenced can cause a substantial increase in debug info (this bug, coupled with PR78265 may be part of the reason that, for a large program at Google, GCC's (compressed) .debug_types section in the object files is 500% larger than Clang's... - well, there's a few other bugs I know of there too, to be fair)
Comment 1 David Blaikie 2017-01-26 15:54:01 UTC
ping