2015-04-25 08:14:52

by He Kuang

[permalink] [raw]
Subject: [PATCH] perf probe: Fix bug in perf probe with global variables

There are missing curly braces which causes find_variable() return wrong
value when probing with global variables.

This problem can be reproduced as following:

$ perf probe -v --add='generic_perform_write global_variable_for_test'
...
Try to find probe point from debuginfo.
Probe point found: generic_perform_write+0
Searching 'global_variable_for_test' variable in context.
An error occurred in debuginfo analysis (-2).
Error: Failed to add events. Reason: No such file or directory (Code: -2)

After this patch:

$ perf probe -v --add='generic_perform_write global_variable_for_test'
...
Converting variable global_variable_for_test into trace event.
global_variable_for_test type is int.
Found 1 probe_trace_events.
Opening /sys/kernel/debug/tracing/kprobe_events write=1
Added new event:
Writing event: p:probe/generic_perform_write _stext+1237464
global_variable_for_test=@global_variable_for_test+0:s32
probe:generic_perform_write (on generic_perform_write with
global_variable_for_test)

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

perf record -e probe:generic_perform_write -aR sleep 1

Signed-off-by: He Kuang <[email protected]>
---
tools/perf/util/probe-finder.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 44554c3..1c3cc07 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
/* Search child die for local variables and parameters. */
if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
/* Search again in global variables */
- if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
+ if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
+ 0, &vr_die)) {
pr_warning("Failed to find '%s' in this function.\n",
pf->pvar->var);
ret = -ENOENT;
+ }
}
if (ret >= 0)
ret = convert_variable(&vr_die, pf);
--
1.8.5.2


Subject: Re: [PATCH] perf probe: Fix bug in perf probe with global variables

(2015/04/25 17:08), He Kuang wrote:
> There are missing curly braces which causes find_variable() return wrong
> value when probing with global variables.
>
> This problem can be reproduced as following:
>
> $ perf probe -v --add='generic_perform_write global_variable_for_test'
> ...
> Try to find probe point from debuginfo.
> Probe point found: generic_perform_write+0
> Searching 'global_variable_for_test' variable in context.
> An error occurred in debuginfo analysis (-2).
> Error: Failed to add events. Reason: No such file or directory (Code: -2)
>
> After this patch:
>
> $ perf probe -v --add='generic_perform_write global_variable_for_test'
> ...
> Converting variable global_variable_for_test into trace event.
> global_variable_for_test type is int.
> Found 1 probe_trace_events.
> Opening /sys/kernel/debug/tracing/kprobe_events write=1
> Added new event:
> Writing event: p:probe/generic_perform_write _stext+1237464
> global_variable_for_test=@global_variable_for_test+0:s32
> probe:generic_perform_write (on generic_perform_write with
> global_variable_for_test)
>
> You can now use it in all perf tools, such as:
>
> perf record -e probe:generic_perform_write -aR sleep 1

Oops, that's my fault! :(

Acked-by: Masami Hiramatsu <[email protected]>

Thank you!!

>
> Signed-off-by: He Kuang <[email protected]>
> ---
> tools/perf/util/probe-finder.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> index 44554c3..1c3cc07 100644
> --- a/tools/perf/util/probe-finder.c
> +++ b/tools/perf/util/probe-finder.c
> @@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
> /* Search child die for local variables and parameters. */
> if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
> /* Search again in global variables */
> - if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
> + if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
> + 0, &vr_die)) {
> pr_warning("Failed to find '%s' in this function.\n",
> pf->pvar->var);
> ret = -ENOENT;
> + }
> }
> if (ret >= 0)
> ret = convert_variable(&vr_die, pf);
>


--
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: [email protected]

2015-04-27 16:38:58

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf probe: Fix bug in perf probe with global variables

Em Sun, Apr 26, 2015 at 09:56:06AM +0900, Masami Hiramatsu escreveu:
> (2015/04/25 17:08), He Kuang wrote:
> > There are missing curly braces which causes find_variable() return wrong
> > value when probing with global variables.
> >
> > This problem can be reproduced as following:
> >
> > $ perf probe -v --add='generic_perform_write global_variable_for_test'
> > ...
> > Try to find probe point from debuginfo.
> > Probe point found: generic_perform_write+0
> > Searching 'global_variable_for_test' variable in context.
> > An error occurred in debuginfo analysis (-2).
> > Error: Failed to add events. Reason: No such file or directory (Code: -2)
> >
> > After this patch:
> >
> > $ perf probe -v --add='generic_perform_write global_variable_for_test'
> > ...
> > Converting variable global_variable_for_test into trace event.
> > global_variable_for_test type is int.
> > Found 1 probe_trace_events.
> > Opening /sys/kernel/debug/tracing/kprobe_events write=1
> > Added new event:
> > Writing event: p:probe/generic_perform_write _stext+1237464
> > global_variable_for_test=@global_variable_for_test+0:s32
> > probe:generic_perform_write (on generic_perform_write with
> > global_variable_for_test)
> >
> > You can now use it in all perf tools, such as:
> >
> > perf record -e probe:generic_perform_write -aR sleep 1
>
> Oops, that's my fault! :(
>
> Acked-by: Masami Hiramatsu <[email protected]>
>
> Thank you!!

Thanks, applied to perf/urgent.

- Arnaldo

Subject: [tip:perf/urgent] perf probe: Fix bug with global variables handling

Commit-ID: d13855ef18e1852b2c4dc86ddf5759c5b34628cb
Gitweb: http://git.kernel.org/tip/d13855ef18e1852b2c4dc86ddf5759c5b34628cb
Author: He Kuang <[email protected]>
AuthorDate: Sat, 25 Apr 2015 16:08:58 +0800
Committer: Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 27 Apr 2015 13:57:29 -0300

perf probe: Fix bug with global variables handling

There are missing curly braces which causes find_variable() return wrong
value when probing with global variables.

This problem can be reproduced as following:

$ perf probe -v --add='generic_perform_write global_variable_for_test'
...
Try to find probe point from debuginfo.
Probe point found: generic_perform_write+0
Searching 'global_variable_for_test' variable in context.
An error occurred in debuginfo analysis (-2).
Error: Failed to add events. Reason: No such file or directory (Code: -2)

After this patch:

$ perf probe -v --add='generic_perform_write global_variable_for_test'
...
Converting variable global_variable_for_test into trace event.
global_variable_for_test type is int.
Found 1 probe_trace_events.
Opening /sys/kernel/debug/tracing/kprobe_events write=1
Added new event:
Writing event: p:probe/generic_perform_write _stext+1237464
global_variable_for_test=@global_variable_for_test+0:s32
probe:generic_perform_write (on generic_perform_write with
global_variable_for_test)

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

perf record -e probe:generic_perform_write -aR sleep 1

Signed-off-by: He Kuang <[email protected]>
Acked-by: Masami Hiramatsu <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Wang Nan <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/util/probe-finder.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 44554c3..1c3cc07 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -578,10 +578,12 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
/* Search child die for local variables and parameters. */
if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) {
/* Search again in global variables */
- if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die))
+ if (!die_find_variable_at(&pf->cu_die, pf->pvar->var,
+ 0, &vr_die)) {
pr_warning("Failed to find '%s' in this function.\n",
pf->pvar->var);
ret = -ENOENT;
+ }
}
if (ret >= 0)
ret = convert_variable(&vr_die, pf);