Re: Encoding BTF information from DWARF causes "has void type" error.

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

 



On Tue, Feb 06, 2024 at 10:42:44AM -0300, Arnaldo Carvalho de Melo wrote:
> On Tue, Feb 06, 2024 at 01:02:26PM +0100, Sebastian Andrzej Siewior wrote:
> > with linux kernel v6.8-rc2-RT and the following file as testcase
> > 
> > ----->8--------
> > 
> > #include <linux/spinlock.h>
> > #include <linux/local_lock.h>
> > 
> > struct per_cpu_struct {
> >         local_lock_t lock;
> >         unsigned int something;
> > };
> > 
> > static DEFINE_PER_CPU(struct per_cpu_struct, per_cpu_struct) = {
> >         .lock = INIT_LOCAL_LOCK(lock),
> > };
> > 
> > DEFINE_GUARD(ll_lock, local_lock_t __percpu*,
> >              local_lock(_T),
> >              local_unlock(_T))
> > 
> > void function(void);
> > void function(void)
> > {
> >         struct per_cpu_struct *pcs = this_cpu_ptr(&per_cpu_struct);
> > 
> >         guard(ll_lock)(&per_cpu_struct.lock);
> >         pcs->something++;
> > }
> > 
> > -----8<--------
> > 
> > compiling and running pahole afterwards:
> > | make kernel/pahole-tc.o && pahole -J --btf_gen_floats -j --lang_exclude=rust  kernel/pahole-tc.o
> > |   CC      kernel/pahole-tc.o
> > | error: found variable 'per_cpu_struct' in CU 'kernel/pahole-tc.c' that has void type
> > 
> > This doesn't look good. If I swap the order of "lock" and "something"
> > within per_cpu_struct then it goes away.
> > The dwarf/die object it complains about has only DW_AT_abstract_origin
> > and DW_AT_location set.

Are you sure?

What I see:

⬢[acme@toolbox pahole]$ cp sebastian-rt-void-variable-btf/pahole-tc/pahole-tc-bad.o .
⬢[acme@toolbox pahole]$ pahole --btf_encode pahole-tc-bad.o
error: found variable 'per_cpu_struct' in CU 'kernel/pahole-tc.c' that has void type
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ readelf -wi sebastian-rt-void-variable-btf/pahole-tc/pahole-tc-bad.o | grep DW_TAG_variable -A5 | grep -w per_cpu_struct -B1 -A4
 <1><764>: Abbrev Number: 29 (DW_TAG_variable)
    <765>   DW_AT_name        : (indirect string, offset: 0x184): per_cpu_struct
    <769>   DW_AT_decl_file   : 1
    <769>   DW_AT_decl_line   : 9
    <76a>   DW_AT_decl_column : 8
    <76b>   DW_AT_type        : <0x73c>
⬢[acme@toolbox pahole]$

⬢[acme@toolbox pahole]$ readelf -wi sebastian-rt-void-variable-btf/pahole-tc/pahole-tc-bad.o | grep '<73c>.*DW_TAG_structure_type' -A7
 <1><73c>: Abbrev Number: 4 (DW_TAG_structure_type)
    <73d>   DW_AT_name        : (indirect string, offset: 0x184): per_cpu_struct
    <741>   DW_AT_byte_size   : 136
    <742>   DW_AT_decl_file   : 1
    <743>   DW_AT_decl_line   : 4
    <744>   DW_AT_decl_column : 8
    <745>   DW_AT_sibling     : <0x764>
 <2><749>: Abbrev Number: 1 (DW_TAG_member)
⬢[acme@toolbox pahole]$

But when using verbose mode:

[95] FUNC function type_id=94
search cu 'kernel/pahole-tc.c' for percpu global variables.
Variable 'per_cpu_struct' from CU 'kernel/pahole-tc.c' at address 0x0 encoded
[96] VAR per_cpu_struct type=90 linkage=0
Variable 'per_cpu_struct' from CU 'kernel/pahole-tc.c' at address 0x0 encoded
[97] VAR per_cpu_struct type=91 linkage=0
error: found variable 'per_cpu_struct' in CU 'kernel/pahole-tc.c' that has void type
[98] DATASEC .data..percpu size=136 vlen=2
	type=96 offset=0 size=136
	type=97 offset=0 size=136
⬢[acme@toolbox pahole]$ pahole -V --btf_encode pahole-tc-bad.o

It ends up considering two variables with that name?

⬢[acme@toolbox pahole]$ readelf -wi sebastian-rt-void-variable-btf/pahole-tc/pahole-tc-bad.o | grep per_cpu_struct -B1 -A5
 <1><73c>: Abbrev Number: 4 (DW_TAG_structure_type)
    <73d>   DW_AT_name        : (indirect string, offset: 0x184): per_cpu_struct
    <741>   DW_AT_byte_size   : 136
    <742>   DW_AT_decl_file   : 1
    <743>   DW_AT_decl_line   : 4
    <744>   DW_AT_decl_column : 8
    <745>   DW_AT_sibling     : <0x764>
--
 <1><764>: Abbrev Number: 29 (DW_TAG_variable)
    <765>   DW_AT_name        : (indirect string, offset: 0x184): per_cpu_struct
    <769>   DW_AT_decl_file   : 1
    <769>   DW_AT_decl_line   : 9
    <76a>   DW_AT_decl_column : 8
    <76b>   DW_AT_type        : <0x73c>
    <76f>   DW_AT_location    : 9 byte block: 3 0 0 0 0 0 0 0 0 	(DW_OP_addr: 0)
⬢[acme@toolbox pahole]$

Just dumping some more info in case Jiri or Alan thinks about something.

- Arnaldo

> > At this point I am not sure if gcc wrongly created the dwarf information
> > or of pahole accidentally matches the internal local_lock_t member as
> > per_cpu_struct because it starts the same address.
> > 
> > >From dumpwarf the problematic entry is:
> > | 0x0000085b:       DW_TAG_variable
> > |                     DW_AT_abstract_origin       (0x0000099e "t")
> > |                     DW_AT_location      (DW_OP_addr 0x0, DW_OP_stack_value)
> > 
> > which looks slightly different in the good case:
> > | 0x00000852:         DW_TAG_variable
> > |                       DW_AT_abstract_origin     (0x00000980 "t")
> > |                       DW_AT_location    (0x00000040: 
> > |                          [0x0000000000000046, 0x000000000000005b): DW_OP_reg3 RBX
> > |                          [0x000000000000005b, 0x0000000000000061): DW_OP_addr 0x0, DW_OP_stack_value)
> > |                       DW_AT_GNU_locviews        (0x0000003c)
> > 
> > I made an archive with c file, the compiled version in bad and good case
> > (swapped the first two members), the dumpwarf output and uploaded to
> > 	https://breakpoint.cc/pahole-tc.tar.xz
> 
> Lots of great info, I'm on it.
> 
> - Arnaldo




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

  Powered by Linux