Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf probe: Skip if the function address is 0

Skip probes if the entry address of the target function is 0. This can
happen when we're handling C++ debuginfo files.

E.g. without this fix, below case still fail.
----
$ ./perf probe -x /usr/lib64/libstdc++.so.6 -vD is_open
probe-definition(0): is_open
symbol:is_open file:(null) line:0 offset:0 return:0 lazy:(null)
0 arguments
symbol:catch file:(null) line:0 offset:0 return:0 lazy:(null)
symbol:throw file:(null) line:0 offset:0 return:0 lazy:(null)
symbol:rethrow file:(null) line:0 offset:0 return:0 lazy:(null)
Open Debuginfo file: /usr/lib/debug/usr/lib64/libstdc++.so.6.0.22.debug
Try to find probe point from debuginfo.
Matched function: is_open [295df]
found inline addr: 0x8ca80
Probe point found: is_open+0
found inline addr: 0x8ca70
Probe point found: is_open+0
found inline addr: 0x8ca60
Probe point found: is_open+0
Matched function: is_open [6527f]
Matched function: is_open [9fe8a]
Probe point found: is_open+0
Matched function: is_open [19710b]
found inline addr: 0xecca9
Probe point found: stdio_filebuf+57
found inline addr: 0x0
Probe point found: swap+0
Matched function: is_open [19fc9d]
Probe point found: is_open+0
Found 7 probe_trace_events.
p:probe_libstdc++/is_open /usr/lib64/libstdc++.so.6.0.22:0x8ca80
p:probe_libstdc++/is_open_1 /usr/lib64/libstdc++.so.6.0.22:0x8ca70
p:probe_libstdc++/is_open_2 /usr/lib64/libstdc++.so.6.0.22:0x8ca60
p:probe_libstdc++/is_open_3 /usr/lib64/libstdc++.so.6.0.22:0xb0ad0
p:probe_libstdc++/is_open_4 /usr/lib64/libstdc++.so.6.0.22:0xecca9
Failed to synthesize probe trace event.
Error: Failed to add events. Reason: Invalid argument (Code: -22)
----
This is because some instances have entry_pc == 0 (see 19710b and
19fc9d). With this fix, those are skipped.

----
$ ./perf probe -x /usr/lib64/libstdc++.so.6 -D is_open
p:probe_libstdc++/is_open /usr/lib64/libstdc++.so.6.0.22:0x8ca80
p:probe_libstdc++/is_open_1 /usr/lib64/libstdc++.so.6.0.22:0x8ca70
p:probe_libstdc++/is_open_2 /usr/lib64/libstdc++.so.6.0.22:0x8ca60
p:probe_libstdc++/is_open_3 /usr/lib64/libstdc++.so.6.0.22:0xb0ad0
p:probe_libstdc++/is_open_4 /usr/lib64/libstdc++.so.6.0.22:0xecca9
----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/147464490707.29804.14277897643725143867.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Masami Hiramatsu and committed by
Arnaldo Carvalho de Melo
0ad45b33 f8da4b51

+11 -1
+11 -1
tools/perf/util/probe-finder.c
··· 955 955 dwarf_diename(in_die)); 956 956 return -ENOENT; 957 957 } 958 + if (addr == 0) { 959 + pr_debug("%s has no valid entry address. skipped.\n", 960 + dwarf_diename(in_die)); 961 + return -ENOENT; 962 + } 958 963 pf->addr = addr; 959 964 pf->addr += pp->offset; 960 965 pr_debug("found inline addr: 0x%jx\n", ··· 1003 998 } else if (die_is_func_instance(sp_die)) { 1004 999 /* Instances always have the entry address */ 1005 1000 dwarf_entrypc(sp_die, &pf->addr); 1001 + /* But in some case the entry address is 0 */ 1002 + if (pf->addr == 0) { 1003 + pr_debug("%s has no entry PC. Skipped\n", 1004 + dwarf_diename(sp_die)); 1005 + param->retval = 0; 1006 1006 /* Real function */ 1007 - if (pp->lazy_line) 1007 + } else if (pp->lazy_line) 1008 1008 param->retval = find_probe_point_lazy(sp_die, pf); 1009 1009 else { 1010 1010 skip_prologue(sp_die, pf);