Re: Possible Bug With Nested Structs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Em Wed, Oct 16, 2019 at 10:11:12AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Oct 15, 2019 at 09:38:28PM -0700, Charles Machalow escreveu:
> > Hello all,
> > 
> > I've built Pahole 1.15 from source on WSL Ubuntu. Though I have is a
> > very simple example of a C struct that doesn't seem to work correctly
> > if compiled as C++ via g++, though works fine when compiled as C via
> > gcc.
> > 
> > Is Pahole intended to work with code compiled as C++ (as opposed to
> > C)? If so, take a look at the simple test.c file (can be compiled via
> 
> It should work with C++ as well, albeit the support that is there was
> mostly in response to reports from users, notably from the guys at
> CERN's ATLAS project, long ago.
> 
> > gcc or g++). Also take a look at the output from running pahole
> > against the created executable. via both g++/gcc builds It seems like
> > the nested struct is duplicated if compiled on C++. Does this seem
> > like a bug?
> 
> I'll check, thanks for the report.


Humm, this is subtle, when building with C we end up with a reordering
of how the structs are stored in the DWARF info:

[acme@quaco charles_machalow]$ grep DW_TAG_structure_type -A1 a.out.from.C.readelf
 <1><9c>: Abbrev Number: 5 (DW_TAG_structure_type)
    <9d>   DW_AT_name        : (indirect string, offset: 0xc7): _INNER
--
 <1><c3>: Abbrev Number: 7 (DW_TAG_structure_type)
    <c4>   DW_AT_byte_size   : 32
--
 <1><12b>: Abbrev Number: 5 (DW_TAG_structure_type)
    <12c>   DW_AT_name        : (indirect string, offset: 0x0): _MY_STRUCT
[acme@quaco charles_machalow]$

[acme@quaco charles_machalow]$ grep DW_TAG_structure_type -A1 a.out.from.C++.readelf
 <1><9c>: Abbrev Number: 5 (DW_TAG_structure_type)
    <9d>   DW_AT_name        : (indirect string, offset: 0x7e): _INNER
--
 <1><c3>: Abbrev Number: 5 (DW_TAG_structure_type)
    <c4>   DW_AT_name        : (indirect string, offset: 0x0): _MY_STRUCT
--
 <2><d0>: Abbrev Number: 7 (DW_TAG_structure_type)
    <d1>   DW_AT_byte_size   : 32
[acme@quaco charles_machalow]$

See that there is one DW_TAG_structure_type that doesn't have a name, as
expected, and it is inside the typedef definition, so in C++ it gets
that <2> right before the Abbrev, meaning it is defined, in C++, only
inside that typedef scope, while in C it ends up having a <1>, which
means it is "generally available".

I'll continue this later to try to figure out why pahole is printing
this thing twice for the C++ case, having that <2> versus <1> as the
clue.

BTW, I've reproduced this with:

[acme@quaco charles_machalow]$ readelf -wi a.out.from.C | grep DW_TAG_compile_unit -A4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x61): GNU C17 9.2.1 20190827 (Red Hat 9.2.1-1) -mtune=generic -march=x86-64 -g
    <10>   DW_AT_language    : 12	(ANSI C99)
    <11>   DW_AT_name        : (indirect string, offset: 0x51): test.c
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0xd8): /home/acme/git/pahole/examples/charles_machalow
[acme@quaco charles_machalow]$ readelf -wi a.out.from.C++ | grep DW_TAG_compile_unit -A4
 <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
    <c>   DW_AT_producer    : (indirect string, offset: 0x85): GNU C++14 9.2.1 20190827 (Red Hat 9.2.1-1) -mtune=generic -march=x86-64 -g
    <10>   DW_AT_language    : 4	(C++)
    <11>   DW_AT_name        : (indirect string, offset: 0x51): test.c
    <15>   DW_AT_comp_dir    : (indirect string, offset: 0xda): /home/acme/git/pahole/examples/charles_machalow
[acme@quaco charles_machalow]$

- Arnaldo
 
>  
> > In both cases, GCC is version 7.4.0.
> > 
> > test.c:
> > #include <stdint.h>
> > 
> > typedef struct _INNER {
> >     long myLong;
> > } INNER;
> > 
> > typedef struct _MY_STRUCT {
> >     struct
> >     {
> >         char a;
> >         int b;
> >         uint64_t ccc;
> >         uint8_t _8_1 : 1;
> >         uint8_t _8_4 : 4;
> >         uint8_t _8_3 : 3;
> >         INNER i;
> >     };
> > 
> > } MY_STRUCT;
> > 
> > int main()
> > {
> >     MY_STRUCT m;
> >     return 0;
> > }
> > 
> > pahole_g++:
> > csm10495@csm10495-desk:~$ g++ -g test.c && pahole a.out -q
> > struct _INNER {
> >         long int                   myLong;
> > };
> > struct _MY_STRUCT {
> >         struct {
> >                 char                       a;
> >                 int                        b;
> >                 uint64_t                   ccc;
> >                 uint8_t                    _8_1:1;
> >                 uint8_t                    _8_4:4;
> >                 uint8_t                    _8_3:3;
> >                 INNER                      i;
> >         };
> > 
> >         struct {
> >                 char               a;
> >                 int                b;
> >                 uint64_t           ccc;
> >                 uint8_t            _8_1:1;
> >                 uint8_t            _8_4:4;
> >                 uint8_t            _8_3:3;
> >                 INNER              i;
> >         };
> > };
> > 
> > pahole_gcc:
> > csm10495@csm10495-desk:~$ gcc -g test.c && pahole a.out -q
> > struct _INNER {
> >         long int                   myLong;
> > };
> > struct _MY_STRUCT {
> >         struct {
> >                 char               a;
> >                 int                b;
> >                 uint64_t           ccc;
> >                 uint8_t            _8_1:1;
> >                 uint8_t            _8_4:4;
> >                 uint8_t            _8_3:3;
> >                 INNER              i;
> >         };
> > };
> > 
> > 
> > Thanks all.
> > 
> > - Charlie Scott Machalow
> 
> -- 
> 
> - Arnaldo

-- 

- Arnaldo



[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux