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

--- Comment #4 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Vineet Gupta <[email protected]>:

https://gcc.gnu.org/g:3e2885588fe0e5273a50c471d41c61ee9aefc269

commit r17-1810-g3e2885588fe0e5273a50c471d41c61ee9aefc269
Author: Vineet Gupta <[email protected]>
Date:   Wed Jun 24 09:19:46 2026 -0700

    dwarf: fix inconsistency in type chains traversal [PR125421]

    typedef chain traversal could sometimes skip an intermediate type.
    This could happen when two DIEs have a common underlying type but diverge
    due to presence of additional attribute in one case and a qualifier in
    other.
    In the example from testcase, variable "perm" typechain misses interim u16.

                 typedef unsigned short __u16;
                          typedef __u16 u16;
      __attribute__((btf_type_tag(""))) u16 a;
                                  const u16 perm;

    generates

      .uleb128 0x1  # (DIE (0x66) DW_TAG_variable)
      .long .LASF3  # DW_AT_name: "perm"
                    # DW_AT_decl_file (1, pr125421.c)
      .byte 0xa     # DW_AT_decl_line
      .byte 0xb     # DW_AT_decl_column
      .long 0x2f    # DW_AT_type

      .uleb128 0x4  # (DIE (0x2f) DW_TAG_const_type)
      .long 0x23    # DW_AT_type                        <-- BUG

      .uleb128 0x3  # (DIE (0x23) DW_TAG_typedef)
      .long .LASF5  # DW_AT_name: "__u16"
      .byte 0x1     # DW_AT_decl_file (pr125421.c)
      .byte 0x7     # DW_AT_decl_line
      .byte 0xf     # DW_AT_decl_column
      .long 0x34    # DW_AT_type

      .uleb128 0x5  # (DIE (0x34) DW_TAG_base_type)
      .byte 0x2     # DW_AT_byte_size
      .byte 0x5     # DW_AT_encoding
      .long .LASF6  # DW_AT_name: "short int"

    What makes this issue worse is depending on the order in which the types
    are specified in source, and processed, the problem may or maynot show up.
    So in the test code above if lines 3 and 4 are swppaed, "perm" gets the
    missing type u16 as expected.

    The issue is in modified_type_die (), get_qualified_type (type) returned
    pointer may not be identical to dtype: TREE_TYPE (TYPE_NAME
(qualified_type))
    while having the same underlying base type. And due to the failed
    pointer identity test, subsequent usage of DECL_ORIGINAL_TYPE () for
recursive
    chain processing can peel away the needed type.

    The implications are for a multi CU build, structurally similar but
    non identical variants of types (due to an embedded member getting a
    different chained typdef) can be generated and accumulate at link time
    in the final .debug_info.

    This would be OK / unnoticed for usual dwarf debugging purposes.
    However in BFP workflow: kernel binary linking invokes pahole to process
    the dwarf and dedup it for btf generation (gcc can emit btf directly but
    thats not been done currently for other reasons). The slightly different
    variations of same structure due to thi issue cause combinatiorial
explosion
    in pahole dedup processing trying to match and failing repeatedly in what
    seems like infinite recursion. The problem showed up and was excerbated
    when trying to enable attr btf_type_tag in kernel with gcc for the first
    time as that is the key ingredient to trigger the latent issue.

    Fix is to handle qualified_type != dtype as if they were identical when
    they are different variant nodes of the same underlying typedef.

    Bootstrapped and regtested on x86 and aarch64.

            PR debug/125421

    gcc/ChangeLog:

            * dwarf2out.cc (modified_type_die): Handle qualified_type being
            a variant of dtype as if they were identical to avoid peeling a
            typdef.
            For named types, use dentry unconditionally as that is valid for
            both cases of qualified_type == and  != dentry.

    gcc/testsuite/ChangeLog:

            * gcc.dg/debug/dwarf2/pr125421.c: New Test.

    Signed-off-by: Vineet Gupta <[email protected]>

Reply via email to