[PATCH 13/18] testsuite, fortran: fix info-types for intel compilers

Andrew Burgess aburgess@redhat.com
Mon May 30 10:33:34 GMT 2022


"Kempke, Nils-Christian" <nils-christian.kempke@intel.com> writes:

>> -----Original Message-----
>> From: Gdb-patches <gdb-patches-bounces+nils-
>> christian.kempke=intel.com@sourceware.org> On Behalf Of Kempke, Nils-
>> Christian via Gdb-patches
>> Sent: Wednesday, May 11, 2022 5:20 PM
>> To: Andrew Burgess <aburgess@redhat.com>; gdb-
>> patches@sourceware.org
>> Subject: RE: [PATCH 13/18] testsuite, fortran: fix info-types for intel
>> compilers
>> 
>> > -----Original Message-----
>> > From: Andrew Burgess <aburgess@redhat.com>
>> > Sent: Wednesday, May 11, 2022 2:06 PM
>> > To: Kempke, Nils-Christian <nils-christian.kempke@intel.com>; gdb-
>> > patches@sourceware.org
>> > Cc: JiniSusan.George@amd.com; Kempke, Nils-Christian <nils-
>> > christian.kempke@intel.com>
>> > Subject: Re: [PATCH 13/18] testsuite, fortran: fix info-types for intel
>> > compilers
>> >
>> > Nils-Christian Kempke <nils-christian.kempke@intel.com> writes:
>> >
>> > > First, the emitted symbol character*1 which is checked in the test
>> > > is not even referenced as a type in the compiled examples.  It seems
>> > > to be a gfortran specific check for some type that gets emitted always.
>> > > I changed the test to use check_optional_entry here to allow the
>> > > symbol's absence.
>> > >
>> > > Second, the line checked for s1 was hardcoded in the test.  Given that
>> > > the type is actually defined on line 41 (which is what is emitted by
>> > > ifx) it even seems wrong.  I changed the line check for s1 to actually
>> > > check for 41 and a gfortran bug has been filed here
>> > >
>> > >    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105454
>> > >
>> > > The test is now marked as xfail for gfortran.
>> > >
>> > > Third, the test was checking for s1 to be emitted by info types.  This
>> > > would mean that the type is put into compilation unit scope in the
>> DWARF
>> > > but, as it is local to the main program this is actually not expected
>> > > and gfortran specific.
>> > > Since I already added the xfail for gfortran here, I opted to also make
>> > > this check gfortran specific.
>> > > ---
>> > >  gdb/testsuite/gdb.fortran/info-types.exp | 10 +++++++---
>> > >  1 file changed, 7 insertions(+), 3 deletions(-)
>> > >
>> > > diff --git a/gdb/testsuite/gdb.fortran/info-types.exp
>> > b/gdb/testsuite/gdb.fortran/info-types.exp
>> > > index 67fe4d79c5..06770aada1 100644
>> > > --- a/gdb/testsuite/gdb.fortran/info-types.exp
>> > > +++ b/gdb/testsuite/gdb.fortran/info-types.exp
>> > > @@ -41,12 +41,16 @@ set real4 [fortran_real4]
>> > >  GDBInfoSymbols::run_command "info types"
>> > >  GDBInfoSymbols::check_header "All defined types:"
>> > >
>> > > -GDBInfoSymbols::check_entry "${srcfile}" "" "${character1}"
>> > > +GDBInfoSymbols::check_optional_entry "${srcfile}" "" "${character1}"
>> >
>> > Could we not just add a reference to character*1 type?  I'm happy to
>> > take this change, but just adding a use might make a stronger test?
>> 
>> Yes, I'll do that. It is true, there will be a bit more coverage.
>> 
>> > >  GDBInfoSymbols::check_entry "${srcfile}" "" "${integer4}"
>> > >  GDBInfoSymbols::check_entry "${srcfile}" "" "${logical4}"
>> > >  GDBInfoSymbols::check_entry "${srcfile}" "$decimal" "Type m1t1;"
>> > >  GDBInfoSymbols::check_entry "${srcfile}" "" "${real4}"
>> > > -GDBInfoSymbols::check_entry "${srcfile}" "37" "Type s1;"
>> > > +
>> > > +if { [test_compiler_info {gfortran-*} f90] } {
>> > > +    setup_xfail *-*-* gcc/105454
>> > > +    GDBInfoSymbols::check_entry "${srcfile}" "41" "Type s1;"
>> > > +}
>> >
>> > Shouldn't the GDBInfoSymbols::check_entry call be outside of the if
>> > block?  I think, with your change, the test will _only_ be run on
>> > gfortran, which is not what you wanted.
>> 
>> Mh - so actually this is what I wanted.  In my opinion emitting s1 here
>> is actually not expected.  The type s1 is defined inside the Fortran program.
>> E.g. ifx also emits it as a child of the program - limiting its scope to that.
>> 
>> Gfortran on the other hand emits it at global CU scope (so not as a child of
>> the program info_types_test).  I think the fact that this type is visible via info
>> types is not correct here.  But, since this emission is also buggy I did not want
>> to delete the test in order to somehow keep track of this line bug.
>> 
>> So I changed the test to only test for this type when ran with gfortran.
>> 
>> My baseline assumption here is, that gdb in the test only prints types in the
>> 'info types' command that are defined at CU DWARF scope.  At least it looks
>> like this when compiling with ifx (which, as said, emits the Type s1 as a child
>> of the program info_types_test).
>> 
>> When checking this compiled with ifx I see in the DWARF
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> <1><1d5>: Abbrev Number: 12 (DW_TAG_subprogram)
>>     <1d6>   DW_AT_low_pc      : 0x4055b0
>>     <1de>   DW_AT_high_pc     : 0x42
>>     <1e2>   DW_AT_frame_base  : 1 byte block: 56        (DW_OP_reg6 (rbp))
>>     <1e4>   DW_AT_linkage_name: (indirect string, offset: 0x224): MAIN__
>>     <1e8>   DW_AT_name        : (indirect string, offset: 0x22b): info_types_test
>>     <1ec>   DW_AT_decl_file   : 1
>>     <1ed>   DW_AT_decl_line   : 37
>>     <1ee>   DW_AT_external    : 1
>>     <1ee>   DW_AT_main_subprogram: 1
>> ...
>> <2><239>: Abbrev Number: 14 (DW_TAG_structure_type)
>>     <23a>   DW_AT_name        : (indirect string, offset: 0x1d4): s1
>>     <23e>   DW_AT_byte_size   : 4
>>     <23f>   DW_AT_decl_file   : 1
>>     <240>   DW_AT_decl_line   : 41
>>  <3><241>: Abbrev Number: 15 (DW_TAG_member)
>>     <242>   DW_AT_name        : (indirect string, offset: 0x207): a
>>     <246>   DW_AT_type        : <0x1ce>
>>     <24a>   DW_AT_decl_file   : 1
>>     <24b>   DW_AT_decl_line   : 41
>>     <24c>   DW_AT_data_member_location: 0
>>     <24d>   DW_AT_accessibility: 1      (public)
>>  <3><24e>: Abbrev Number: 0
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> So s1 is being emitted but as a child of MAIN__. With gfortran on the other
>> hand I get
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> <1><2ec>: Abbrev Number: 18 (DW_TAG_structure_type)
>>     <2ed>   DW_AT_name        : s1
>>     <2f0>   DW_AT_byte_size   : 4
>>     <2f1>   DW_AT_decl_file   : 1
>>     <2f2>   DW_AT_decl_line   : 37
>>     <2f3>   DW_AT_sibling     : <0x302>
>>  <2><2f7>: Abbrev Number: 4 (DW_TAG_member)
>>     <2f8>   DW_AT_name        : a
>>     <2fa>   DW_AT_decl_file   : 1
>>     <2fb>   DW_AT_decl_line   : 42
>>     <2fc>   DW_AT_type        : <0x2bf>
>>     <300>   DW_AT_data_member_location: 0
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> emitted as a child of the whole compile unit.
>> 
>> It might be, that this is actually not the expected behavior of GDB here.
>> But it seems, that types defined as children of subroutines will not be
>> displayed by 'info types'.
>> 
>> Similarly, I looked at this in c++ and we have the same here: Compiling
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> int main (int argc, char *argv[])
>> {
>>   struct test {};
>> 
>>   test a;
>>   return 0;
>> }
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> With gcc -O0 -g (version 9.4.0) will emit DWARF like:
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> <1><2d>: Abbrev Number: 2 (DW_TAG_subprogram)
>>     <2e>   DW_AT_external    : 1
>>     <2e>   DW_AT_name        : (indirect string, offset: 0xb4): main
>>     <32>   DW_AT_decl_file   : 1
>>     <33>   DW_AT_decl_line   : 1
>>     <34>   DW_AT_decl_column : 5
>>     <35>   DW_AT_type        : <0xf7>
>>     <39>   DW_AT_low_pc      : 0x1129
>>     <41>   DW_AT_high_pc     : 0x16
>>     <49>   DW_AT_frame_base  : 1 byte block: 9c         (DW_OP_call_frame_cfa)
>>     <4b>   DW_AT_GNU_all_call_sites: 1
>>     <4b>   DW_AT_sibling     : <0xf7>
>>  <2><4f>: Abbrev Number: 3 (DW_TAG_formal_parameter)
>> ...
>> <2><6d>: Abbrev Number: 4 (DW_TAG_structure_type)
>>     <6e>   DW_AT_name        : (indirect string, offset: 0xf): test
>>     <72>   DW_AT_byte_size   : 1
>>     <73>   DW_AT_decl_file   : 1
>>     <74>   DW_AT_decl_line   : 3
>>     <75>   DW_AT_decl_column : 10
>>     <76>   DW_AT_sibling     : <0xe9>
>>  <3><7a>: Abbrev Number: 5 (DW_TAG_subprogram)
>> ...
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 
>> So the type of test is not emitted at CU level, but as a child of main.
>> Doing
>> 
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> (gdb) info types
>> All defined types:
>> 
>> File ./c.cpp:
>>         char
>>         int
>> (gdb) start
>> ...
>> 6         return 0;
>> (gdb) info types test
>> All types matching regular expression "test":
>> (gdb)
>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> will also not emit the type.
>> 
>> So either this is wrong in GDB - or the emission of the type at global level
>> is not quite correct here and should not even be tested.
>> 
>> I see that my commit message does not quite cover all this though.
>> But what do you think?
>> 
>> Thanks,
>> Nils
>> 
>
> I dug into this a bit more .. It seems indeed that the symbols are only
> searched at a global level.  In symtab.c:add_matching_symbols which is
> called as a result of e.g. 'info types' we only search the symbols put into
> either the block GLOBAL_BLOCK, or STATIC_BLOCK.
>
> According to block.h 
>
>    The GLOBAL_BLOCK contains all the symbols defined in this compilation
>    whose scope is the entire program linked together.
>    The STATIC_BLOCK contains all the symbols whose scope is the
>    entire compilation excluding other separate compilations.
>
> so indeed, I would not expect these local symbols to appear when typing
> 'info symbols'/'info types' in GDB.
>
> So, I think the emission of s1 in 'info types' when compiled with gfortran
> Is wrong (and likely this should also become a GCC/gfortran bug). It does not
> happen with ifx or flang.
>
> About the second comment on this patch:
>
>> > > -GDBInfoSymbols::check_entry "${srcfile}" "" "${character1}"
>> > > +GDBInfoSymbols::check_optional_entry "${srcfile}" "" "${character1}"
>> >
>> > Could we not just add a reference to character*1 type?  I'm happy to
>> > take this change, but just adding a use might make a stronger test?
>> 
>> Yes, I'll do that. It is true, there will be a bit more coverage.
>
> It is actually difficult to do this.  I added this line to the test (in this case to
> the program info_types_test):
>
>   character(kind=1) :: d = 'c'
>
> Adding a character to the executable and compiling it with ifx or gfortran
> will not trigger the emission of an additional type though.  In fact, neither,
> gfortran, nor ifx emit the type of variable d as ${character1}, e.g. character*1:
>
> gfortran this type is described as
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> <2><32e>: Abbrev Number: 21 (DW_TAG_variable)
>     <32f>   DW_AT_name        : d
>     <331>   DW_AT_decl_file   : 1
>     <332>   DW_AT_decl_line   : 45
>     <333>   DW_AT_type        : <0x365>
> ...
> <1><365>: Abbrev Number: 25 (DW_TAG_string_type)
>     <366>   DW_AT_byte_size   : 1
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> and IFX
> will describe the character type not with a 
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> <2><24f>: Abbrev Number: 13 (DW_TAG_variable)
>     <250>   DW_AT_name        : (indirect string, offset: 0x1f7): d
>     <254>   DW_AT_type        : <0x286>
>     <258>   DW_AT_decl_file   : 1
>     <259>   DW_AT_decl_line   : 45
>     <25a>   DW_AT_location    : 9 byte block: 3 a0 f3 48 0 0 0 0 0      (DW_OP_addr: 48f3a0)
>     <264>   DW_AT_linkage_name: (indirect string, offset: 0x205): info_types_test_$D
> ...
> <1><286>: Abbrev Number: 18 (DW_TAG_string_type)
>     <287>   DW_AT_name        : (indirect string, offset: 0x1f9): CHARACTER_0
>     <28b>   DW_AT_byte_size   : 1
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> I also tried lines like
>
>   character*1 :: d = 'c'
>
> and
>
>   character :: d = 'c'
>
> but all three were emitted as the same string_type in DWARF.
> So, to conclude, I do not even know whether it is possible to
> actually get gfortran to emit a type called character*1 naturally..
>
> The only place within the Fortran testsuite where a check for
> the compiler dependent type fortran_character1 exists is info-types.
> The problem with the emission as DW_TAG_string_type is that this will not
> make GDB generate a symbol for the type - in read.c it says
>
>     /* These dies have a type, but processing them does not create
>        a symbol or recurse to process the children.  Therefore we can
>        read them on-demand through read_type_die.  */
>
> So for this part, I think the type should not be emitted at all.  I do also not think
> that it is wrong DWARF to emit the character*1 as a string_type of length 1.
> Btw. when printing the type in gdb this is hidden as Fortran string types
> are printed as character*DW_AT_byte_size, so for ifx or gfortran we get
>
>    (gdb) ptype d
>    type = character*1
>
> I lastly checked this with flang and here, finally, we get a character base type
> emitted as
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> <2><29b>: Abbrev Number: 16 (DW_TAG_variable)
>     <29c>   DW_AT_name        : (indirect string, offset: 0x1b9): d
>     <2a0>   DW_AT_type        : <0x372>
> ...
> <1><372>: Abbrev Number: 10 (DW_TAG_base_type)
>     <373>   DW_AT_name        : (indirect string, offset: 0x1ad): character
>     <377>   DW_AT_encoding    : 5       (signed)
>     <378>   DW_AT_byte_size   : 1
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> which, rightfully, made GDB emit a type called 'character' in the 'info types'.
>
> I think we should keep the check for the character type optional, even when
> adding a line that actually uses it to the test (as only flang DWARF emits it).
> The other alternative is to remove this check completely which I also think is ok.
>
> There should be a gfortran bug filed about the emission of this
> character*1, too though.

Thanks for all the work you've done looking into this.  Given what
you've said, then I'm happy with your original change.

Thanks,
Andrew



More information about the Gdb-patches mailing list