Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755234AbbKRGU2 (ORCPT ); Wed, 18 Nov 2015 01:20:28 -0500 Received: from terminus.zytor.com ([198.137.202.10]:50218 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753995AbbKRGU0 (ORCPT ); Wed, 18 Nov 2015 01:20:26 -0500 Date: Tue, 17 Nov 2015 22:19:58 -0800 From: tip-bot for Wang Nan Message-ID: Cc: acme@redhat.com, lizefan@huawei.com, wangnan0@huawei.com, masami.hiramatsu.pt@hitachi.com, ast@kernel.org, linux-kernel@vger.kernel.org, tglx@linutronix.de, mingo@kernel.org, hpa@zytor.com Reply-To: hpa@zytor.com, mingo@kernel.org, tglx@linutronix.de, ast@kernel.org, linux-kernel@vger.kernel.org, masami.hiramatsu.pt@hitachi.com, wangnan0@huawei.com, lizefan@huawei.com, acme@redhat.com In-Reply-To: <1447417761-156094-3-git-send-email-wangnan0@huawei.com> References: <1447417761-156094-3-git-send-email-wangnan0@huawei.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/urgent] perf probe: Clear probe_trace_event when add_probe_trace_event() fails Git-Commit-ID: 092b1f0b5f9f797812da0de927c3aa26acbe8762 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4724 Lines: 135 Commit-ID: 092b1f0b5f9f797812da0de927c3aa26acbe8762 Gitweb: http://git.kernel.org/tip/092b1f0b5f9f797812da0de927c3aa26acbe8762 Author: Wang Nan AuthorDate: Fri, 13 Nov 2015 12:29:11 +0000 Committer: Arnaldo Carvalho de Melo CommitDate: Fri, 13 Nov 2015 12:28:09 -0300 perf probe: Clear probe_trace_event when add_probe_trace_event() fails When probing with a glob, errors in add_probe_trace_event() won't be passed to debuginfo__find_trace_events() because it would be modified by probe_point_search_cb(). It causes a segfault if perf fails to find an argument for a probe point matched by the glob. For example: # ./perf probe -v -n 'SyS_dup? oldfd' probe-definition(0): SyS_dup? oldfd symbol:SyS_dup? file:(null) line:0 offset:0 return:0 lazy:(null) parsing arg: oldfd into oldfd 1 arguments Looking at the vmlinux_path (7 entries long) Using /lib/modules/4.3.0-rc4+/build/vmlinux for symbols Open Debuginfo file: /lib/modules/4.3.0-rc4+/build/vmlinux Try to find probe point from debuginfo. Matched function: SyS_dup3 found inline addr: 0xffffffff812095c0 Probe point found: SyS_dup3+0 Searching 'oldfd' variable in context. Converting variable oldfd into trace event. oldfd type is long int. found inline addr: 0xffffffff812096d4 Probe point found: SyS_dup2+36 Searching 'oldfd' variable in context. Failed to find 'oldfd' in this function. Matched function: SyS_dup3 Probe point found: SyS_dup3+0 Searching 'oldfd' variable in context. Converting variable oldfd into trace event. oldfd type is long int. Matched function: SyS_dup2 Probe point found: SyS_dup2+0 Searching 'oldfd' variable in context. Converting variable oldfd into trace event. oldfd type is long int. Found 4 probe_trace_events. Opening /sys/kernel/debug/tracing//kprobe_events write=1 Writing event: p:probe/SyS_dup3 _text+2135488 oldfd=%di:s64 Segmentation fault (core dumped) # This patch ensures that add_probe_trace_event() doesn't touches tf->ntevs and tf->tevs if those functions fail. After the patch: # perf probe 'SyS_dup? oldfd' Failed to find 'oldfd' in this function. Added new events: probe:SyS_dup3 (on SyS_dup? with oldfd) probe:SyS_dup3_1 (on SyS_dup? with oldfd) probe:SyS_dup2 (on SyS_dup? with oldfd) You can now use it in all perf tools, such as: perf record -e probe:SyS_dup2 -aR sleep 1 Signed-off-by: Wang Nan Tested-by: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Masami Hiramatsu Cc: Zefan Li Cc: pi3orama@163.com Link: http://lkml.kernel.org/r/1447417761-156094-3-git-send-email-wangnan0@huawei.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/probe-finder.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 63993d7..05012bb 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c @@ -1183,7 +1183,7 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) container_of(pf, struct trace_event_finder, pf); struct perf_probe_point *pp = &pf->pev->point; struct probe_trace_event *tev; - struct perf_probe_arg *args; + struct perf_probe_arg *args = NULL; int ret, i; /* Check number of tevs */ @@ -1198,19 +1198,23 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) ret = convert_to_trace_point(&pf->sp_die, tf->mod, pf->addr, pp->retprobe, pp->function, &tev->point); if (ret < 0) - return ret; + goto end; tev->point.realname = strdup(dwarf_diename(sc_die)); - if (!tev->point.realname) - return -ENOMEM; + if (!tev->point.realname) { + ret = -ENOMEM; + goto end; + } pr_debug("Probe point found: %s+%lu\n", tev->point.symbol, tev->point.offset); /* Expand special probe argument if exist */ args = zalloc(sizeof(struct perf_probe_arg) * MAX_PROBE_ARGS); - if (args == NULL) - return -ENOMEM; + if (args == NULL) { + ret = -ENOMEM; + goto end; + } ret = expand_probe_args(sc_die, pf, args); if (ret < 0) @@ -1234,6 +1238,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) } end: + if (ret) { + clear_probe_trace_event(tev); + tf->ntevs--; + } free(args); return ret; } -- 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/