RE: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-22 Thread 平松雅巳 / HIRAMATU,MASAMI
>From: Wangnan (F) [mailto:wangn...@huawei.com]
>On 2016/1/22 13:56, 平松雅巳 / HIRAMATU,MASAMI wrote:
>>> From: Wangnan (F) [mailto:wangn...@huawei.com]
>>> I think this problem is not introduced by my patch. In fact
>>> there's a fundamental problem in get_arch_regstr() that it is
>>> impossible to switch sub ISA.
>> Right, but I guess this can fixed by switching %sp (for x86-64)
>> and +0(%sp) (for x86-32) instead of $stack.
>>
>
>It may not work.
>
>No matter how we change regoffset_table, when get_arch_regstr()
>get a register number 4, how can it know whether we are looking
>for x86_32 register and return $stack or return %si for x86_64?

I think we can also use elf header to get the ISA of the
target binary.

>The fundamental problem is: we need a way to map dwarf's register
>number to register names so uprobe know which register we are
>looking for, but the API we designed for this can't distinguish
>the sub ISAs dwarf are using.

As I said, we can read the elf header and get the Class or Machine
and switch the table according to it. Can't it?

Thanks,



RE: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-22 Thread 平松雅巳 / HIRAMATU,MASAMI
>From: Wangnan (F) [mailto:wangn...@huawei.com]
>On 2016/1/22 13:56, 平松雅巳 / HIRAMATU,MASAMI wrote:
>>> From: Wangnan (F) [mailto:wangn...@huawei.com]
>>> I think this problem is not introduced by my patch. In fact
>>> there's a fundamental problem in get_arch_regstr() that it is
>>> impossible to switch sub ISA.
>> Right, but I guess this can fixed by switching %sp (for x86-64)
>> and +0(%sp) (for x86-32) instead of $stack.
>>
>
>It may not work.
>
>No matter how we change regoffset_table, when get_arch_regstr()
>get a register number 4, how can it know whether we are looking
>for x86_32 register and return $stack or return %si for x86_64?

I think we can also use elf header to get the ISA of the
target binary.

>The fundamental problem is: we need a way to map dwarf's register
>number to register names so uprobe know which register we are
>looking for, but the API we designed for this can't distinguish
>the sub ISAs dwarf are using.

As I said, we can read the elf header and get the Class or Machine
and switch the table according to it. Can't it?

Thanks,



Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Wangnan (F)



On 2016/1/22 13:56, 平松雅巳 / HIRAMATU,MASAMI wrote:

From: Wangnan (F) [mailto:wangn...@huawei.com]

On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:

Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:

gcc 5 doesn't seem to care about these, but gcc 6 does and that
results in a build failure.

Ben, please CC the people on the CC list for the patch that introduces
the problem, Wang, He, can I have your Acked-by?

- Arnaldo


This patch lead me find a bug in original code.

If both perf and target ELF binary is x86_64, following command works okay:

  # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval timeout
  
  Opening /sys/kernel/debug/tracing//uprobe_events write=1
  Writing event: p:probe_libc/pselect
/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0
data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64
nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64
  

But if the library is x86_32, result is incorrect:

   # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
   
   Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
timeout=+20(%si):u32
   

We know that (%si) is used to passing arguments. Here we should see
'%sp' or '$stack'.

Use a x86_32 perf we get currect result:

  # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
  
  Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
tval=-180($stack):u64
  

Ah, I see. Uprobes may not check the target binary is in 32bit mode.
Since the stack of x86-64 and x86-32 on pt_regs are different,
(regs->sp points stack on x86-64, &(regs->pt) points stack on x86-32)
uprobes would better checking and change the behavior.

But anyway, it is also fixed by changing perf's register table.



Use a small test program to check the result:

  #include 
  #include 
  #include 
  #include 

  static struct {
 fd_set r, w, e;
 struct timespec ts;
 sigset_t m;
  } s;

  int main()
  {
 memset(, '\0', sizeof(s));

 pselect(0, , , , , );
 return 0;
  }

# gcc -m32 -g ./test_pselect.c

Use x86_32 perf:

# ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data
exceptfds readfds writefds nfds sigmask tval
Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
tval=-180($stack):u64
Added new event:
   probe_libc:pselect   (on pselect in
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
readfds writefds nfds sigmask tval)

You can now use it in all perf tools, such as:

 perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
a.out 25336 [006] 64588.457597: probe_libc:pselect:
(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780
writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0

Switch to x86_64 perf:

  # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
  
  Opening /sys/kernel/debug/tracing//uprobe_events write=1
Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
Added new event:
   probe_libc:pselect   (on pselect in
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
readfds writefds nfds sigmask tval)

You can now use it in all perf tools, such as:

 perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
a.out 25599 [002] 64759.743554: probe_libc:pselect:
(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0
sigmask=0x0 tval=0x0

Sad...

I think this problem is not introduced by my patch. In fact
there's a fundamental problem in get_arch_regstr() that it is
impossible to switch sub ISA.

Right, but I guess this can fixed by switching %sp (for x86-64)
and +0(%sp) (for x86-32) instead of $stack.
  


It may not work.

No matter how we change regoffset_table, when 

RE: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread 平松雅巳 / HIRAMATU,MASAMI
>From: Wangnan (F) [mailto:wangn...@huawei.com]
>
>On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:
>> Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:
>>> gcc 5 doesn't seem to care about these, but gcc 6 does and that
>>> results in a build failure.
>> Ben, please CC the people on the CC list for the patch that introduces
>> the problem, Wang, He, can I have your Acked-by?
>>
>> - Arnaldo
>>
>
>This patch lead me find a bug in original code.
>
>If both perf and target ELF binary is x86_64, following command works okay:
>
>  # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval timeout
>  
>  Opening /sys/kernel/debug/tracing//uprobe_events write=1
>  Writing event: p:probe_libc/pselect
>/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0
>data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64
>nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64
>  
>
>But if the library is x86_32, result is incorrect:
>
>   # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>   
>   Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
>exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
>nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
>timeout=+20(%si):u32
>   
>
>We know that (%si) is used to passing arguments. Here we should see
>'%sp' or '$stack'.
>
>Use a x86_32 perf we get currect result:
>
>  # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>  
>  Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
>data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
>writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
>tval=-180($stack):u64
>  

Ah, I see. Uprobes may not check the target binary is in 32bit mode.
Since the stack of x86-64 and x86-32 on pt_regs are different,
(regs->sp points stack on x86-64, &(regs->pt) points stack on x86-32)
uprobes would better checking and change the behavior.

But anyway, it is also fixed by changing perf's register table.

>
>
>Use a small test program to check the result:
>
>  #include 
>  #include 
>  #include 
>  #include 
>
>  static struct {
> fd_set r, w, e;
> struct timespec ts;
> sigset_t m;
>  } s;
>
>  int main()
>  {
> memset(, '\0', sizeof(s));
>
> pselect(0, , , , , );
> return 0;
>  }
>
># gcc -m32 -g ./test_pselect.c
>
>Use x86_32 perf:
>
># ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data
>exceptfds readfds writefds nfds sigmask tval
>Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
>data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
>writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
>tval=-180($stack):u64
>Added new event:
>   probe_libc:pselect   (on pselect in
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
>readfds writefds nfds sigmask tval)
>
>You can now use it in all perf tools, such as:
>
> perf record -e probe_libc:pselect -aR sleep 1
>
># ./perf record -e probe_libc:pselect ./a.out
>[ perf record: Woken up 1 times to write data ]
>[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
># ./perf script
>a.out 25336 [006] 64588.457597: probe_libc:pselect:
>(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780
>writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0
>
>Switch to x86_64 perf:
>
>  # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>  
>  Opening /sys/kernel/debug/tracing//uprobe_events write=1
>Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
>exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
>nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
>Added new event:
>   probe_libc:pselect   (on pselect in
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
>readfds writefds nfds sigmask tval)
>
>You can now use it in all perf tools, such as:
>
> perf record -e probe_libc:pselect -aR sleep 1
>
># ./perf record -e probe_libc:pselect ./a.out
>[ perf record: Woken up 1 times to write data ]
>[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
># ./perf script
>a.out 25599 [002] 64759.743554: probe_libc:pselect:
>(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0
>sigmask=0x0 tval=0x0
>
>Sad...
>
>I think this problem is not introduced by my patch. In fact
>there's a fundamental problem in get_arch_regstr() that it is
>impossible to switch sub ISA.

Right, but I guess this can fixed by switching %sp (for x86-64)
and +0(%sp) (for x86-32) 

Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Wangnan (F)



On 2016/1/21 23:41, Arnaldo Carvalho de Melo wrote:


But... I think that the unflexible original code has a bug, one that makes it
not work when using gcc6 :-\

So I think we should make it build in gcc6, using that patch (or does it
have some other problem?) so that at least doing what we can do now can
be done for those using gcc6.

Then fix these shortcomings you detected.


OK. His patch does what it claims to do. Please merge it first, then
let's look into my problem.

Thank you.




Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Arnaldo Carvalho de Melo
Em Thu, Jan 21, 2016 at 12:38:48PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Jan 21, 2016 at 12:43:04PM +0800, Wangnan (F) escreveu:
> > I think this problem is not introduced by my patch. In fact
> > there's a fundamental problem in get_arch_regstr() that it is
> > impossible to switch sub ISA.
> 
> > Not only x86_64 and x86_32, I think on arm64 we also have this
> > problem when we try to setup uprobes on arm32 code. For me the
> > later problem is more important because there are many legacy arm32
> > applications on Android platform (and I have already seen the buggy
> > unwind result in this case. It is another problem though).
> 
> Humm, and possibly to do something with arm code on a x86 workstation,
> even if just analysis, yeah, I think these functions should take as an
> argument the desired architecture instead of assuming it is the one in
> the machine issuing the commands.
>  
> > So I suggest us to solve this problem first before considering
> > gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table

But... I think that the unflexible original code has a bug, one that makes it
not work when using gcc6 :-\

So I think we should make it build in gcc6, using that patch (or does it
have some other problem?) so that at least doing what we can do now can
be done for those using gcc6.

Then fix these shortcomings you detected.

- Arnaldo

> > should both be compiled no matter which ISA we select for perf.
> > 
> > Thank you.


Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Arnaldo Carvalho de Melo
Em Thu, Jan 21, 2016 at 12:43:04PM +0800, Wangnan (F) escreveu:
> I think this problem is not introduced by my patch. In fact
> there's a fundamental problem in get_arch_regstr() that it is
> impossible to switch sub ISA.

> Not only x86_64 and x86_32, I think on arm64 we also have this
> problem when we try to setup uprobes on arm32 code. For me the
> later problem is more important because there are many legacy arm32
> applications on Android platform (and I have already seen the buggy
> unwind result in this case. It is another problem though).

Humm, and possibly to do something with arm code on a x86 workstation,
even if just analysis, yeah, I think these functions should take as an
argument the desired architecture instead of assuming it is the one in
the machine issuing the commands.
 
> So I suggest us to solve this problem first before considering
> gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table
> should both be compiled no matter which ISA we select for perf.
> 
> Thank you.


Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Arnaldo Carvalho de Melo
Em Thu, Jan 21, 2016 at 12:38:48PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Thu, Jan 21, 2016 at 12:43:04PM +0800, Wangnan (F) escreveu:
> > I think this problem is not introduced by my patch. In fact
> > there's a fundamental problem in get_arch_regstr() that it is
> > impossible to switch sub ISA.
> 
> > Not only x86_64 and x86_32, I think on arm64 we also have this
> > problem when we try to setup uprobes on arm32 code. For me the
> > later problem is more important because there are many legacy arm32
> > applications on Android platform (and I have already seen the buggy
> > unwind result in this case. It is another problem though).
> 
> Humm, and possibly to do something with arm code on a x86 workstation,
> even if just analysis, yeah, I think these functions should take as an
> argument the desired architecture instead of assuming it is the one in
> the machine issuing the commands.
>  
> > So I suggest us to solve this problem first before considering
> > gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table

But... I think that the unflexible original code has a bug, one that makes it
not work when using gcc6 :-\

So I think we should make it build in gcc6, using that patch (or does it
have some other problem?) so that at least doing what we can do now can
be done for those using gcc6.

Then fix these shortcomings you detected.

- Arnaldo

> > should both be compiled no matter which ISA we select for perf.
> > 
> > Thank you.


Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Arnaldo Carvalho de Melo
Em Thu, Jan 21, 2016 at 12:43:04PM +0800, Wangnan (F) escreveu:
> I think this problem is not introduced by my patch. In fact
> there's a fundamental problem in get_arch_regstr() that it is
> impossible to switch sub ISA.

> Not only x86_64 and x86_32, I think on arm64 we also have this
> problem when we try to setup uprobes on arm32 code. For me the
> later problem is more important because there are many legacy arm32
> applications on Android platform (and I have already seen the buggy
> unwind result in this case. It is another problem though).

Humm, and possibly to do something with arm code on a x86 workstation,
even if just analysis, yeah, I think these functions should take as an
argument the desired architecture instead of assuming it is the one in
the machine issuing the commands.
 
> So I suggest us to solve this problem first before considering
> gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table
> should both be compiled no matter which ISA we select for perf.
> 
> Thank you.


Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Wangnan (F)



On 2016/1/21 23:41, Arnaldo Carvalho de Melo wrote:


But... I think that the unflexible original code has a bug, one that makes it
not work when using gcc6 :-\

So I think we should make it build in gcc6, using that patch (or does it
have some other problem?) so that at least doing what we can do now can
be done for those using gcc6.

Then fix these shortcomings you detected.


OK. His patch does what it claims to do. Please merge it first, then
let's look into my problem.

Thank you.




RE: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread 平松雅巳 / HIRAMATU,MASAMI
>From: Wangnan (F) [mailto:wangn...@huawei.com]
>
>On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:
>> Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:
>>> gcc 5 doesn't seem to care about these, but gcc 6 does and that
>>> results in a build failure.
>> Ben, please CC the people on the CC list for the patch that introduces
>> the problem, Wang, He, can I have your Acked-by?
>>
>> - Arnaldo
>>
>
>This patch lead me find a bug in original code.
>
>If both perf and target ELF binary is x86_64, following command works okay:
>
>  # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval timeout
>  
>  Opening /sys/kernel/debug/tracing//uprobe_events write=1
>  Writing event: p:probe_libc/pselect
>/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0
>data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64
>nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64
>  
>
>But if the library is x86_32, result is incorrect:
>
>   # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>   
>   Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
>exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
>nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
>timeout=+20(%si):u32
>   
>
>We know that (%si) is used to passing arguments. Here we should see
>'%sp' or '$stack'.
>
>Use a x86_32 perf we get currect result:
>
>  # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>  
>  Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
>data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
>writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
>tval=-180($stack):u64
>  

Ah, I see. Uprobes may not check the target binary is in 32bit mode.
Since the stack of x86-64 and x86-32 on pt_regs are different,
(regs->sp points stack on x86-64, &(regs->pt) points stack on x86-32)
uprobes would better checking and change the behavior.

But anyway, it is also fixed by changing perf's register table.

>
>
>Use a small test program to check the result:
>
>  #include 
>  #include 
>  #include 
>  #include 
>
>  static struct {
> fd_set r, w, e;
> struct timespec ts;
> sigset_t m;
>  } s;
>
>  int main()
>  {
> memset(, '\0', sizeof(s));
>
> pselect(0, , , , , );
> return 0;
>  }
>
># gcc -m32 -g ./test_pselect.c
>
>Use x86_32 perf:
>
># ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data
>exceptfds readfds writefds nfds sigmask tval
>Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
>data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
>writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
>tval=-180($stack):u64
>Added new event:
>   probe_libc:pselect   (on pselect in
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
>readfds writefds nfds sigmask tval)
>
>You can now use it in all perf tools, such as:
>
> perf record -e probe_libc:pselect -aR sleep 1
>
># ./perf record -e probe_libc:pselect ./a.out
>[ perf record: Woken up 1 times to write data ]
>[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
># ./perf script
>a.out 25336 [006] 64588.457597: probe_libc:pselect:
>(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780
>writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0
>
>Switch to x86_64 perf:
>
>  # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
>data exceptfds readfds writefds nfds sigmask tval
>  
>  Opening /sys/kernel/debug/tracing//uprobe_events write=1
>Writing event: p:probe_libc/pselect
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
>exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
>nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
>Added new event:
>   probe_libc:pselect   (on pselect in
>/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
>readfds writefds nfds sigmask tval)
>
>You can now use it in all perf tools, such as:
>
> perf record -e probe_libc:pselect -aR sleep 1
>
># ./perf record -e probe_libc:pselect ./a.out
>[ perf record: Woken up 1 times to write data ]
>[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
># ./perf script
>a.out 25599 [002] 64759.743554: probe_libc:pselect:
>(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0
>sigmask=0x0 tval=0x0
>
>Sad...
>
>I think this problem is not introduced by my patch. In fact
>there's a fundamental problem in get_arch_regstr() that it is
>impossible to switch sub ISA.

Right, but I guess this can fixed by switching %sp (for x86-64)
and +0(%sp) (for x86-32) 

Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-21 Thread Wangnan (F)



On 2016/1/22 13:56, 平松雅巳 / HIRAMATU,MASAMI wrote:

From: Wangnan (F) [mailto:wangn...@huawei.com]

On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:

Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:

gcc 5 doesn't seem to care about these, but gcc 6 does and that
results in a build failure.

Ben, please CC the people on the CC list for the patch that introduces
the problem, Wang, He, can I have your Acked-by?

- Arnaldo


This patch lead me find a bug in original code.

If both perf and target ELF binary is x86_64, following command works okay:

  # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval timeout
  
  Opening /sys/kernel/debug/tracing//uprobe_events write=1
  Writing event: p:probe_libc/pselect
/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0
data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64
nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64
  

But if the library is x86_32, result is incorrect:

   # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
   
   Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
timeout=+20(%si):u32
   

We know that (%si) is used to passing arguments. Here we should see
'%sp' or '$stack'.

Use a x86_32 perf we get currect result:

  # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
  
  Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
tval=-180($stack):u64
  

Ah, I see. Uprobes may not check the target binary is in 32bit mode.
Since the stack of x86-64 and x86-32 on pt_regs are different,
(regs->sp points stack on x86-64, &(regs->pt) points stack on x86-32)
uprobes would better checking and change the behavior.

But anyway, it is also fixed by changing perf's register table.



Use a small test program to check the result:

  #include 
  #include 
  #include 
  #include 

  static struct {
 fd_set r, w, e;
 struct timespec ts;
 sigset_t m;
  } s;

  int main()
  {
 memset(, '\0', sizeof(s));

 pselect(0, , , , , );
 return 0;
  }

# gcc -m32 -g ./test_pselect.c

Use x86_32 perf:

# ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data
exceptfds readfds writefds nfds sigmask tval
Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32
tval=-180($stack):u64
Added new event:
   probe_libc:pselect   (on pselect in
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
readfds writefds nfds sigmask tval)

You can now use it in all perf tools, such as:

 perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
a.out 25336 [006] 64588.457597: probe_libc:pselect:
(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780
writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0

Switch to x86_64 perf:

  # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect
data exceptfds readfds writefds nfds sigmask tval
  
  Opening /sys/kernel/debug/tracing//uprobe_events write=1
Writing event: p:probe_libc/pselect
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64
Added new event:
   probe_libc:pselect   (on pselect in
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds
readfds writefds nfds sigmask tval)

You can now use it in all perf tools, such as:

 perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
a.out 25599 [002] 64759.743554: probe_libc:pselect:
(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0
sigmask=0x0 tval=0x0

Sad...

I think this problem is not introduced by my patch. In fact
there's a fundamental problem in get_arch_regstr() that it is
impossible to switch sub ISA.

Right, but I guess this can fixed by switching %sp (for x86-64)
and +0(%sp) (for x86-32) instead of $stack.
  


It may not work.

No matter how we change regoffset_table, when 

Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-20 Thread Wangnan (F)



On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:

Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:

gcc 5 doesn't seem to care about these, but gcc 6 does and that
results in a build failure.

Ben, please CC the people on the CC list for the patch that introduces
the problem, Wang, He, can I have your Acked-by?

- Arnaldo
  


This patch lead me find a bug in original code.

If both perf and target ELF binary is x86_64, following command works okay:

 # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval timeout

 
 Opening /sys/kernel/debug/tracing//uprobe_events write=1
 Writing event: p:probe_libc/pselect 
/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0 
data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64 
nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64

 

But if the library is x86_32, result is incorrect:

  # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

  
  Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64 
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32 
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64 
timeout=+20(%si):u32

  

We know that (%si) is used to passing arguments. Here we should see 
'%sp' or '$stack'.


Use a x86_32 perf we get currect result:

 # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

 
 Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32 
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32 
tval=-180($stack):u64

 


Use a small test program to check the result:

 #include 
 #include 
 #include 
 #include 

 static struct {
fd_set r, w, e;
struct timespec ts;
sigset_t m;
 } s;

 int main()
 {
memset(, '\0', sizeof(s));

pselect(0, , , , , );
return 0;
 }

# gcc -m32 -g ./test_pselect.c

Use x86_32 perf:

# ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data 
exceptfds readfds writefds nfds sigmask tval
Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32 
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32 
tval=-180($stack):u64

Added new event:
  probe_libc:pselect   (on pselect in 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds 
readfds writefds nfds sigmask tval)


You can now use it in all perf tools, such as:

perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
   a.out 25336 [006] 64588.457597: probe_libc:pselect: 
(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780 
writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0


Switch to x86_64 perf:

 # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

 
 Opening /sys/kernel/debug/tracing//uprobe_events write=1
Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64 
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32 
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64

Added new event:
  probe_libc:pselect   (on pselect in 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds 
readfds writefds nfds sigmask tval)


You can now use it in all perf tools, such as:

perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
   a.out 25599 [002] 64759.743554: probe_libc:pselect: 
(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0 
sigmask=0x0 tval=0x0


Sad...

I think this problem is not introduced by my patch. In fact
there's a fundamental problem in get_arch_regstr() that it is
impossible to switch sub ISA.

Not only x86_64 and x86_32, I think on arm64 we also have this
problem when we try to setup uprobes on arm32 code. For me the
later problem is more important because there are many legacy arm32
applications on Android platform (and I have already seen the buggy
unwind result in this case. It is another problem though).

So I suggest us to solve this problem first before considering
gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table
should both be compiled no matter which ISA we select for perf.

Thank you.



Re: [PATCH perf 3/4] perf tools: Fix unused variables: x86_{32,64}_regoffset_table

2016-01-20 Thread Wangnan (F)



On 2016/1/20 21:59, Arnaldo Carvalho de Melo wrote:

Em Tue, Jan 19, 2016 at 09:33:06PM +, Ben Hutchings escreveu:

gcc 5 doesn't seem to care about these, but gcc 6 does and that
results in a build failure.

Ben, please CC the people on the CC list for the patch that introduces
the problem, Wang, He, can I have your Acked-by?

- Arnaldo
  


This patch lead me find a bug in original code.

If both perf and target ELF binary is x86_64, following command works okay:

 # perf probe -v -n --exec /tmp/oxygen_root/lib64/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval timeout

 
 Opening /sys/kernel/debug/tracing//uprobe_events write=1
 Writing event: p:probe_libc/pselect 
/home/w00229757/oxygen_root-w00229757/lib64/libc-2.18.so:0xdfef0 
data=-216(%sp):u64 exceptfds=%cx:u64 readfds=%si:u64 writefds=%dx:u64 
nfds=%di:s32 sigmask=%r9:u64 tval=-232(%sp):u64 timeout=%r8:u64

 

But if the library is x86_32, result is incorrect:

  # perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

  
  Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64 
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32 
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64 
timeout=+20(%si):u32

  

We know that (%si) is used to passing arguments. Here we should see 
'%sp' or '$stack'.


Use a x86_32 perf we get currect result:

 # ~/perf probe -v -n --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

 
 Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32 
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32 
tval=-180($stack):u64

 


Use a small test program to check the result:

 #include 
 #include 
 #include 
 #include 

 static struct {
fd_set r, w, e;
struct timespec ts;
sigset_t m;
 } s;

 int main()
 {
memset(, '\0', sizeof(s));

pselect(0, , , , , );
return 0;
 }

# gcc -m32 -g ./test_pselect.c

Use x86_32 perf:

# ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect data 
exceptfds readfds writefds nfds sigmask tval
Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 
data=-172($stack):u64 exceptfds=+16($stack):u32 readfds=+8($stack):u32 
writefds=+12($stack):u32 nfds=+4($stack):s32 sigmask=+24($stack):u32 
tval=-180($stack):u64

Added new event:
  probe_libc:pselect   (on pselect in 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds 
readfds writefds nfds sigmask tval)


You can now use it in all perf tools, such as:

perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
   a.out 25336 [006] 64588.457597: probe_libc:pselect: 
(f7663330) data=0xf772e000 exceptfds=0x8049880 readfds=0x8049780 
writefds=0x8049800 nfds=0 sigmask=0x8049908 tval=0x0


Switch to x86_64 perf:

 # ./perf probe -v  --exec /tmp/oxygen_root/lib32/libc.so.6 pselect 
data exceptfds readfds writefds nfds sigmask tval

 
 Opening /sys/kernel/debug/tracing//uprobe_events write=1
Writing event: p:probe_libc/pselect 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so:0xd1330 data=-172(%si):u64 
exceptfds=+16(%si):u32 readfds=+8(%si):u32 writefds=+12(%si):u32 
nfds=+4(%si):s32 sigmask=+24(%si):u32 tval=-180(%si):u64

Added new event:
  probe_libc:pselect   (on pselect in 
/tmp/oxygen_root-w00229757/lib32/libc-2.18.so with data exceptfds 
readfds writefds nfds sigmask tval)


You can now use it in all perf tools, such as:

perf record -e probe_libc:pselect -aR sleep 1

# ./perf record -e probe_libc:pselect ./a.out
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.011 MB perf.data (1 samples) ]
# ./perf script
   a.out 25599 [002] 64759.743554: probe_libc:pselect: 
(f76e7330) data=0x0 exceptfds=0x0 readfds=0x0 writefds=0x0 nfds=0 
sigmask=0x0 tval=0x0


Sad...

I think this problem is not introduced by my patch. In fact
there's a fundamental problem in get_arch_regstr() that it is
impossible to switch sub ISA.

Not only x86_64 and x86_32, I think on arm64 we also have this
problem when we try to setup uprobes on arm32 code. For me the
later problem is more important because there are many legacy arm32
applications on Android platform (and I have already seen the buggy
unwind result in this case. It is another problem though).

So I suggest us to solve this problem first before considering
gcc 6 Werror. At least x86_32_regoffset_table and x86_64_regoffset_table
should both be compiled no matter which ISA we select for perf.

Thank you.