Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752487AbbKYLfE (ORCPT ); Wed, 25 Nov 2015 06:35:04 -0500 Received: from szxga01-in.huawei.com ([58.251.152.64]:64525 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751732AbbKYLfC (ORCPT ); Wed, 25 Nov 2015 06:35:02 -0500 From: Wang Nan To: CC: , , "Wang Nan" , Arnaldo Carvalho de Melo , Masami Hiramatsu , Namhyung Kim , Zefan Li , Subject: [PATCH] perf probe: Adjust dso->long_name for offline module Date: Wed, 25 Nov 2015 11:30:59 +0000 Message-ID: <1448451059-156220-1-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A020203.56559CD6.00B6,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: c01af26dbf181f4a6a91dc6cf9401ba4 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3889 Lines: 111 If libelf unable to open debuginfo for an offline module but the ko has symtab, something unexpected may happen. # rm -rf ~/.debug/ # mv /usr/lib64/elfutils/libebl_x86_64.so{,.bak} # ./perf probe -m /home/wangnan/kmodule/mymodule.ko my_func [mymodule] with build id 326ab42550ef3d24944f53c817533728367effeb not found, continuing without symbols Failed to find symbol my_func in /home/wangnan/kmodule/mymodule.ko Error: Failed to add events # ./perf buildid-cache -a ./mymodule.ko # ./perf probe -m /home/wangnan/kmodule/mymodule.ko my_func Added new event: probe:my_func (on my_func in /home/wangnan/kmodule/mymodule.ko) You can now use it in all perf tools, such as: perf record -e probe:my_func -aR sleep 1 In the above example, probe fails if it isn't in buildid-cache. However, user would expect it success in both case because perf is able to find probe points actually. The problem is because perf won't utilize module's full path if it failed to open debuginfo. In convert_to_probe_trace_events -> find_probe_trace_events_from_map -> get_target_map -> kernel_get_module_map -> machine__findnew_module_map -> map_groups__find_by_name map_groups__find_by_name() is able to find the map of that module, but this information is found from /proc/modules before it knows the real path of the offline module. Therefore, the map->dso->long_name is set to something like '[mymodule]', which prevents dso__load() find the real path of the module file. In another aspect, if dso__load() can get the offline module through buildid cache, it can read symble table from that ko. Even if debuginfo is not available, 'perf probe' can success if the '.symtab' can be found. This patch fixes long_name so dso__load() is able to find module's path and read symbol table in this case. After this patch: # rm -rf ~/.debug/ # mv /usr/lib64/elfutils/libebl_x86_64.so{,.bak} # ./perf probe -m /home/wangnan/kmodule/mymodule.ko my_func Added new event: probe:my_func (on my_func in /home/wangnan/kmodule/mymodule.ko) You can now use it in all perf tools, such as: perf record -e probe:my_func -aR sleep 1 # mv /usr/lib64/elfutils/libebl_x86_64.so{.bak,} Signed-off-by: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Masami Hiramatsu Cc: Namhyung Kim Cc: Zefan Li Cc: pi3orama@163.com --- tools/perf/util/probe-event.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 93996ec..ea4f79f 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -2516,6 +2516,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, struct probe_trace_point *tp; int num_matched_functions; int ret, i, j, skipped = 0; + const char *dup_filename; map = get_target_map(pev->target, pev->uprobes); if (!map) { @@ -2523,6 +2524,21 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, goto out; } + /* + * If the map's dso is an offline module, give dso__load() a chance + * to find the file path of that module by fixing long_name. + */ + if (map->dso && strchr(pev->target, '/')) { + if (!map->dso->long_name || map->dso->long_name[0] == '[') { + dup_filename = strdup(pev->target); + if (!dup_filename) { + ret = -ENOMEM; + goto out; + } + dso__set_long_name(map->dso, dup_filename, true); + } + } + syms = malloc(sizeof(struct symbol *) * probe_conf.max_probes); if (!syms) { ret = -ENOMEM; -- 1.8.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/