Em Thu, Apr 23, 2020 at 08:01:13PM +0900, Masami Hiramatsu escreveu: > Since commit 03db8b583d1c ("perf tools: Fix maps__find_symbol_by_name()") > introduced map address range check in maps__find_symbol_by_name(), > we can not get "_etext" from kernel map because _etext is placed > on the edge of the kernel .text section (= kernel map in perf.) > > To fix this issue, this checks the address correctness > by map address range information (map->start and map->end) > instead of using _etext address. > > This can cause an error if the target inlined function is > embedded in both __init function and normal function. > > For exaample, request_resource() is a normal function but also > embedded in __init reserve_setup(). In this case, the probe point > in reserve_setup() must be skipped. However, without this fix, > it failes to setup all probe points. > ================ > # ./perf probe -v request_resource > probe-definition(0): request_resource > symbol:request_resource file:(null) line:0 offset:0 return:0 lazy:(null) > 0 arguments > Looking at the vmlinux_path (8 entries long) > Using /usr/lib/debug/lib/modules/5.5.17-200.fc31.x86_64/vmlinux for symbols > Open Debuginfo file: /usr/lib/debug/lib/modules/5.5.17-200.fc31.x86_64/vmlinux > Try to find probe point from debuginfo. > Matched function: request_resource [15e29ad] > found inline addr: 0xffffffff82fbf892 > Probe point found: reserve_setup+204 > found inline addr: 0xffffffff810e9790 > Probe point found: request_resource+0 > Found 2 probe_trace_events. > Opening /sys/kernel/debug/tracing//kprobe_events write=1 > Opening /sys/kernel/debug/tracing//README write=0 > Writing event: p:probe/request_resource _text+33290386 > Failed to write event: Invalid argument > Error: Failed to add events. Reason: Invalid argument (Code: -22) > ================ > > With this fix, > > ================ > # ./perf probe request_resource > reserve_setup is out of .text, skip it. > Added new events: > (null):(null) (on request_resource) But what is this (null):(null) probe? Confusing :-) Thanks for working on this! - Arnaldo > probe:request_resource (on request_resource) > > You can now use it in all perf tools, such as: > > perf record -e probe:request_resource -aR sleep 1 > > ================ > > Fixes: 03db8b583d1c ("perf tools: Fix maps__find_symbol_by_name()") > Reported-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx> > Signed-off-by: Masami Hiramatsu <mhiramat@xxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > tools/perf/util/probe-event.c | 25 +++++++++++++------------ > 1 file changed, 13 insertions(+), 12 deletions(-) > > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c > index f75df63309be..a5387e03e365 100644 > --- a/tools/perf/util/probe-event.c > +++ b/tools/perf/util/probe-event.c > @@ -236,21 +236,22 @@ static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) > static bool kprobe_blacklist__listed(unsigned long address); > static bool kprobe_warn_out_range(const char *symbol, unsigned long address) > { > - u64 etext_addr = 0; > - int ret; > - > - /* Get the address of _etext for checking non-probable text symbol */ > - ret = kernel_get_symbol_address_by_name("_etext", &etext_addr, > - false, false); > + struct map *map; > + bool ret = false; > > - if (ret == 0 && etext_addr < address) > - pr_warning("%s is out of .text, skip it.\n", symbol); > - else if (kprobe_blacklist__listed(address)) > + map = kernel_get_module_map(NULL); > + if (map) { > + ret = address <= map->start || map->end < address; > + if (ret) > + pr_warning("%s is out of .text, skip it.\n", symbol); > + map__put(map); > + } > + if (!ret && kprobe_blacklist__listed(address)) { > pr_warning("%s is blacklisted function, skip it.\n", symbol); > - else > - return false; > + ret = true; > + } > > - return true; > + return ret; > } > > /* > -- - Arnaldo