linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH perf/core 00/10] perf-probe --cache and SDT support
@ 2016-07-12 10:04 Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
                   ` (10 more replies)
  0 siblings, 11 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:04 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Hi,

Here is the 14th version of the patchset for probe-cache and 
initial SDT support.

Here is the previous v13: https://lkml.org/lkml/2016/7/1/133

This version includes patches which not merged yet. This also
adds a bugfix;
 - [1/10] Resend the bugfix patch which was sent 4th July.
          (https://lkml.org/lkml/2016/7/3/217)

Thank you,

---

Masami Hiramatsu (10):
      [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params
      perf probe: Accept %sdt and %cached event name
      perf-probe: Make --list shows only available cached events
      perf: probe-cache: Add for_each_probe_cache_entry() wrapper
      perf probe: Allow wildcard for cached events
      perf probe: Search SDT/cached event from all probe caches
      perf probe: Support @BUILDID or @FILE suffix for SDT events
      perf probe: Support a special SDT probe format
      perf build: Add sdt feature detection
      perf-test: Add a test case for SDT event


 tools/perf/Documentation/perf-probe.txt |   11 +
 tools/perf/Makefile.perf                |    3 
 tools/perf/builtin-probe.c              |    2 
 tools/perf/config/Makefile              |   10 +
 tools/perf/tests/Build                  |    1 
 tools/perf/tests/builtin-test.c         |    4 
 tools/perf/tests/make                   |    3 
 tools/perf/tests/sdt.c                  |  115 ++++++++++++
 tools/perf/tests/tests.h                |    1 
 tools/perf/util/build-id.c              |   76 ++++++++
 tools/perf/util/build-id.h              |    3 
 tools/perf/util/probe-event.c           |  309 +++++++++++++++++++++++++++----
 tools/perf/util/probe-event.h           |    1 
 tools/perf/util/probe-file.c            |   57 +++++-
 tools/perf/util/probe-file.h            |    5 +
 15 files changed, 542 insertions(+), 59 deletions(-)
 create mode 100644 tools/perf/tests/sdt.c

--
Masami Hiramatsu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
@ 2016-07-12 10:04 ` Masami Hiramatsu
  2016-07-14  7:05   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:04 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Fix to show correct error messages for $vars and $params because
those special variables requires debug information to find the
real variables or function parameters.

E.g. without this fix;
  ----
  # perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
  Failed to write event: Invalid argument
  Please upgrade your kernel to at least 3.14 to have access to feature $params
    Error: Failed to add events.
  ----
Perf ends up with an error, but the message is not correct.
With this fix, perf shows correct error message as below.
  ----
  # perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
  The /usr/lib64/libc-2.23.so file has no debug information.
  Rebuild with -g, or install an appropriate debuginfo package.
    Error: Failed to add events.
  ----

Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 tools/perf/util/probe-event.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 0201f66..dff9a54 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1547,7 +1547,9 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
 		return true;
 
 	for (i = 0; i < pev->nargs; i++)
-		if (is_c_varname(pev->args[i].var))
+		if (is_c_varname(pev->args[i].var) ||
+		    !strcmp(pev->args[i].var, "$params") ||
+		    !strcmp(pev->args[i].var, "$vars"))
 			return true;
 
 	return false;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
@ 2016-07-12 10:04 ` Masami Hiramatsu
  2016-07-14  7:05   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:04 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

To improbe usability, support %[PROVIDER:]SDTEVENT format to
add new probes on SDT and cached events.

e.g.
  ----
  # perf probe -x /lib/libc-2.17.so  %lll_lock_wait_private
  Added new event:
    sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
  /usr/lib/libc-2.17.so)

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

          perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1

  # perf probe -l | more
    sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
   in /usr/lib/libc-2.17.so)
  ----

Note that this is not only for SDT events, but also normal
events with event-name.

e.g. define "myevent" on cache (-n doesn't add the real probe)
  ----
  # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
  ----
  Reuse the "myevent" from cache as below.
  ----
  # perf probe -x ./perf %myevent
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v10:
  - Update Documentation/perf-probe.txt to add a link about SDT.
 Changes in v7:
  - Fix a bug to return an error if no SDT/cached events found in cache.
---
 tools/perf/Documentation/perf-probe.txt |    9 +++
 tools/perf/util/probe-event.c           |   82 ++++++++++++++++++++++---------
 tools/perf/util/probe-event.h           |    1 
 tools/perf/util/probe-file.c            |    9 +++
 4 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 7a258e9..39e3870 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,6 +151,8 @@ Probe points are defined by following syntax.
     3) Define event based on source file with lazy pattern
      [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
+    4) Pre-defined SDT events or cached event with name
+     %[PROVIDER:]SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
 Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
@@ -158,6 +160,11 @@ modules.
 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  In addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
+Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events.
+
+For details of the SDT, see below.
+https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
 
 PROBE ARGUMENT
 --------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
 
 SEE ALSO
 --------
-linkperf:perf-trace[1], linkperf:perf-record[1]
+linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index dff9a54..3642cca 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1197,6 +1197,34 @@ err:
 	return err;
 }
 
+static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
+{
+	char *ptr;
+
+	ptr = strchr(*arg, ':');
+	if (ptr) {
+		*ptr = '\0';
+		if (!is_c_func_name(*arg))
+			goto ng_name;
+		pev->group = strdup(*arg);
+		if (!pev->group)
+			return -ENOMEM;
+		*arg = ptr + 1;
+	} else
+		pev->group = NULL;
+	if (!is_c_func_name(*arg)) {
+ng_name:
+		semantic_error("%s is bad for event name -it must "
+			       "follow C symbol-naming rule.\n", *arg);
+		return -EINVAL;
+	}
+	pev->event = strdup(*arg);
+	if (pev->event == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
@@ -1204,38 +1232,43 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	char *ptr, *tmp;
 	char c, nc = 0;
 	bool file_spec = false;
+	int ret;
+
 	/*
 	 * <Syntax>
 	 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
 	 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
+	 * perf probe %[GRP:]SDT_EVENT
 	 */
 	if (!arg)
 		return -EINVAL;
 
+	if (arg[0] == '%') {
+		pev->sdt = true;
+		arg++;
+	}
+
 	ptr = strpbrk(arg, ";=@+%");
-	if (ptr && *ptr == '=') {	/* Event name */
-		*ptr = '\0';
-		tmp = ptr + 1;
-		ptr = strchr(arg, ':');
+	if (pev->sdt) {
 		if (ptr) {
-			*ptr = '\0';
-			if (!is_c_func_name(arg))
-				goto not_fname;
-			pev->group = strdup(arg);
-			if (!pev->group)
-				return -ENOMEM;
-			arg = ptr + 1;
-		} else
-			pev->group = NULL;
-		if (!is_c_func_name(arg)) {
-not_fname:
-			semantic_error("%s is bad for event name -it must "
-				       "follow C symbol-naming rule.\n", arg);
+			semantic_error("%s must contain only an SDT event name.\n", arg);
 			return -EINVAL;
 		}
-		pev->event = strdup(arg);
-		if (pev->event == NULL)
-			return -ENOMEM;
+		ret = parse_perf_probe_event_name(&arg, pev);
+		if (ret == 0) {
+			if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
+				ret = -errno;
+		}
+		return ret;
+	}
+
+	if (ptr && *ptr == '=') {	/* Event name */
+		*ptr = '\0';
+		tmp = ptr + 1;
+		ret = parse_perf_probe_event_name(&arg, pev);
+		if (ret < 0)
+			return ret;
+
 		arg = tmp;
 	}
 
@@ -2876,7 +2909,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 
 	entry = probe_cache__find(cache, pev);
 	if (!entry) {
-		ret = 0;
+		/* SDT must be in the cache */
+		ret = pev->sdt ? -ENOENT : 0;
 		goto out;
 	}
 
@@ -2915,7 +2949,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 {
 	int ret;
 
-	if (!pev->group) {
+	if (!pev->group && !pev->sdt) {
 		/* Set group name if not given */
 		if (!pev->uprobes) {
 			pev->group = strdup(PERFPROBE_GROUP);
@@ -2934,8 +2968,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 
 	/* At first, we need to lookup cache entry */
 	ret = find_probe_trace_events_from_cache(pev, tevs);
-	if (ret > 0)
-		return ret;	/* Found in probe cache */
+	if (ret > 0 || pev->sdt)	/* SDT can be found only in the cache */
+		return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
 
 	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
 		ret = find_probe_trace_events_from_map(pev, tevs);
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 432b690..e18ea9f 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -85,6 +85,7 @@ struct perf_probe_event {
 	char			*group;	/* Group name */
 	struct perf_probe_point	point;	/* Probe point */
 	int			nargs;	/* Number of arguments */
+	bool			sdt;	/* SDT/cached event flag */
 	bool			uprobes;	/* Uprobe event flag */
 	char			*target;	/* Target binary */
 	struct perf_probe_arg	*args;	/* Arguments */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 5b563b2..b642d06 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -547,6 +547,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 		return NULL;
 
 	list_for_each_entry(entry, &pcache->entries, node) {
+		if (pev->sdt) {
+			if (entry->pev.event &&
+			    streql(entry->pev.event, pev->event) &&
+			    (!pev->group ||
+			     streql(entry->pev.group, pev->group)))
+				goto found;
+
+			continue;
+		}
 		/* Hit if same event name or same command-string */
 		if ((pev->event &&
 		     (streql(entry->pev.group, pev->group) &&

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
  2016-07-12 10:04 ` [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
@ 2016-07-12 10:04 ` Masami Hiramatsu
  2016-07-13 19:28   ` Arnaldo Carvalho de Melo
  2016-07-14  7:06   ` [tip:perf/core] perf probe: Make --list show " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
                   ` (7 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:04 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

Make "perf probe --cache --list" shows only available cached events
by checking build-id validity.

E.g. without this patch:
  ----
  $ ./perf probe --cache --add oldevent=cmd_probe
  $ make #(to update ./perf)
  $ ./perf probe --cache --add newevent=cmd_probe
  $ ./perf probe --cache --list
  /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
  probe_perf:newevent=cmd_probe
  /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1
  probe_perf:oldevent=cmd_probe
  ----
It shows both of old and new events but user can not use old one.
With this;
  ----
  $ ./perf probe --cache -l
  /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
  probe_perf:newevent=cmd_probe
  ----
This show only new event which is on the existing binary.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v13:
  - Instead of the perf-list, apply this change for perf-probe --list
    because of avoiding to confuse user.
 Changes in v7:
  - Validate build-id via sysfs if it is for kallsyms,
 Changes in v4:
  - Rename a parameter 'valid' to 'validonly' :)
---
 tools/perf/builtin-probe.c   |    2 +-
 tools/perf/util/build-id.c   |   33 ++++++++++++++++++++++++++++++++-
 tools/perf/util/build-id.h   |    2 +-
 tools/perf/util/probe-file.c |    2 +-
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index a1a5cd1..de75af5 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
 	struct str_node *nd;
 	int ret;
 
-	bidlist = build_id_cache__list_all();
+	bidlist = build_id_cache__list_all(false);
 	if (!bidlist) {
 		ret = -errno;
 		pr_debug("Failed to get buildids: %d\n", ret);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index e1a1640..8e86a83 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -206,6 +206,31 @@ out:
 	return ret;
 }
 
+/* Check if the given build_id cache is valid on current running system */
+static bool build_id_cache__valid_id(char *sbuild_id)
+{
+	char real_sbuild_id[SBUILD_ID_SIZE] = "";
+	char *pathname;
+	int ret = 0;
+	bool result = false;
+
+	pathname = build_id_cache__origname(sbuild_id);
+	if (!pathname)
+		return false;
+
+	if (!strcmp(pathname, DSO__NAME_KALLSYMS))
+		ret = sysfs__sprintf_build_id("/", real_sbuild_id);
+	else if (pathname[0] == '/')
+		ret = filename__sprintf_build_id(pathname, real_sbuild_id);
+	else
+		ret = -EINVAL;	/* Should we support other special DSO cache? */
+	if (ret >= 0)
+		result = (strcmp(sbuild_id, real_sbuild_id) == 0);
+	free(pathname);
+
+	return result;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
 	return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
 	return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
 }
 
-struct strlist *build_id_cache__list_all(void)
+struct strlist *build_id_cache__list_all(bool validonly)
 {
 	struct strlist *toplist, *linklist = NULL, *bidlist;
 	struct str_node *nd, *nd2;
 	char *topdir, *linkdir = NULL;
 	char sbuild_id[SBUILD_ID_SIZE];
 
+	/* for filename__ functions */
+	if (validonly)
+		symbol__init(NULL);
+
 	/* Open the top-level directory */
 	if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
 		return NULL;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
 			if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
 				     nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
 				goto err_out;
+			if (validonly && !build_id_cache__valid_id(sbuild_id))
+				continue;
 			if (strlist__add(bidlist, sbuild_id) < 0)
 				goto err_out;
 		}
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index b742e27..64e740f 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
 char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso);
-struct strlist *build_id_cache__list_all(void);
+struct strlist *build_id_cache__list_all(bool validonly);
 int build_id_cache__list_build_ids(const char *pathname,
 				   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index b642d06..b062545 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
 	pr_debug("list cache with filter: %s\n", buf);
 	free(buf);
 
-	bidlist = build_id_cache__list_all();
+	bidlist = build_id_cache__list_all(true);
 	if (!bidlist) {
 		pr_debug("Failed to get buildids: %d\n", errno);
 		return -EINVAL;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (2 preceding siblings ...)
  2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-14  7:06   ` [tip:perf/core] perf " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Add for_each_probe_cache_entry() wrapper macro
for hiding list in probe_cache.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-file.c |    8 ++++----
 tools/perf/util/probe-file.h |    2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index b062545..9152ad2 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 	if (!cmd)
 		return NULL;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		if (pev->sdt) {
 			if (entry->pev.event &&
 			    streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache,
 {
 	struct probe_cache_entry *entry = NULL;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		/* Hit if same event name or same command-string */
 		if (streql(entry->pev.group, group) &&
 		    streql(entry->pev.event, event))
@@ -746,7 +746,7 @@ int probe_cache__commit(struct probe_cache *pcache)
 	if (ret < 0)
 		goto out;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		ret = probe_cache_entry__write(entry, pcache->fd);
 		pr_debug("Cache committed: %d\n", ret);
 		if (ret < 0)
@@ -788,7 +788,7 @@ static int probe_cache__show_entries(struct probe_cache *pcache,
 {
 	struct probe_cache_entry *entry;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		if (probe_cache_entry__compare(entry, filter))
 			printf("%s\n", entry->spev);
 	}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index ddf5ae2..d513b34 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -21,6 +21,8 @@ struct probe_cache {
 
 #define PF_FL_UPROBE	1
 #define PF_FL_RW	2
+#define for_each_probe_cache_entry(entry, pcache) \
+	list_for_each_entry(entry, &pcache->entries, node)
 
 int probe_file__open(int flag);
 int probe_file__open_both(int *kfd, int *ufd, int flag);

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (3 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-13 19:36   ` Arnaldo Carvalho de Melo
  2016-07-14  7:07   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Allo glob wildcard for reusing cached/SDT events. E.g.

  # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v12:
  - Rename strlist__for_each to strlist__for_each_entry.
 Changes in v10:
  - Split off bugfix, adding interface, and target search patches.
  - Do not export clear_probe_trace_events().
 Changes in v7:
  - Continue to search caches if a build-id cache has no probe cache.
  - Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
  - Fix to add probes correctly when a wildcard matchs both of
    uprobes and kprobes.
 Changes in v5.1:
  - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
---
 tools/perf/util/probe-event.c |  107 +++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/probe-file.c  |   38 ++++++++++++---
 tools/perf/util/probe-file.h  |    3 +
 3 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 3642cca..1aeac09 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
 	ptr = strchr(*arg, ':');
 	if (ptr) {
 		*ptr = '\0';
-		if (!is_c_func_name(*arg))
+		if (!pev->sdt && !is_c_func_name(*arg))
 			goto ng_name;
 		pev->group = strdup(*arg);
 		if (!pev->group)
@@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
 		*arg = ptr + 1;
 	} else
 		pev->group = NULL;
-	if (!is_c_func_name(*arg)) {
+	if (!pev->sdt && !is_c_func_name(*arg)) {
 ng_name:
 		semantic_error("%s is bad for event name -it must "
 			       "follow C symbol-naming rule.\n", *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
 			ret = -ENOMEM;
 			goto out;
 		}
+		tev->uprobes = (tp->module[0] == '/');
 		p++;
 	} else
 		p = argv[1];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 	int ret;
 
 	/* If probe_event or trace_event already have the name, reuse it */
-	if (pev->event)
+	if (pev->event && !pev->sdt)
 		event = pev->event;
 	else if (tev->event)
 		event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 		else
 			event = tev->point.realname;
 	}
-	if (pev->group)
+	if (pev->group && !pev->sdt)
 		group = pev->group;
 	else if (tev->group)
 		group = tev->group;
@@ -2894,6 +2895,100 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+/* Concatinate two arrays */
+static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
+{
+	void *ret;
+
+	ret = malloc(sz_a + sz_b);
+	if (ret) {
+		memcpy(ret, a, sz_a);
+		memcpy(ret + sz_a, b, sz_b);
+	}
+	return ret;
+}
+
+static int
+concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
+			  struct probe_trace_event **tevs2, int ntevs2)
+{
+	struct probe_trace_event *new_tevs;
+	int ret = 0;
+
+	if (ntevs == 0) {
+		*tevs = *tevs2;
+		*ntevs = ntevs2;
+		*tevs2 = NULL;
+		return 0;
+	}
+
+	if (*ntevs + ntevs2 > probe_conf.max_probes)
+		ret = -E2BIG;
+	else {
+		/* Concatinate the array of probe_trace_event */
+		new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
+				  *tevs2, ntevs2 * sizeof(**tevs2));
+		if (!new_tevs)
+			ret = -ENOMEM;
+		else {
+			free(*tevs);
+			*tevs = new_tevs;
+			*ntevs += ntevs2;
+		}
+	}
+	if (ret < 0)
+		clear_probe_trace_events(*tevs2, ntevs2);
+	zfree(tevs2);
+
+	return ret;
+}
+
+/*
+ * Try to find probe_trace_event from given probe caches. Return the number
+ * of cached events found, if an error occurs return the error.
+ */
+static int find_cached_events(struct perf_probe_event *pev,
+			      struct probe_trace_event **tevs,
+			      const char *target)
+{
+	struct probe_cache *cache;
+	struct probe_cache_entry *entry;
+	struct probe_trace_event *tmp_tevs = NULL;
+	int ntevs = 0;
+	int ret = 0;
+
+	cache = probe_cache__new(target);
+	/* Return 0 ("not found") if the target has no probe cache. */
+	if (!cache)
+		return 0;
+
+	for_each_probe_cache_entry(entry, cache) {
+		/* Skip the cache entry which has no name */
+		if (!entry->pev.event || !entry->pev.group)
+			continue;
+		if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
+		    strglobmatch(entry->pev.event, pev->event)) {
+			ret = probe_cache_entry__get_event(entry, &tmp_tevs);
+			if (ret > 0)
+				ret = concat_probe_trace_events(tevs, &ntevs,
+								&tmp_tevs, ret);
+			if (ret < 0)
+				break;
+		}
+	}
+	probe_cache__delete(cache);
+	if (ret < 0) {
+		clear_probe_trace_events(*tevs, ntevs);
+		zfree(tevs);
+	} else {
+		ret = ntevs;
+		if (ntevs > 0 && target && target[0] == '/')
+			pev->uprobes = true;
+	}
+
+	return ret;
+}
+
 static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 					      struct probe_trace_event **tevs)
 {
@@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 	struct str_node *node;
 	int ret, i;
 
+	if (pev->sdt)
+		/* For SDT/cached events, we use special search functions */
+		return find_cached_events(pev, tevs, pev->target);
+
 	cache = probe_cache__new(pev->target);
 	if (!cache)
 		return 0;
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 9152ad2..78a84f5 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)
 	return entry;
 }
 
-/* For the kernel probe caches, pass target = NULL */
+int probe_cache_entry__get_event(struct probe_cache_entry *entry,
+				 struct probe_trace_event **tevs)
+{
+	struct probe_trace_event *tev;
+	struct str_node *node;
+	int ret, i;
+
+	ret = strlist__nr_entries(entry->tevlist);
+	if (ret > probe_conf.max_probes)
+		return -E2BIG;
+
+	*tevs = zalloc(ret * sizeof(*tev));
+	if (!*tevs)
+		return -ENOMEM;
+
+	i = 0;
+	strlist__for_each_entry(node, entry->tevlist) {
+		tev = &(*tevs)[i++];
+		ret = parse_probe_trace_command(node->s, tev);
+		if (ret < 0)
+			break;
+	}
+	return i;
+}
+
+/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
 static int probe_cache__open(struct probe_cache *pcache, const char *target)
 {
 	char cpath[PATH_MAX];
 	char sbuildid[SBUILD_ID_SIZE];
 	char *dir_name = NULL;
-	bool is_kallsyms = !target;
+	bool is_kallsyms = false;
 	int ret, fd;
 
 	if (target && build_id_cache__cached(target)) {
@@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
 		goto found;
 	}
 
-	if (target)
-		ret = filename__sprintf_build_id(target, sbuildid);
-	else {
+	if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
 		target = DSO__NAME_KALLSYMS;
+		is_kallsyms = true;
 		ret = sysfs__sprintf_build_id("/", sbuildid);
-	}
+	} else
+		ret = filename__sprintf_build_id(target, sbuildid);
+
 	if (ret < 0) {
 		pr_debug("Failed to get build-id from %s.\n", target);
 		return ret;
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index d513b34..cafbe1d 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
 				  struct strlist *plist);
 int probe_file__del_strlist(int fd, struct strlist *namelist);
 
+int probe_cache_entry__get_event(struct probe_cache_entry *entry,
+				 struct probe_trace_event **tevs);
+
 struct probe_cache *probe_cache__new(const char *target);
 int probe_cache__add_entry(struct probe_cache *pcache,
 			   struct perf_probe_event *pev,

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (4 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-14  7:07   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Search SDT/cached event from all probe caches if user doesn't
pass any binary. With this, we don't have to specify target
binary for SDT and named cached events (which start with %).

E.g. without this, a target binary must be passed with -x.

 # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

With this change, we don't need it anymore.

 # perf probe -a %sdt_libc:\*

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v12:
  - Rename strlist__for_each to strlist__for_each_entry.
 Changes from v10:
  - Splitted from "perf probe: Allow wildcard for cached events"
---
 tools/perf/util/probe-event.c |  105 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 1aeac09..679aa6b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 	return 0;
 }
 
-static int __add_probe_trace_events(struct perf_probe_event *pev,
-				     struct probe_trace_event *tevs,
-				     int ntevs, bool allow_suffix)
+static int __open_probe_file_and_namelist(bool uprobe,
+					  struct strlist **namelist)
 {
-	int i, fd, ret;
-	struct probe_trace_event *tev = NULL;
-	struct probe_cache *cache = NULL;
-	struct strlist *namelist;
+	int fd;
 
-	fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
+	fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
 	if (fd < 0)
 		return fd;
 
 	/* Get current event names */
-	namelist = probe_file__get_namelist(fd);
-	if (!namelist) {
+	*namelist = probe_file__get_namelist(fd);
+	if (!(*namelist)) {
 		pr_debug("Failed to get current event list.\n");
-		ret = -ENOMEM;
-		goto close_out;
+		close(fd);
+		return -ENOMEM;
 	}
+	return fd;
+}
+
+static int __add_probe_trace_events(struct perf_probe_event *pev,
+				     struct probe_trace_event *tevs,
+				     int ntevs, bool allow_suffix)
+{
+	int i, fd[2] = {-1, -1}, up, ret;
+	struct probe_trace_event *tev = NULL;
+	struct probe_cache *cache = NULL;
+	struct strlist *namelist[2] = {NULL, NULL};
+
+	up = pev->uprobes ? 1 : 0;
+	fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
+	if (fd[up] < 0)
+		return fd[up];
 
 	ret = 0;
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
+		up = tev->uprobes ? 1 : 0;
+		if (fd[up] == -1) {	/* Open the kprobe/uprobe_events */
+			fd[up] = __open_probe_file_and_namelist(up,
+								&namelist[up]);
+			if (fd[up] < 0)
+				goto close_out;
+		}
 		/* Skip if the symbol is out of .text or blacklisted */
 		if (!tev->point.symbol && !pev->uprobes)
 			continue;
 
 		/* Set new name for tev (and update namelist) */
-		ret = probe_trace_event__set_name(tev, pev, namelist,
+		ret = probe_trace_event__set_name(tev, pev, namelist[up],
 						  allow_suffix);
 		if (ret < 0)
 			break;
 
-		ret = probe_file__add_event(fd, tev);
+		ret = probe_file__add_event(fd[up], tev);
 		if (ret < 0)
 			break;
 
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		probe_cache__delete(cache);
 	}
 
-	strlist__delete(namelist);
 close_out:
-	close(fd);
+	for (up = 0; up < 2; up++) {
+		strlist__delete(namelist[up]);
+		if (fd[up] >= 0)
+			close(fd[up]);
+	}
 	return ret;
 }
 
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,
 	return ret;
 }
 
+/* Try to find probe_trace_event from all probe caches */
+static int find_cached_events_all(struct perf_probe_event *pev,
+				   struct probe_trace_event **tevs)
+{
+	struct probe_trace_event *tmp_tevs = NULL;
+	struct strlist *bidlist;
+	struct str_node *nd;
+	char *pathname;
+	int ntevs = 0;
+	int ret;
+
+	/* Get the buildid list of all valid caches */
+	bidlist = build_id_cache__list_all(true);
+	if (!bidlist) {
+		ret = -errno;
+		pr_debug("Failed to get buildids: %d\n", ret);
+		return ret;
+	}
+
+	ret = 0;
+	strlist__for_each_entry(nd, bidlist) {
+		pathname = build_id_cache__origname(nd->s);
+		ret = find_cached_events(pev, &tmp_tevs, pathname);
+		/* In the case of cnt == 0, we just skip it */
+		if (ret > 0)
+			ret = concat_probe_trace_events(tevs, &ntevs,
+							&tmp_tevs, ret);
+		free(pathname);
+		if (ret < 0)
+			break;
+	}
+	strlist__delete(bidlist);
+
+	if (ret < 0) {
+		clear_probe_trace_events(*tevs, ntevs);
+		zfree(tevs);
+	} else
+		ret = ntevs;
+
+	return ret;
+}
+
 static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 					      struct probe_trace_event **tevs)
 {
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 	struct str_node *node;
 	int ret, i;
 
-	if (pev->sdt)
+	if (pev->sdt) {
 		/* For SDT/cached events, we use special search functions */
-		return find_cached_events(pev, tevs, pev->target);
-
+		if (!pev->target)
+			return find_cached_events_all(pev, tevs);
+		else
+			return find_cached_events(pev, tevs, pev->target);
+	}
 	cache = probe_cache__new(pev->target);
 	if (!cache)
 		return 0;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (5 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-13 19:50   ` Arnaldo Carvalho de Melo
  2016-07-14  7:08   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 08/10] perf probe: Support a special SDT probe format Masami Hiramatsu
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Support @BUILDID or @FILE suffix for SDT events. This allows
perf to add probes on SDTs/pre-cached events on given FILE
or the file which has given BUILDID (also, this complements
BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below.
If you would like to add a probe on sdt_libstdcxx:catch on gcc,
you can do as below.

  ----
  # perf list sdt | tail -n 6
    sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
    sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
    sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  # perf probe -a %sdt_libstdcxx:catch@0cc
  Added new event:
    sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)

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

  	perf record -e sdt_libstdcxx:catch -aR sleep 1
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 Changes in v12:
  - Rename strlist__for_each to strlist__for_each_entry.
---
 tools/perf/util/build-id.c    |   43 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/build-id.h    |    1 +
 tools/perf/util/probe-event.c |   17 ++++++++++++++--
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 8e86a83..e59003e 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -523,6 +523,49 @@ err_out:
 	goto out_free;
 }
 
+static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (!isxdigit(maybe_sbuild_id[i]))
+			return false;
+	}
+	return true;
+}
+
+/* Return the valid complete build-id */
+char *build_id_cache__complement(const char *incomplete_sbuild_id)
+{
+	struct strlist *bidlist;
+	struct str_node *nd, *cand = NULL;
+	char *sbuild_id = NULL;
+	size_t len = strlen(incomplete_sbuild_id);
+
+	if (len >= SBUILD_ID_SIZE ||
+	    !str_is_build_id(incomplete_sbuild_id, len))
+		return NULL;
+
+	bidlist = build_id_cache__list_all(true);
+	if (!bidlist)
+		return NULL;
+
+	strlist__for_each_entry(nd, bidlist) {
+		if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
+			continue;
+		if (cand) {	/* Error: There are more than 2 candidates. */
+			cand = NULL;
+			break;
+		}
+		cand = nd;
+	}
+	if (cand)
+		sbuild_id = strdup(cand->s);
+	strlist__delete(bidlist);
+
+	return sbuild_id;
+}
+
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso)
 {
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 64e740f..d279906 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso);
 struct strlist *build_id_cache__list_all(bool validonly);
+char *build_id_cache__complement(const char *incomplete_sbuild_id);
 int build_id_cache__list_build_ids(const char *pathname,
 				   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 679aa6b..0dadaa3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	ptr = strpbrk(arg, ";=@+%");
 	if (pev->sdt) {
 		if (ptr) {
-			semantic_error("%s must contain only an SDT event name.\n", arg);
-			return -EINVAL;
+			if (*ptr != '@') {
+				semantic_error("%s must be an SDT name.\n",
+					       arg);
+				return -EINVAL;
+			}
+			/* This must be a target file name or build id */
+			tmp = build_id_cache__complement(ptr + 1);
+			if (tmp) {
+				pev->target = build_id_cache__origname(tmp);
+				free(tmp);
+			} else
+				pev->target = strdup(ptr + 1);
+			if (!pev->target)
+				return -ENOMEM;
+			*ptr = '\0';
 		}
 		ret = parse_perf_probe_event_name(&arg, pev);
 		if (ret == 0) {

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 08/10] perf probe: Support a special SDT probe format
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (6 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-14  7:08   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:05 ` [PATCH perf/core 09/10] perf build: Add sdt feature detection Masami Hiramatsu
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Support a special SDT probe format which can omit the '%' prefix
only if the SDT group name starts with "sdt_". So, for example
both of "%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable
for perf probe --add.

E.g. without this:
  ----
  # perf probe -a sdt_libc:setjmp
  Semantic error :There is non-digit char in line number.
  ...
  ----
With this:
  ----
  # perf probe -a sdt_libc:setjmp
  Added new event:
    sdt_libc:setjmp      (on %setjmp in /usr/lib64/libc-2.20.so)

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

  	perf record -e sdt_libc:setjmp -aR sleep 1
  ----

Suggested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 tools/perf/Documentation/perf-probe.txt |    4 +++-
 tools/perf/util/probe-event.c           |   12 ++++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 39e3870..736da44 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -152,7 +152,9 @@ Probe points are defined by following syntax.
      [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
     4) Pre-defined SDT events or cached event with name
-     %[PROVIDER:]SDTEVENT
+     %[sdt_PROVIDER:]SDTEVENT
+     or,
+     sdt_PROVIDER:SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
 Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 0dadaa3..e12e3b0 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1243,9 +1243,17 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	if (!arg)
 		return -EINVAL;
 
-	if (arg[0] == '%') {
+	/*
+	 * If the probe point starts with '%',
+	 * or starts with "sdt_" and has a ':' but no '=',
+	 * then it should be a SDT/cached probe point.
+	 */
+	if (arg[0] == '%' ||
+	    (!strncmp(arg, "sdt_", 4) &&
+	     !!strchr(arg, ':') && !strchr(arg, '='))) {
 		pev->sdt = true;
-		arg++;
+		if (arg[0] == '%')
+			arg++;
 	}
 
 	ptr = strpbrk(arg, ";=@+%");

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 09/10] perf build: Add sdt feature detection
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (7 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 08/10] perf probe: Support a special SDT probe format Masami Hiramatsu
@ 2016-07-12 10:05 ` Masami Hiramatsu
  2016-07-14  7:09   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2016-07-12 10:06 ` [PATCH perf/core 10/10] perf-test: Add a test case for SDT event Masami Hiramatsu
  2016-07-14  1:35 ` [PATCH perf/core 00/10] perf-probe --cache and SDT support Arnaldo Carvalho de Melo
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:05 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

This checks whether sys/sdt.h is available or not,
which is required for DTRACE_PROBE().
We can disable this feature by passing NO_SDT=1 when
building.
This flag will be used for SDT test case and further
SDT events in perftools.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 tools/perf/Makefile.perf   |    3 +++
 tools/perf/config/Makefile |   10 ++++++++++
 tools/perf/tests/make      |    3 ++-
 3 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 3dd529b..a1ec630 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -61,7 +61,8 @@ FEATURE_TESTS_BASIC :=			\
 	zlib				\
 	lzma				\
 	get_cpuid			\
-	bpf
+	bpf				\
+	sdt
 
 # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
 # of all feature tests
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 6747116..8716ab2 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -44,7 +44,8 @@ FILES=					\
 	test-zlib.bin			\
 	test-lzma.bin			\
 	test-bpf.bin			\
-	test-get_cpuid.bin
+	test-get_cpuid.bin		\
+	test-sdt.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 
@@ -209,6 +210,9 @@ $(OUTPUT)test-get_cpuid.bin:
 $(OUTPUT)test-bpf.bin:
 	$(BUILD)
 
+$(OUTPUT)test-sdt.bin:
+	$(BUILD)
+
 -include $(OUTPUT)*.d
 
 ###############################
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 7433cca..bab33d8 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -141,6 +141,10 @@
 # include "test-libcrypto.c"
 #undef main
 
+#define main main_test_sdt
+# include "test-sdt.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
 	main_test_libpython();
@@ -173,6 +177,7 @@ int main(int argc, char *argv[])
 	main_test_get_cpuid();
 	main_test_bpf();
 	main_test_libcrypto();
+	main_test_sdt();
 
 	return 0;
 }
diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c
new file mode 100644
index 0000000..e4531a6
--- /dev/null
+++ b/tools/build/feature/test-sdt.c
@@ -0,0 +1,7 @@
+#include <sys/sdt.h>
+
+int main(void)
+{
+	DTRACE_PROBE(provider, name);
+	return 0;
+}
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index d0a2cb1..458eaf5 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBBPF if you do not want BPF support
 #
+# Define NO_SDT if you do not want to define SDT event in perf tools,
+# note that it doesn't disable SDT scanning support.
+#
 # Define FEATURES_DUMP to provide features detection dump file
 # and bypass the feature detection
 
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c7e269a..b55f9ec 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -349,6 +349,16 @@ ifndef NO_LIBELF
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
+ifndef NO_SDT
+  ifneq ($(feature-sdt), 1)
+    msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev);
+    NO_SDT := 1;
+  else
+    CFLAGS += -DHAVE_SDT_EVENT
+    $(call detected,CONFIG_SDT_EVENT)
+  endif
+endif
+
 ifdef PERF_HAVE_JITDUMP
   ifndef NO_DWARF
     $(call detected,CONFIG_JITDUMP)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 51966d9..143f4d5 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -82,6 +82,7 @@ make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
+make_no_sdt	    := NO_SDT=1
 make_tags           := tags
 make_cscope         := cscope
 make_help           := help
@@ -105,7 +106,7 @@ make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
-make_minimal        += NO_LIBCRYPTO=1
+make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1
 
 # $(run) contains all available tests
 run := make_pure

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [PATCH perf/core 10/10] perf-test: Add a test case for SDT event
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (8 preceding siblings ...)
  2016-07-12 10:05 ` [PATCH perf/core 09/10] perf build: Add sdt feature detection Masami Hiramatsu
@ 2016-07-12 10:06 ` Masami Hiramatsu
  2016-07-14  7:10   ` [tip:perf/core] perf test: " tip-bot for Masami Hiramatsu
  2016-07-14  1:35 ` [PATCH perf/core 00/10] perf-probe --cache and SDT support Arnaldo Carvalho de Melo
  10 siblings, 1 reply; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-12 10:06 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Masami Hiramatsu, linux-kernel, Namhyung Kim, Peter Zijlstra,
	Ingo Molnar, Hemant Kumar, Ananth N Mavinakayanahalli,
	Brendan Gregg

Add a basic test case for SDT event support.
This test scans an SDT event in perftools and
check whether the SDT event is correctly stored
into the buildid cache.
Here is an example:
  ----
  $ perf test sdt -v
  47: Test SDT event probing                                   :
  --- start ---
  test child forked, pid 20732
  Found 72 SDTs in /home/mhiramat/ksrc/linux/tools/perf/perf
  Writing cache: %sdt_perf:test_target=test_target
  Cache committed: 0
  symbol:test_target file:(null) line:0 offset:0 return:0 lazy:(null)
  test child finished with 0
  ---- end ----
  Test SDT event probing: Ok
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
---
 tools/perf/tests/Build          |    1 
 tools/perf/tests/builtin-test.c |    4 +
 tools/perf/tests/sdt.c          |  115 +++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |    1 
 4 files changed, 121 insertions(+)
 create mode 100644 tools/perf/tests/sdt.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66a2898..4158422 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -39,6 +39,7 @@ perf-y += stat.o
 perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
+perf-y += sdt.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 07c14e9..74ed9f5 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -218,6 +218,10 @@ static struct test generic_tests[] = {
 		.func = test__cpu_map_print,
 	},
 	{
+		.desc = "Test SDT event probing",
+		.func = test__sdt_event,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
new file mode 100644
index 0000000..f59d210
--- /dev/null
+++ b/tools/perf/tests/sdt.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <util/util.h>
+#include <util/evlist.h>
+#include <linux/filter.h>
+#include "tests.h"
+#include "debug.h"
+#include "probe-file.h"
+#include "build-id.h"
+
+/* To test SDT event, we need libelf support to scan elf binary */
+#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
+
+#include <sys/sdt.h>
+
+static int target_function(void)
+{
+	DTRACE_PROBE(perf, test_target);
+	return TEST_OK;
+}
+
+/* Copied from builtin-buildid-cache.c */
+static int build_id_cache__add_file(const char *filename)
+{
+	char sbuild_id[SBUILD_ID_SIZE];
+	u8 build_id[BUILD_ID_SIZE];
+	int err;
+
+	err = filename__read_build_id(filename, &build_id, sizeof(build_id));
+	if (err < 0) {
+		pr_debug("Failed to read build id of %s\n", filename);
+		return err;
+	}
+
+	build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+	err = build_id_cache__add_s(sbuild_id, filename, false, false);
+	if (err < 0)
+		pr_debug("Failed to add build id cache of %s\n", filename);
+	return err;
+}
+
+static char *get_self_path(void)
+{
+	char *buf = calloc(PATH_MAX, sizeof(char));
+
+	if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
+		pr_debug("Failed to get correct path of perf\n");
+		free(buf);
+		return NULL;
+	}
+	return buf;
+}
+
+static int search_cached_probe(const char *target,
+			       const char *group, const char *event)
+{
+	struct probe_cache *cache = probe_cache__new(target);
+	int ret = 0;
+
+	if (!cache) {
+		pr_debug("Failed to open probe cache of %s\n", target);
+		return -EINVAL;
+	}
+
+	if (!probe_cache__find_by_name(cache, group, event)) {
+		pr_debug("Failed to find %s:%s in the cache\n", group, event);
+		ret = -ENOENT;
+	}
+	probe_cache__delete(cache);
+
+	return ret;
+}
+
+int test__sdt_event(int subtests __maybe_unused)
+{
+	int ret = TEST_FAIL;
+	char __tempdir[] = "./test-buildid-XXXXXX";
+	char *tempdir = NULL, *myself = get_self_path();
+
+	if (myself == NULL || mkdtemp(__tempdir) == NULL) {
+		pr_debug("Failed to make a tempdir for build-id cache\n");
+		goto error;
+	}
+	/* Note that buildid_dir must be an absolute path */
+	tempdir = realpath(__tempdir, NULL);
+
+	/* At first, scan itself */
+	set_buildid_dir(tempdir);
+	if (build_id_cache__add_file(myself) < 0)
+		goto error_rmdir;
+
+	/* Open a cache and make sure the SDT is stored */
+	if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
+		goto error_rmdir;
+
+	/* TBD: probing on the SDT event and collect logs */
+
+	/* Call the target and get an event */
+	ret = target_function();
+
+error_rmdir:
+	/* Cleanup temporary buildid dir */
+	rm_rf(tempdir);
+error:
+	free(tempdir);
+	free(myself);
+	return ret;
+}
+#else
+int test__sdt_event(int subtests __maybe_unused)
+{
+	pr_debug("Skip SDT event test because SDT support is not compiled\n");
+	return TEST_SKIP;
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 52f9695..a0288f8 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -88,6 +88,7 @@ int test__event_update(int subtest);
 int test__event_times(int subtest);
 int test__backward_ring_buffer(int subtest);
 int test__cpu_map_print(int subtest);
+int test__sdt_event(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events
  2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
@ 2016-07-13 19:28   ` Arnaldo Carvalho de Melo
  2016-07-14  6:13     ` Masami Hiramatsu
  2016-07-14  7:06   ` [tip:perf/core] perf probe: Make --list show " tip-bot for Masami Hiramatsu
  1 sibling, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-13 19:28 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Tue, Jul 12, 2016 at 07:04:54PM +0900, Masami Hiramatsu escreveu:
> From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> 
> Make "perf probe --cache --list" shows only available cached events
> by checking build-id validity.

Something is missing here, I tried following these steps and couldn't
get to the same results, can you retry them at this point in time, i.e.
after applying just the three first patches in this series?

I'm continuing anyway, as I want to check the rest...

- Arnaldo
 
> E.g. without this patch:
>   ----
>   $ ./perf probe --cache --add oldevent=cmd_probe
>   $ make #(to update ./perf)
>   $ ./perf probe --cache --add newevent=cmd_probe
>   $ ./perf probe --cache --list
>   /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
>   probe_perf:newevent=cmd_probe
>   /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1
>   probe_perf:oldevent=cmd_probe
>   ----
> It shows both of old and new events but user can not use old one.
> With this;
>   ----
>   $ ./perf probe --cache -l
>   /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
>   probe_perf:newevent=cmd_probe
>   ----
> This show only new event which is on the existing binary.
> 
> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  Changes in v13:
>   - Instead of the perf-list, apply this change for perf-probe --list
>     because of avoiding to confuse user.
>  Changes in v7:
>   - Validate build-id via sysfs if it is for kallsyms,
>  Changes in v4:
>   - Rename a parameter 'valid' to 'validonly' :)
> ---
>  tools/perf/builtin-probe.c   |    2 +-
>  tools/perf/util/build-id.c   |   33 ++++++++++++++++++++++++++++++++-
>  tools/perf/util/build-id.h   |    2 +-
>  tools/perf/util/probe-file.c |    2 +-
>  4 files changed, 35 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
> index a1a5cd1..de75af5 100644
> --- a/tools/perf/builtin-probe.c
> +++ b/tools/perf/builtin-probe.c
> @@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
>  	struct str_node *nd;
>  	int ret;
>  
> -	bidlist = build_id_cache__list_all();
> +	bidlist = build_id_cache__list_all(false);
>  	if (!bidlist) {
>  		ret = -errno;
>  		pr_debug("Failed to get buildids: %d\n", ret);
> diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
> index e1a1640..8e86a83 100644
> --- a/tools/perf/util/build-id.c
> +++ b/tools/perf/util/build-id.c
> @@ -206,6 +206,31 @@ out:
>  	return ret;
>  }
>  
> +/* Check if the given build_id cache is valid on current running system */
> +static bool build_id_cache__valid_id(char *sbuild_id)
> +{
> +	char real_sbuild_id[SBUILD_ID_SIZE] = "";
> +	char *pathname;
> +	int ret = 0;
> +	bool result = false;
> +
> +	pathname = build_id_cache__origname(sbuild_id);
> +	if (!pathname)
> +		return false;
> +
> +	if (!strcmp(pathname, DSO__NAME_KALLSYMS))
> +		ret = sysfs__sprintf_build_id("/", real_sbuild_id);
> +	else if (pathname[0] == '/')
> +		ret = filename__sprintf_build_id(pathname, real_sbuild_id);
> +	else
> +		ret = -EINVAL;	/* Should we support other special DSO cache? */
> +	if (ret >= 0)
> +		result = (strcmp(sbuild_id, real_sbuild_id) == 0);
> +	free(pathname);
> +
> +	return result;
> +}
> +
>  static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
>  {
>  	return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
> @@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
>  	return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
>  }
>  
> -struct strlist *build_id_cache__list_all(void)
> +struct strlist *build_id_cache__list_all(bool validonly)
>  {
>  	struct strlist *toplist, *linklist = NULL, *bidlist;
>  	struct str_node *nd, *nd2;
>  	char *topdir, *linkdir = NULL;
>  	char sbuild_id[SBUILD_ID_SIZE];
>  
> +	/* for filename__ functions */
> +	if (validonly)
> +		symbol__init(NULL);
> +
>  	/* Open the top-level directory */
>  	if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
>  		return NULL;
> @@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
>  			if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
>  				     nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
>  				goto err_out;
> +			if (validonly && !build_id_cache__valid_id(sbuild_id))
> +				continue;
>  			if (strlist__add(bidlist, sbuild_id) < 0)
>  				goto err_out;
>  		}
> diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
> index b742e27..64e740f 100644
> --- a/tools/perf/util/build-id.h
> +++ b/tools/perf/util/build-id.h
> @@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
>  char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
>  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
>  			       bool is_kallsyms, bool is_vdso);
> -struct strlist *build_id_cache__list_all(void);
> +struct strlist *build_id_cache__list_all(bool validonly);
>  int build_id_cache__list_build_ids(const char *pathname,
>  				   struct strlist **result);
>  bool build_id_cache__cached(const char *sbuild_id);
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index b642d06..b062545 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
>  	pr_debug("list cache with filter: %s\n", buf);
>  	free(buf);
>  
> -	bidlist = build_id_cache__list_all();
> +	bidlist = build_id_cache__list_all(true);
>  	if (!bidlist) {
>  		pr_debug("Failed to get buildids: %d\n", errno);
>  		return -EINVAL;

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events
  2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
@ 2016-07-13 19:36   ` Arnaldo Carvalho de Melo
  2016-07-14  7:07   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-13 19:36 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Tue, Jul 12, 2016 at 07:05:18PM +0900, Masami Hiramatsu escreveu:
> Allo glob wildcard for reusing cached/SDT events. E.g.
> 
>   # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

The example message for this could be improved to also use a wildcard
:-)
 
> This example adds probes for all SDT in libc.
> Note that the SDTs must have been scanned by perf buildid-cache.
> 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  Changes in v12:
>   - Rename strlist__for_each to strlist__for_each_entry.
>  Changes in v10:
>   - Split off bugfix, adding interface, and target search patches.
>   - Do not export clear_probe_trace_events().
>  Changes in v7:
>   - Continue to search caches if a build-id cache has no probe cache.
>   - Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
>   - Fix to add probes correctly when a wildcard matchs both of
>     uprobes and kprobes.
>  Changes in v5.1:
>   - Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
> ---
>  tools/perf/util/probe-event.c |  107 +++++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/probe-file.c  |   38 ++++++++++++---
>  tools/perf/util/probe-file.h  |    3 +
>  3 files changed, 138 insertions(+), 10 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 3642cca..1aeac09 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
>  	ptr = strchr(*arg, ':');
>  	if (ptr) {
>  		*ptr = '\0';
> -		if (!is_c_func_name(*arg))
> +		if (!pev->sdt && !is_c_func_name(*arg))
>  			goto ng_name;
>  		pev->group = strdup(*arg);
>  		if (!pev->group)
> @@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
>  		*arg = ptr + 1;
>  	} else
>  		pev->group = NULL;
> -	if (!is_c_func_name(*arg)) {
> +	if (!pev->sdt && !is_c_func_name(*arg)) {
>  ng_name:
>  		semantic_error("%s is bad for event name -it must "
>  			       "follow C symbol-naming rule.\n", *arg);
> @@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
>  			ret = -ENOMEM;
>  			goto out;
>  		}
> +		tev->uprobes = (tp->module[0] == '/');
>  		p++;
>  	} else
>  		p = argv[1];
> @@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
>  	int ret;
>  
>  	/* If probe_event or trace_event already have the name, reuse it */
> -	if (pev->event)
> +	if (pev->event && !pev->sdt)
>  		event = pev->event;
>  	else if (tev->event)
>  		event = tev->event;
> @@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
>  		else
>  			event = tev->point.realname;
>  	}
> -	if (pev->group)
> +	if (pev->group && !pev->sdt)
>  		group = pev->group;
>  	else if (tev->group)
>  		group = tev->group;
> @@ -2894,6 +2895,100 @@ errout:
>  
>  bool __weak arch__prefers_symtab(void) { return false; }
>  
> +/* Concatinate two arrays */
> +static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
> +{
> +	void *ret;
> +
> +	ret = malloc(sz_a + sz_b);
> +	if (ret) {
> +		memcpy(ret, a, sz_a);
> +		memcpy(ret + sz_a, b, sz_b);
> +	}
> +	return ret;
> +}
> +
> +static int
> +concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
> +			  struct probe_trace_event **tevs2, int ntevs2)
> +{
> +	struct probe_trace_event *new_tevs;
> +	int ret = 0;
> +
> +	if (ntevs == 0) {
> +		*tevs = *tevs2;
> +		*ntevs = ntevs2;
> +		*tevs2 = NULL;
> +		return 0;
> +	}
> +
> +	if (*ntevs + ntevs2 > probe_conf.max_probes)
> +		ret = -E2BIG;
> +	else {
> +		/* Concatinate the array of probe_trace_event */
> +		new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
> +				  *tevs2, ntevs2 * sizeof(**tevs2));
> +		if (!new_tevs)
> +			ret = -ENOMEM;
> +		else {
> +			free(*tevs);
> +			*tevs = new_tevs;
> +			*ntevs += ntevs2;
> +		}
> +	}
> +	if (ret < 0)
> +		clear_probe_trace_events(*tevs2, ntevs2);
> +	zfree(tevs2);
> +
> +	return ret;
> +}
> +
> +/*
> + * Try to find probe_trace_event from given probe caches. Return the number
> + * of cached events found, if an error occurs return the error.
> + */
> +static int find_cached_events(struct perf_probe_event *pev,
> +			      struct probe_trace_event **tevs,
> +			      const char *target)
> +{
> +	struct probe_cache *cache;
> +	struct probe_cache_entry *entry;
> +	struct probe_trace_event *tmp_tevs = NULL;
> +	int ntevs = 0;
> +	int ret = 0;
> +
> +	cache = probe_cache__new(target);
> +	/* Return 0 ("not found") if the target has no probe cache. */
> +	if (!cache)
> +		return 0;
> +
> +	for_each_probe_cache_entry(entry, cache) {
> +		/* Skip the cache entry which has no name */
> +		if (!entry->pev.event || !entry->pev.group)
> +			continue;
> +		if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
> +		    strglobmatch(entry->pev.event, pev->event)) {
> +			ret = probe_cache_entry__get_event(entry, &tmp_tevs);
> +			if (ret > 0)
> +				ret = concat_probe_trace_events(tevs, &ntevs,
> +								&tmp_tevs, ret);
> +			if (ret < 0)
> +				break;
> +		}
> +	}
> +	probe_cache__delete(cache);
> +	if (ret < 0) {
> +		clear_probe_trace_events(*tevs, ntevs);
> +		zfree(tevs);
> +	} else {
> +		ret = ntevs;
> +		if (ntevs > 0 && target && target[0] == '/')
> +			pev->uprobes = true;
> +	}
> +
> +	return ret;
> +}
> +
>  static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
>  					      struct probe_trace_event **tevs)
>  {
> @@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
>  	struct str_node *node;
>  	int ret, i;
>  
> +	if (pev->sdt)
> +		/* For SDT/cached events, we use special search functions */
> +		return find_cached_events(pev, tevs, pev->target);
> +
>  	cache = probe_cache__new(pev->target);
>  	if (!cache)
>  		return 0;
> diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> index 9152ad2..78a84f5 100644
> --- a/tools/perf/util/probe-file.c
> +++ b/tools/perf/util/probe-file.c
> @@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)
>  	return entry;
>  }
>  
> -/* For the kernel probe caches, pass target = NULL */
> +int probe_cache_entry__get_event(struct probe_cache_entry *entry,
> +				 struct probe_trace_event **tevs)
> +{
> +	struct probe_trace_event *tev;
> +	struct str_node *node;
> +	int ret, i;
> +
> +	ret = strlist__nr_entries(entry->tevlist);
> +	if (ret > probe_conf.max_probes)
> +		return -E2BIG;
> +
> +	*tevs = zalloc(ret * sizeof(*tev));
> +	if (!*tevs)
> +		return -ENOMEM;
> +
> +	i = 0;
> +	strlist__for_each_entry(node, entry->tevlist) {
> +		tev = &(*tevs)[i++];
> +		ret = parse_probe_trace_command(node->s, tev);
> +		if (ret < 0)
> +			break;
> +	}
> +	return i;
> +}
> +
> +/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
>  static int probe_cache__open(struct probe_cache *pcache, const char *target)
>  {
>  	char cpath[PATH_MAX];
>  	char sbuildid[SBUILD_ID_SIZE];
>  	char *dir_name = NULL;
> -	bool is_kallsyms = !target;
> +	bool is_kallsyms = false;
>  	int ret, fd;
>  
>  	if (target && build_id_cache__cached(target)) {
> @@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
>  		goto found;
>  	}
>  
> -	if (target)
> -		ret = filename__sprintf_build_id(target, sbuildid);
> -	else {
> +	if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
>  		target = DSO__NAME_KALLSYMS;
> +		is_kallsyms = true;
>  		ret = sysfs__sprintf_build_id("/", sbuildid);
> -	}
> +	} else
> +		ret = filename__sprintf_build_id(target, sbuildid);
> +
>  	if (ret < 0) {
>  		pr_debug("Failed to get build-id from %s.\n", target);
>  		return ret;
> diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
> index d513b34..cafbe1d 100644
> --- a/tools/perf/util/probe-file.h
> +++ b/tools/perf/util/probe-file.h
> @@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
>  				  struct strlist *plist);
>  int probe_file__del_strlist(int fd, struct strlist *namelist);
>  
> +int probe_cache_entry__get_event(struct probe_cache_entry *entry,
> +				 struct probe_trace_event **tevs);
> +
>  struct probe_cache *probe_cache__new(const char *target);
>  int probe_cache__add_entry(struct probe_cache *pcache,
>  			   struct perf_probe_event *pev,

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
@ 2016-07-13 19:50   ` Arnaldo Carvalho de Melo
  2016-07-14  0:07     ` Arnaldo Carvalho de Melo
  2016-07-14  7:08   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  1 sibling, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-13 19:50 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Tue, Jul 12, 2016 at 07:05:37PM +0900, Masami Hiramatsu escreveu:
> Support @BUILDID or @FILE suffix for SDT events. This allows
> perf to add probes on SDTs/pre-cached events on given FILE
> or the file which has given BUILDID (also, this complements
> BUILDID.)
> For example, both gcc and libstdc++ has same SDTs as below.
> If you would like to add a probe on sdt_libstdcxx:catch on gcc,
> you can do as below.

Ok, how to add those entries?

[root@jouet hello_world]# perf probe -x /usr/bin/gcc -a %sdt_gcc:\*
  Error: Failed to add events.
[root@jouet hello_world]# perf probe --verbose -x /usr/bin/gcc -a %sdt_gcc:\*
probe-definition(0): %sdt_gcc:*
0 arguments
symbol:throw file:(null) line:0 offset:0 return:0 lazy:(null)
symbol:rethrow file:(null) line:0 offset:0 return:0 lazy:(null)
symbol:catch file:(null) line:0 offset:0 return:0 lazy:(null)
symbol:unwind file:(null) line:0 offset:0 return:0 lazy:(null)
  Error: Failed to add events. Reason: No such file or directory (Code: -2)
[root@jouet hello_world]# 

Can those messages be improved? What am I missing?
 
>   ----
>   # perf list sdt | tail -n 6
>     sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
>     sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
>     sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
>     sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
>     sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
>     sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
>   # perf probe -a %sdt_libstdcxx:catch@0cc
>   Added new event:
>     sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)
> 
>   You can now use it in all perf tools, such as:
> 
>   	perf record -e sdt_libstdcxx:catch -aR sleep 1
>   ----
> 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  Changes in v12:
>   - Rename strlist__for_each to strlist__for_each_entry.
> ---
>  tools/perf/util/build-id.c    |   43 +++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/build-id.h    |    1 +
>  tools/perf/util/probe-event.c |   17 ++++++++++++++--
>  3 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
> index 8e86a83..e59003e 100644
> --- a/tools/perf/util/build-id.c
> +++ b/tools/perf/util/build-id.c
> @@ -523,6 +523,49 @@ err_out:
>  	goto out_free;
>  }
>  
> +static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < len; i++) {
> +		if (!isxdigit(maybe_sbuild_id[i]))
> +			return false;
> +	}
> +	return true;
> +}
> +
> +/* Return the valid complete build-id */
> +char *build_id_cache__complement(const char *incomplete_sbuild_id)
> +{
> +	struct strlist *bidlist;
> +	struct str_node *nd, *cand = NULL;
> +	char *sbuild_id = NULL;
> +	size_t len = strlen(incomplete_sbuild_id);
> +
> +	if (len >= SBUILD_ID_SIZE ||
> +	    !str_is_build_id(incomplete_sbuild_id, len))
> +		return NULL;
> +
> +	bidlist = build_id_cache__list_all(true);
> +	if (!bidlist)
> +		return NULL;
> +
> +	strlist__for_each_entry(nd, bidlist) {
> +		if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
> +			continue;
> +		if (cand) {	/* Error: There are more than 2 candidates. */
> +			cand = NULL;
> +			break;
> +		}
> +		cand = nd;
> +	}
> +	if (cand)
> +		sbuild_id = strdup(cand->s);
> +	strlist__delete(bidlist);
> +
> +	return sbuild_id;
> +}
> +
>  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
>  			       bool is_kallsyms, bool is_vdso)
>  {
> diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
> index 64e740f..d279906 100644
> --- a/tools/perf/util/build-id.h
> +++ b/tools/perf/util/build-id.h
> @@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
>  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
>  			       bool is_kallsyms, bool is_vdso);
>  struct strlist *build_id_cache__list_all(bool validonly);
> +char *build_id_cache__complement(const char *incomplete_sbuild_id);
>  int build_id_cache__list_build_ids(const char *pathname,
>  				   struct strlist **result);
>  bool build_id_cache__cached(const char *sbuild_id);
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 679aa6b..0dadaa3 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
>  	ptr = strpbrk(arg, ";=@+%");
>  	if (pev->sdt) {
>  		if (ptr) {
> -			semantic_error("%s must contain only an SDT event name.\n", arg);
> -			return -EINVAL;
> +			if (*ptr != '@') {
> +				semantic_error("%s must be an SDT name.\n",
> +					       arg);
> +				return -EINVAL;
> +			}
> +			/* This must be a target file name or build id */
> +			tmp = build_id_cache__complement(ptr + 1);
> +			if (tmp) {
> +				pev->target = build_id_cache__origname(tmp);
> +				free(tmp);
> +			} else
> +				pev->target = strdup(ptr + 1);
> +			if (!pev->target)
> +				return -ENOMEM;
> +			*ptr = '\0';
>  		}
>  		ret = parse_perf_probe_event_name(&arg, pev);
>  		if (ret == 0) {

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-13 19:50   ` Arnaldo Carvalho de Melo
@ 2016-07-14  0:07     ` Arnaldo Carvalho de Melo
  2016-07-14  0:16       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-14  0:07 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Wed, Jul 13, 2016 at 04:50:19PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Tue, Jul 12, 2016 at 07:05:37PM +0900, Masami Hiramatsu escreveu:
> > Support @BUILDID or @FILE suffix for SDT events. This allows
> > perf to add probes on SDTs/pre-cached events on given FILE
> > or the file which has given BUILDID (also, this complements
> > BUILDID.)
> > For example, both gcc and libstdc++ has same SDTs as below.
> > If you would like to add a probe on sdt_libstdcxx:catch on gcc,
> > you can do as below.
> 
> Ok, how to add those entries?
> 
> [root@jouet hello_world]# perf probe -x /usr/bin/gcc -a %sdt_gcc:\*
>   Error: Failed to add events.
> [root@jouet hello_world]# perf probe --verbose -x /usr/bin/gcc -a %sdt_gcc:\*
> probe-definition(0): %sdt_gcc:*
> 0 arguments
> symbol:throw file:(null) line:0 offset:0 return:0 lazy:(null)
> symbol:rethrow file:(null) line:0 offset:0 return:0 lazy:(null)
> symbol:catch file:(null) line:0 offset:0 return:0 lazy:(null)
> symbol:unwind file:(null) line:0 offset:0 return:0 lazy:(null)
>   Error: Failed to add events. Reason: No such file or directory (Code: -2)
> [root@jouet hello_world]# 

So, ok, I managed with:

[root@jouet ~]# perf probe -x /usr/bin/gcc %sdt_libstdcxx:\*
Added new events:
  sdt_libstdcxx:throw  (on %* in /usr/bin/gcc)
  sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc)
  sdt_libstdcxx:catch  (on %* in /usr/bin/gcc)

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

	perf record -e sdt_libstdcxx:catch -aR sleep 1

[root@jouet ~]# 

I then tried to remove the events just created:

# perf probe -d  %sdt_libstdcxx:\*
#

It tells me nothing, cool, probably it removed it all, then I go and
try re-adding them:

[root@jouet ~]# perf probe -x /usr/bin/gcc %sdt_libstdcxx:\*
Error: event "throw" already exists.
 Hint: Remove existing event by 'perf probe -d'
       or force duplicates by 'perf probe -f'
       or set 'force=yes' in BPF source.
  Error: Failed to add events.
[root@jouet ~]#

Huh?

Then I tried like you did above, using 'perf list sdt'

[root@jouet ~]# perf list sdt

List of pre-defined events (to be used in -e):

[root@jouet ~]#

But they appear via 'perf probe -l'

[root@jouet ~]# perf probe -l sdt_libs*
  sdt_libstdcxx:catch  (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc)
  sdt_libstdcxx:rethrow (on d_print_subexpr+280@libsupc++/cp-demangle.c in /usr/bin/gcc)
  sdt_libstdcxx:throw  (on d_print_subexpr+93@libsupc++/cp-demangle.c in /usr/bin/gcc)
[root@jouet ~]#

There is no event, then, guessing, I tried removing that %, since I don't see
it in the 'perf probe -l' output, so it must've been just some distracting
artifact at the time of adding the SDT prove:

[root@jouet ~]# perf probe -d  sdt_libstdcxx:\*
Removed event: sdt_libstdcxx:catch
Removed event: sdt_libstdcxx:rethrow
Removed event: sdt_libstdcxx:throw
[root@jouet ~]# perf probe -l sdt_libs*
[root@jouet ~]#

Ok, now it works, but then if I try having both the gcc and libstdc++ ones, I can't:

[root@jouet ~]# perf probe -x /usr/lib64/libstdc++.so.6 %sdt_libstdcxx:\*
Error: event "catch" already exists.
 Hint: Remove existing event by 'perf probe -d'
       or force duplicates by 'perf probe -f'
       or set 'force=yes' in BPF source.
  Error: Failed to add events.

So I forced it:

[root@jouet ~]# perf probe -f -x /usr/lib64/libstdc++.so.6 %sdt_libstdcxx:\*
Added new events:
  sdt_libstdcxx:catch_1 (on %* in /usr/lib64/libstdc++.so.6.0.22)
  sdt_libstdcxx:throw_1 (on %* in /usr/lib64/libstdc++.so.6.0.22)
  sdt_libstdcxx:rethrow_1 (on %* in /usr/lib64/libstdc++.so.6.0.22)

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

	perf record -e sdt_libstdcxx:rethrow_1 -aR sleep 1

[root@jouet ~]# 

If it will rename it, why require -f? Where is the duplicity?

If I go and re-read all the discussion on the thread that lead to these
patches, I may figure out all those questions, but then, that would be a lot
of info to have in mind :-\

I.e. I would suggest that no -f should be needed, that that "Error: event
"catch" already exists" shouldn't be even emitted, since those will be
different events, i.e. one is named "sdt_libstdcxx:catch" and the other
"sdt_libstdcxx:catch_1"...

But that becomes an usability problem, couldn't it have the basename in it?
I.e.:

sdt_gcc_libstdcxx:catch and sdt_libstdc++:catch?

I'm going to look my inbox for patches I overlook that added 'perf list sdt'...

- Arnaldo

 
> Can those messages be improved? What am I missing?
>  
> >   ----
> >   # perf list sdt | tail -n 6
> >     sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
> >     sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
> >     sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
> >     sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
> >     sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
> >     sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
> >   # perf probe -a %sdt_libstdcxx:catch@0cc
> >   Added new event:
> >     sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> >   	perf record -e sdt_libstdcxx:catch -aR sleep 1
> >   ----
> > 
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > ---
> >  Changes in v12:
> >   - Rename strlist__for_each to strlist__for_each_entry.
> > ---
> >  tools/perf/util/build-id.c    |   43 +++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/build-id.h    |    1 +
> >  tools/perf/util/probe-event.c |   17 ++++++++++++++--
> >  3 files changed, 59 insertions(+), 2 deletions(-)
> > 
> > diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
> > index 8e86a83..e59003e 100644
> > --- a/tools/perf/util/build-id.c
> > +++ b/tools/perf/util/build-id.c
> > @@ -523,6 +523,49 @@ err_out:
> >  	goto out_free;
> >  }
> >  
> > +static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
> > +{
> > +	size_t i;
> > +
> > +	for (i = 0; i < len; i++) {
> > +		if (!isxdigit(maybe_sbuild_id[i]))
> > +			return false;
> > +	}
> > +	return true;
> > +}
> > +
> > +/* Return the valid complete build-id */
> > +char *build_id_cache__complement(const char *incomplete_sbuild_id)
> > +{
> > +	struct strlist *bidlist;
> > +	struct str_node *nd, *cand = NULL;
> > +	char *sbuild_id = NULL;
> > +	size_t len = strlen(incomplete_sbuild_id);
> > +
> > +	if (len >= SBUILD_ID_SIZE ||
> > +	    !str_is_build_id(incomplete_sbuild_id, len))
> > +		return NULL;
> > +
> > +	bidlist = build_id_cache__list_all(true);
> > +	if (!bidlist)
> > +		return NULL;
> > +
> > +	strlist__for_each_entry(nd, bidlist) {
> > +		if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
> > +			continue;
> > +		if (cand) {	/* Error: There are more than 2 candidates. */
> > +			cand = NULL;
> > +			break;
> > +		}
> > +		cand = nd;
> > +	}
> > +	if (cand)
> > +		sbuild_id = strdup(cand->s);
> > +	strlist__delete(bidlist);
> > +
> > +	return sbuild_id;
> > +}
> > +
> >  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
> >  			       bool is_kallsyms, bool is_vdso)
> >  {
> > diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
> > index 64e740f..d279906 100644
> > --- a/tools/perf/util/build-id.h
> > +++ b/tools/perf/util/build-id.h
> > @@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
> >  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
> >  			       bool is_kallsyms, bool is_vdso);
> >  struct strlist *build_id_cache__list_all(bool validonly);
> > +char *build_id_cache__complement(const char *incomplete_sbuild_id);
> >  int build_id_cache__list_build_ids(const char *pathname,
> >  				   struct strlist **result);
> >  bool build_id_cache__cached(const char *sbuild_id);
> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> > index 679aa6b..0dadaa3 100644
> > --- a/tools/perf/util/probe-event.c
> > +++ b/tools/perf/util/probe-event.c
> > @@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> >  	ptr = strpbrk(arg, ";=@+%");
> >  	if (pev->sdt) {
> >  		if (ptr) {
> > -			semantic_error("%s must contain only an SDT event name.\n", arg);
> > -			return -EINVAL;
> > +			if (*ptr != '@') {
> > +				semantic_error("%s must be an SDT name.\n",
> > +					       arg);
> > +				return -EINVAL;
> > +			}
> > +			/* This must be a target file name or build id */
> > +			tmp = build_id_cache__complement(ptr + 1);
> > +			if (tmp) {
> > +				pev->target = build_id_cache__origname(tmp);
> > +				free(tmp);
> > +			} else
> > +				pev->target = strdup(ptr + 1);
> > +			if (!pev->target)
> > +				return -ENOMEM;
> > +			*ptr = '\0';
> >  		}
> >  		ret = parse_perf_probe_event_name(&arg, pev);
> >  		if (ret == 0) {

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-14  0:07     ` Arnaldo Carvalho de Melo
@ 2016-07-14  0:16       ` Arnaldo Carvalho de Melo
  2016-07-14  0:20         ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-14  0:16 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
> I'm going to look my inbox for patches I overlook that added 'perf list sdt'...

So it is here:

->  976   T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events

June, 24, you forgot to rebase it for this new cset series, I'm doing
that now.

- Arnaldo

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-14  0:16       ` Arnaldo Carvalho de Melo
@ 2016-07-14  0:20         ` Arnaldo Carvalho de Melo
  2016-07-14 15:32           ` Masami Hiramatsu
  0 siblings, 1 reply; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-14  0:20 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Wed, Jul 13, 2016 at 09:16:32PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
> > I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
> 
> So it is here:
> 
> ->  976   T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events
> 
> June, 24, you forgot to rebase it for this new cset series, I'm doing
> that now.

Ok, now it works:


[root@jouet ~]# perf list sdt

List of pre-defined events (to be used in -e):

  sdt_libc:lll_lock_wait_private                     [SDT event]
  sdt_libc:longjmp                                   [SDT event]
  sdt_libc:longjmp_target                            [SDT event]
  sdt_libc:memory_arena_new                          [SDT event]
  sdt_libc:memory_arena_retry                        [SDT event]
  sdt_libc:memory_arena_reuse                        [SDT event]
  sdt_libc:memory_arena_reuse_free_list              [SDT event]
  sdt_libc:memory_arena_reuse_wait                   [SDT event]
  sdt_libc:memory_calloc_retry                       [SDT event]
  sdt_libc:memory_heap_free                          [SDT event]
  sdt_libc:memory_heap_less                          [SDT event]
  sdt_libc:memory_heap_more                          [SDT event]
  sdt_libc:memory_heap_new                           [SDT event]
  sdt_libc:memory_malloc_retry                       [SDT event]
  sdt_libc:memory_mallopt                            [SDT event]
  sdt_libc:memory_mallopt_arena_max                  [SDT event]
  sdt_libc:memory_mallopt_arena_test                 [SDT event]
  sdt_libc:memory_mallopt_check_action               [SDT event]
  sdt_libc:memory_mallopt_free_dyn_thresholds        [SDT event]
  sdt_libc:memory_mallopt_mmap_max                   [SDT event]
  sdt_libc:memory_mallopt_mmap_threshold             [SDT event]
  sdt_libc:memory_mallopt_mxfast                     [SDT event]
  sdt_libc:memory_mallopt_perturb                    [SDT event]
  sdt_libc:memory_mallopt_top_pad                    [SDT event]
  sdt_libc:memory_mallopt_trim_threshold             [SDT event]
  sdt_libc:memory_memalign_retry                     [SDT event]
  sdt_libc:memory_realloc_retry                      [SDT event]
  sdt_libc:memory_sbrk_less                          [SDT event]
  sdt_libc:memory_sbrk_more                          [SDT event]
  sdt_libc:setjmp                                    [SDT event]
  sdt_libgcc:unwind                                  [SDT event]
  sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
  sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
  sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6)   [SDT event]
  sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
  sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
  sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
[root@jouet ~]#

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 00/10] perf-probe --cache and SDT support
  2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
                   ` (9 preceding siblings ...)
  2016-07-12 10:06 ` [PATCH perf/core 10/10] perf-test: Add a test case for SDT event Masami Hiramatsu
@ 2016-07-14  1:35 ` Arnaldo Carvalho de Melo
  10 siblings, 0 replies; 30+ messages in thread
From: Arnaldo Carvalho de Melo @ 2016-07-14  1:35 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

Em Tue, Jul 12, 2016 at 07:04:23PM +0900, Masami Hiramatsu escreveu:
> Hi,
> 
> Here is the 14th version of the patchset for probe-cache and 
> initial SDT support.
> 
> Here is the previous v13: https://lkml.org/lkml/2016/7/1/133

Ok, applied it and also one that you missed in this set, the one adding
'perf list sdt', that I rebased and tested,

Thanks,

- Arnaldo
 
> This version includes patches which not merged yet. This also
> adds a bugfix;
>  - [1/10] Resend the bugfix patch which was sent 4th July.
>           (https://lkml.org/lkml/2016/7/3/217)
> 
> Thank you,
> 
> ---
> 
> Masami Hiramatsu (10):
>       [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params
>       perf probe: Accept %sdt and %cached event name
>       perf-probe: Make --list shows only available cached events
>       perf: probe-cache: Add for_each_probe_cache_entry() wrapper
>       perf probe: Allow wildcard for cached events
>       perf probe: Search SDT/cached event from all probe caches
>       perf probe: Support @BUILDID or @FILE suffix for SDT events
>       perf probe: Support a special SDT probe format
>       perf build: Add sdt feature detection
>       perf-test: Add a test case for SDT event
> 
> 
>  tools/perf/Documentation/perf-probe.txt |   11 +
>  tools/perf/Makefile.perf                |    3 
>  tools/perf/builtin-probe.c              |    2 
>  tools/perf/config/Makefile              |   10 +
>  tools/perf/tests/Build                  |    1 
>  tools/perf/tests/builtin-test.c         |    4 
>  tools/perf/tests/make                   |    3 
>  tools/perf/tests/sdt.c                  |  115 ++++++++++++
>  tools/perf/tests/tests.h                |    1 
>  tools/perf/util/build-id.c              |   76 ++++++++
>  tools/perf/util/build-id.h              |    3 
>  tools/perf/util/probe-event.c           |  309 +++++++++++++++++++++++++++----
>  tools/perf/util/probe-event.h           |    1 
>  tools/perf/util/probe-file.c            |   57 +++++-
>  tools/perf/util/probe-file.h            |    5 +
>  15 files changed, 542 insertions(+), 59 deletions(-)
>  create mode 100644 tools/perf/tests/sdt.c
> 
> --
> Masami Hiramatsu

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events
  2016-07-13 19:28   ` Arnaldo Carvalho de Melo
@ 2016-07-14  6:13     ` Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-14  6:13 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

On Wed, 13 Jul 2016 16:28:37 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Em Tue, Jul 12, 2016 at 07:04:54PM +0900, Masami Hiramatsu escreveu:
> > From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> > 
> > Make "perf probe --cache --list" shows only available cached events
> > by checking build-id validity.
> 
> Something is missing here, I tried following these steps and couldn't
> get to the same results, can you retry them at this point in time, i.e.
> after applying just the three first patches in this series?

Sorry, I missed some steps, see below;

> 
> I'm continuing anyway, as I want to check the rest...
> 
> - Arnaldo
>  
> > E.g. without this patch:
> >   ----
> >   $ ./perf probe --cache --add oldevent=cmd_probe

Here, you have to change perf source code so that perf binary
build-id is changed.

And make a copy of perf (as perf.old) so that you can get build-id
of both binary.

> >   $ make #(to update ./perf)

So, prese ensure that the new perf binary has different build-id.

If both binary has same build-id, you'll see just one cache.

Thank you,

> >   $ ./perf probe --cache --add newevent=cmd_probe
> >   $ ./perf probe --cache --list
> >   /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
> >   probe_perf:newevent=cmd_probe
> >   /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1
> >   probe_perf:oldevent=cmd_probe
> >   ----
> > It shows both of old and new events but user can not use old one.
> > With this;
> >   ----
> >   $ ./perf probe --cache -l
> >   /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
> >   probe_perf:newevent=cmd_probe
> >   ----
> > This show only new event which is on the existing binary.
> > 
> > Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > ---
> >  Changes in v13:
> >   - Instead of the perf-list, apply this change for perf-probe --list
> >     because of avoiding to confuse user.
> >  Changes in v7:
> >   - Validate build-id via sysfs if it is for kallsyms,
> >  Changes in v4:
> >   - Rename a parameter 'valid' to 'validonly' :)
> > ---
> >  tools/perf/builtin-probe.c   |    2 +-
> >  tools/perf/util/build-id.c   |   33 ++++++++++++++++++++++++++++++++-
> >  tools/perf/util/build-id.h   |    2 +-
> >  tools/perf/util/probe-file.c |    2 +-
> >  4 files changed, 35 insertions(+), 4 deletions(-)
> > 
> > diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
> > index a1a5cd1..de75af5 100644
> > --- a/tools/perf/builtin-probe.c
> > +++ b/tools/perf/builtin-probe.c
> > @@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
> >  	struct str_node *nd;
> >  	int ret;
> >  
> > -	bidlist = build_id_cache__list_all();
> > +	bidlist = build_id_cache__list_all(false);
> >  	if (!bidlist) {
> >  		ret = -errno;
> >  		pr_debug("Failed to get buildids: %d\n", ret);
> > diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
> > index e1a1640..8e86a83 100644
> > --- a/tools/perf/util/build-id.c
> > +++ b/tools/perf/util/build-id.c
> > @@ -206,6 +206,31 @@ out:
> >  	return ret;
> >  }
> >  
> > +/* Check if the given build_id cache is valid on current running system */
> > +static bool build_id_cache__valid_id(char *sbuild_id)
> > +{
> > +	char real_sbuild_id[SBUILD_ID_SIZE] = "";
> > +	char *pathname;
> > +	int ret = 0;
> > +	bool result = false;
> > +
> > +	pathname = build_id_cache__origname(sbuild_id);
> > +	if (!pathname)
> > +		return false;
> > +
> > +	if (!strcmp(pathname, DSO__NAME_KALLSYMS))
> > +		ret = sysfs__sprintf_build_id("/", real_sbuild_id);
> > +	else if (pathname[0] == '/')
> > +		ret = filename__sprintf_build_id(pathname, real_sbuild_id);
> > +	else
> > +		ret = -EINVAL;	/* Should we support other special DSO cache? */
> > +	if (ret >= 0)
> > +		result = (strcmp(sbuild_id, real_sbuild_id) == 0);
> > +	free(pathname);
> > +
> > +	return result;
> > +}
> > +
> >  static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
> >  {
> >  	return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
> > @@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
> >  	return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
> >  }
> >  
> > -struct strlist *build_id_cache__list_all(void)
> > +struct strlist *build_id_cache__list_all(bool validonly)
> >  {
> >  	struct strlist *toplist, *linklist = NULL, *bidlist;
> >  	struct str_node *nd, *nd2;
> >  	char *topdir, *linkdir = NULL;
> >  	char sbuild_id[SBUILD_ID_SIZE];
> >  
> > +	/* for filename__ functions */
> > +	if (validonly)
> > +		symbol__init(NULL);
> > +
> >  	/* Open the top-level directory */
> >  	if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
> >  		return NULL;
> > @@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
> >  			if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
> >  				     nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
> >  				goto err_out;
> > +			if (validonly && !build_id_cache__valid_id(sbuild_id))
> > +				continue;
> >  			if (strlist__add(bidlist, sbuild_id) < 0)
> >  				goto err_out;
> >  		}
> > diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
> > index b742e27..64e740f 100644
> > --- a/tools/perf/util/build-id.h
> > +++ b/tools/perf/util/build-id.h
> > @@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
> >  char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
> >  char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
> >  			       bool is_kallsyms, bool is_vdso);
> > -struct strlist *build_id_cache__list_all(void);
> > +struct strlist *build_id_cache__list_all(bool validonly);
> >  int build_id_cache__list_build_ids(const char *pathname,
> >  				   struct strlist **result);
> >  bool build_id_cache__cached(const char *sbuild_id);
> > diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
> > index b642d06..b062545 100644
> > --- a/tools/perf/util/probe-file.c
> > +++ b/tools/perf/util/probe-file.c
> > @@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
> >  	pr_debug("list cache with filter: %s\n", buf);
> >  	free(buf);
> >  
> > -	bidlist = build_id_cache__list_all();
> > +	bidlist = build_id_cache__list_all(true);
> >  	if (!bidlist) {
> >  		pr_debug("Failed to get buildids: %d\n", errno);
> >  		return -EINVAL;


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Fix to show correct error message for $vars and $params
  2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
@ 2016-07-14  7:05   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: peterz, mingo, namhyung, tglx, linux-kernel, ananth,
	brendan.d.gregg, mhiramat, hpa, acme, acme, hemant

Commit-ID:  f6eb0518f325ef0d6557fbef5c7ebe48a81e74db
Gitweb:     http://git.kernel.org/tip/f6eb0518f325ef0d6557fbef5c7ebe48a81e74db
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:04:34 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:04 -0300

perf probe: Fix to show correct error message for $vars and $params

Fix to show correct error messages for $vars and $params because
those special variables requires debug information to find the
real variables or function parameters.

E.g. without this fix;
  ----
  # perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
  Failed to write event: Invalid argument
  Please upgrade your kernel to at least 3.14 to have access to feature $params
    Error: Failed to add events.
  ----

Perf ends up with an error, but the message is not correct.  With this
fix, perf shows correct error message as below.

  ----
  # perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
  The /usr/lib64/libc-2.23.so file has no debug information.
  Rebuild with -g, or install an appropriate debuginfo package.
    Error: Failed to add events.
  ----

Reported-and-Tested-by: Arnaldo Carvalho de Melo <acme@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831787438.17065.6152436996780110699.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 2b222a7..fef9768 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1547,7 +1547,9 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
 		return true;
 
 	for (i = 0; i < pev->nargs; i++)
-		if (is_c_varname(pev->args[i].var))
+		if (is_c_varname(pev->args[i].var) ||
+		    !strcmp(pev->args[i].var, "$params") ||
+		    !strcmp(pev->args[i].var, "$vars"))
 			return true;
 
 	return false;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Accept %sdt and %cached event name
  2016-07-12 10:04 ` [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
@ 2016-07-14  7:05   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: ananth, linux-kernel, namhyung, brendan.d.gregg, hpa,
	masami.hiramatsu.pt, acme, peterz, tglx, mhiramat, mingo, hemant

Commit-ID:  36a009fe07bdecd201335f982babb8af34b603e2
Gitweb:     http://git.kernel.org/tip/36a009fe07bdecd201335f982babb8af34b603e2
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Tue, 12 Jul 2016 19:04:43 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:05 -0300

perf probe: Accept %sdt and %cached event name

To improve usability, support %[PROVIDER:]SDTEVENT format to add new
probes on SDT and cached events.

e.g.
  ----
  # perf probe -x /lib/libc-2.17.so  %lll_lock_wait_private
  Added new event:
    sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in /usr/lib/libc-2.17.so)

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

          perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1

  # perf probe -l | more
    sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21 in /usr/lib/libc-2.17.so)
  ----

Note that this is not only for SDT events, but also normal
events with event-name.

e.g. define "myevent" on cache (-n doesn't add the real probe)
  ----
  # perf probe -x ./perf --cache -n --add 'myevent=dso__load $params'
  ----
  Reuse the "myevent" from cache as below.
  ----
  # perf probe -x ./perf %myevent
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831788372.17065.3645054540325909346.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |  9 +++-
 tools/perf/util/probe-event.c           | 82 +++++++++++++++++++++++----------
 tools/perf/util/probe-event.h           |  1 +
 tools/perf/util/probe-file.c            |  9 ++++
 4 files changed, 76 insertions(+), 25 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 7a258e9..39e3870 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,6 +151,8 @@ Probe points are defined by following syntax.
     3) Define event based on source file with lazy pattern
      [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
+    4) Pre-defined SDT events or cached event with name
+     %[PROVIDER:]SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
 Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
@@ -158,6 +160,11 @@ modules.
 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition.  In addition, '@SRC' specifies a source file which has that function.
 It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
+'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name.
+Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events.
+
+For details of the SDT, see below.
+https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
 
 PROBE ARGUMENT
 --------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
 
 SEE ALSO
 --------
-linkperf:perf-trace[1], linkperf:perf-record[1]
+linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index fef9768..85f25d4 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1197,6 +1197,34 @@ err:
 	return err;
 }
 
+static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
+{
+	char *ptr;
+
+	ptr = strchr(*arg, ':');
+	if (ptr) {
+		*ptr = '\0';
+		if (!is_c_func_name(*arg))
+			goto ng_name;
+		pev->group = strdup(*arg);
+		if (!pev->group)
+			return -ENOMEM;
+		*arg = ptr + 1;
+	} else
+		pev->group = NULL;
+	if (!is_c_func_name(*arg)) {
+ng_name:
+		semantic_error("%s is bad for event name -it must "
+			       "follow C symbol-naming rule.\n", *arg);
+		return -EINVAL;
+	}
+	pev->event = strdup(*arg);
+	if (pev->event == NULL)
+		return -ENOMEM;
+
+	return 0;
+}
+
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
@@ -1204,38 +1232,43 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	char *ptr, *tmp;
 	char c, nc = 0;
 	bool file_spec = false;
+	int ret;
+
 	/*
 	 * <Syntax>
 	 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
 	 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
+	 * perf probe %[GRP:]SDT_EVENT
 	 */
 	if (!arg)
 		return -EINVAL;
 
+	if (arg[0] == '%') {
+		pev->sdt = true;
+		arg++;
+	}
+
 	ptr = strpbrk(arg, ";=@+%");
-	if (ptr && *ptr == '=') {	/* Event name */
-		*ptr = '\0';
-		tmp = ptr + 1;
-		ptr = strchr(arg, ':');
+	if (pev->sdt) {
 		if (ptr) {
-			*ptr = '\0';
-			if (!is_c_func_name(arg))
-				goto not_fname;
-			pev->group = strdup(arg);
-			if (!pev->group)
-				return -ENOMEM;
-			arg = ptr + 1;
-		} else
-			pev->group = NULL;
-		if (!is_c_func_name(arg)) {
-not_fname:
-			semantic_error("%s is bad for event name -it must "
-				       "follow C symbol-naming rule.\n", arg);
+			semantic_error("%s must contain only an SDT event name.\n", arg);
 			return -EINVAL;
 		}
-		pev->event = strdup(arg);
-		if (pev->event == NULL)
-			return -ENOMEM;
+		ret = parse_perf_probe_event_name(&arg, pev);
+		if (ret == 0) {
+			if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
+				ret = -errno;
+		}
+		return ret;
+	}
+
+	if (ptr && *ptr == '=') {	/* Event name */
+		*ptr = '\0';
+		tmp = ptr + 1;
+		ret = parse_perf_probe_event_name(&arg, pev);
+		if (ret < 0)
+			return ret;
+
 		arg = tmp;
 	}
 
@@ -2876,7 +2909,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 
 	entry = probe_cache__find(cache, pev);
 	if (!entry) {
-		ret = 0;
+		/* SDT must be in the cache */
+		ret = pev->sdt ? -ENOENT : 0;
 		goto out;
 	}
 
@@ -2915,7 +2949,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 {
 	int ret;
 
-	if (!pev->group) {
+	if (!pev->group && !pev->sdt) {
 		/* Set group name if not given */
 		if (!pev->uprobes) {
 			pev->group = strdup(PERFPROBE_GROUP);
@@ -2934,8 +2968,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 
 	/* At first, we need to lookup cache entry */
 	ret = find_probe_trace_events_from_cache(pev, tevs);
-	if (ret > 0)
-		return ret;	/* Found in probe cache */
+	if (ret > 0 || pev->sdt)	/* SDT can be found only in the cache */
+		return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
 
 	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
 		ret = find_probe_trace_events_from_map(pev, tevs);
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 432b690..e18ea9f 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -85,6 +85,7 @@ struct perf_probe_event {
 	char			*group;	/* Group name */
 	struct perf_probe_point	point;	/* Probe point */
 	int			nargs;	/* Number of arguments */
+	bool			sdt;	/* SDT/cached event flag */
 	bool			uprobes;	/* Uprobe event flag */
 	char			*target;	/* Target binary */
 	struct perf_probe_arg	*args;	/* Arguments */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index e705a74..fc16b17 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -547,6 +547,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 		return NULL;
 
 	list_for_each_entry(entry, &pcache->entries, node) {
+		if (pev->sdt) {
+			if (entry->pev.event &&
+			    streql(entry->pev.event, pev->event) &&
+			    (!pev->group ||
+			     streql(entry->pev.group, pev->group)))
+				goto found;
+
+			continue;
+		}
 		/* Hit if same event name or same command-string */
 		if ((pev->event &&
 		     (streql(entry->pev.group, pev->group) &&

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Make --list show only available cached events
  2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
  2016-07-13 19:28   ` Arnaldo Carvalho de Melo
@ 2016-07-14  7:06   ` tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hemant, hpa, peterz, mingo, masami.hiramatsu.pt, acme, ananth,
	tglx, mhiramat, linux-kernel, namhyung, brendan.d.gregg

Commit-ID:  c3492a3a4e58117f18d96125e67b0bed7c4231e1
Gitweb:     http://git.kernel.org/tip/c3492a3a4e58117f18d96125e67b0bed7c4231e1
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Tue, 12 Jul 2016 19:04:54 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:05 -0300

perf probe: Make --list show only available cached events

Make "perf probe --cache --list" show only available cached events by
checking build-id validity.

E.g. without this patch:
  ----
  $ ./perf probe --cache --add oldevent=cmd_probe
  $ make #(to update ./perf)
  $ ./perf probe --cache --add newevent=cmd_probe
  $ ./perf probe --cache --list
  /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
  probe_perf:newevent=cmd_probe
  /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1
  probe_perf:oldevent=cmd_probe
  ----
It shows both of old and new events but user can not use old one.
With this;
  ----
  $ ./perf probe --cache -l
  /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69
  probe_perf:newevent=cmd_probe
  ----

This shows only new events which are on the existing binary.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831789417.17065.17896487479879669610.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-probe.c   |  2 +-
 tools/perf/util/build-id.c   | 33 ++++++++++++++++++++++++++++++++-
 tools/perf/util/build-id.h   |  2 +-
 tools/perf/util/probe-file.c |  2 +-
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index c6d890a..ee5b421 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)
 	struct str_node *nd;
 	int ret;
 
-	bidlist = build_id_cache__list_all();
+	bidlist = build_id_cache__list_all(false);
 	if (!bidlist) {
 		ret = -errno;
 		pr_debug("Failed to get buildids: %d\n", ret);
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 1e504e4..36b4279 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -206,6 +206,31 @@ out:
 	return ret;
 }
 
+/* Check if the given build_id cache is valid on current running system */
+static bool build_id_cache__valid_id(char *sbuild_id)
+{
+	char real_sbuild_id[SBUILD_ID_SIZE] = "";
+	char *pathname;
+	int ret = 0;
+	bool result = false;
+
+	pathname = build_id_cache__origname(sbuild_id);
+	if (!pathname)
+		return false;
+
+	if (!strcmp(pathname, DSO__NAME_KALLSYMS))
+		ret = sysfs__sprintf_build_id("/", real_sbuild_id);
+	else if (pathname[0] == '/')
+		ret = filename__sprintf_build_id(pathname, real_sbuild_id);
+	else
+		ret = -EINVAL;	/* Should we support other special DSO cache? */
+	if (ret >= 0)
+		result = (strcmp(sbuild_id, real_sbuild_id) == 0);
+	free(pathname);
+
+	return result;
+}
+
 static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
 {
 	return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,
 	return (i == SBUILD_ID_SIZE - 3) && (d->d_name[i] == '\0');
 }
 
-struct strlist *build_id_cache__list_all(void)
+struct strlist *build_id_cache__list_all(bool validonly)
 {
 	struct strlist *toplist, *linklist = NULL, *bidlist;
 	struct str_node *nd, *nd2;
 	char *topdir, *linkdir = NULL;
 	char sbuild_id[SBUILD_ID_SIZE];
 
+	/* for filename__ functions */
+	if (validonly)
+		symbol__init(NULL);
+
 	/* Open the top-level directory */
 	if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
 		return NULL;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)
 			if (snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
 				     nd->s, nd2->s) != SBUILD_ID_SIZE - 1)
 				goto err_out;
+			if (validonly && !build_id_cache__valid_id(sbuild_id))
+				continue;
 			if (strlist__add(bidlist, sbuild_id) < 0)
 				goto err_out;
 		}
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index b742e27..64e740f 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);
 char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso);
-struct strlist *build_id_cache__list_all(void);
+struct strlist *build_id_cache__list_all(bool validonly);
 int build_id_cache__list_build_ids(const char *pathname,
 				   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index fc16b17..a5059dc 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -808,7 +808,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)
 	pr_debug("list cache with filter: %s\n", buf);
 	free(buf);
 
-	bidlist = build_id_cache__list_all();
+	bidlist = build_id_cache__list_all(true);
 	if (!bidlist) {
 		pr_debug("Failed to get buildids: %d\n", errno);
 		return -EINVAL;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe-cache: Add for_each_probe_cache_entry() wrapper
  2016-07-12 10:05 ` [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
@ 2016-07-14  7:06   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:06 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: brendan.d.gregg, hpa, peterz, mingo, mhiramat, ananth, tglx,
	acme, linux-kernel, namhyung, hemant

Commit-ID:  05bf2c8a2a819132b4a8f35d4315ff22e8e84a20
Gitweb:     http://git.kernel.org/tip/05bf2c8a2a819132b4a8f35d4315ff22e8e84a20
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:04 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:06 -0300

perf probe-cache: Add for_each_probe_cache_entry() wrapper

Add for_each_probe_cache_entry() wrapper macro for hiding list in
probe_cache.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831790386.17065.15082256697569419710.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-file.c | 8 ++++----
 tools/perf/util/probe-file.h | 2 ++
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index a5059dc..abfb05c 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
 	if (!cmd)
 		return NULL;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		if (pev->sdt) {
 			if (entry->pev.event &&
 			    streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache,
 {
 	struct probe_cache_entry *entry = NULL;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		/* Hit if same event name or same command-string */
 		if (streql(entry->pev.group, group) &&
 		    streql(entry->pev.event, event))
@@ -748,7 +748,7 @@ int probe_cache__commit(struct probe_cache *pcache)
 	if (ret < 0)
 		goto out;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		ret = probe_cache_entry__write(entry, pcache->fd);
 		pr_debug("Cache committed: %d\n", ret);
 		if (ret < 0)
@@ -790,7 +790,7 @@ static int probe_cache__show_entries(struct probe_cache *pcache,
 {
 	struct probe_cache_entry *entry;
 
-	list_for_each_entry(entry, &pcache->entries, node) {
+	for_each_probe_cache_entry(entry, pcache) {
 		if (probe_cache_entry__compare(entry, filter))
 			printf("%s\n", entry->spev);
 	}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index ddf5ae2..d513b34 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -21,6 +21,8 @@ struct probe_cache {
 
 #define PF_FL_UPROBE	1
 #define PF_FL_RW	2
+#define for_each_probe_cache_entry(entry, pcache) \
+	list_for_each_entry(entry, &pcache->entries, node)
 
 int probe_file__open(int flag);
 int probe_file__open_both(int *kfd, int *ufd, int flag);

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Allow wildcard for cached events
  2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
  2016-07-13 19:36   ` Arnaldo Carvalho de Melo
@ 2016-07-14  7:07   ` tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: tglx, mhiramat, mingo, acme, ananth, brendan.d.gregg, namhyung,
	hpa, peterz, hemant, linux-kernel

Commit-ID:  42bba263eb58800b6239a0cb35ac17fd29379277
Gitweb:     http://git.kernel.org/tip/42bba263eb58800b6239a0cb35ac17fd29379277
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:18 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:07 -0300

perf probe: Allow wildcard for cached events

Allo glob wildcard for reusing cached/SDT events. E.g.

  # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.

Committer note:

Using it to check what of those SDT probes would take place when doing
a cargo run (rust):

  # trace --no-sys --event sdt_libc:* cargo run
     0.000 sdt_libc:setjmp:(7f326b69c4d1))
    28.423 sdt_libc:setjmp:(7f4b0a5364d1))
    29.000 sdt_libc:setjmp:(7f4b0a5364d1))
    88.597 sdt_libc:setjmp:(7fc01fd414d1))
    89.220 sdt_libc:setjmp:(7fc01fd414d1))
    95.501 sdt_libc:setjmp:(7f326b69c4d1))
     Running `target/debug/hello_world`
    97.110 sdt_libc:setjmp:(7f95e09234d1))
  Hello, world!
  #

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831791813.17065.17846564230840594888.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 107 ++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/probe-file.c  |  38 ++++++++++++---
 tools/perf/util/probe-file.h  |   3 ++
 3 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 85f25d4..7b96e68 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
 	ptr = strchr(*arg, ':');
 	if (ptr) {
 		*ptr = '\0';
-		if (!is_c_func_name(*arg))
+		if (!pev->sdt && !is_c_func_name(*arg))
 			goto ng_name;
 		pev->group = strdup(*arg);
 		if (!pev->group)
@@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
 		*arg = ptr + 1;
 	} else
 		pev->group = NULL;
-	if (!is_c_func_name(*arg)) {
+	if (!pev->sdt && !is_c_func_name(*arg)) {
 ng_name:
 		semantic_error("%s is bad for event name -it must "
 			       "follow C symbol-naming rule.\n", *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev)
 			ret = -ENOMEM;
 			goto out;
 		}
+		tev->uprobes = (tp->module[0] == '/');
 		p++;
 	} else
 		p = argv[1];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 	int ret;
 
 	/* If probe_event or trace_event already have the name, reuse it */
-	if (pev->event)
+	if (pev->event && !pev->sdt)
 		event = pev->event;
 	else if (tev->event)
 		event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 		else
 			event = tev->point.realname;
 	}
-	if (pev->group)
+	if (pev->group && !pev->sdt)
 		group = pev->group;
 	else if (tev->group)
 		group = tev->group;
@@ -2894,6 +2895,100 @@ errout:
 
 bool __weak arch__prefers_symtab(void) { return false; }
 
+/* Concatinate two arrays */
+static void *memcat(void *a, size_t sz_a, void *b, size_t sz_b)
+{
+	void *ret;
+
+	ret = malloc(sz_a + sz_b);
+	if (ret) {
+		memcpy(ret, a, sz_a);
+		memcpy(ret + sz_a, b, sz_b);
+	}
+	return ret;
+}
+
+static int
+concat_probe_trace_events(struct probe_trace_event **tevs, int *ntevs,
+			  struct probe_trace_event **tevs2, int ntevs2)
+{
+	struct probe_trace_event *new_tevs;
+	int ret = 0;
+
+	if (ntevs == 0) {
+		*tevs = *tevs2;
+		*ntevs = ntevs2;
+		*tevs2 = NULL;
+		return 0;
+	}
+
+	if (*ntevs + ntevs2 > probe_conf.max_probes)
+		ret = -E2BIG;
+	else {
+		/* Concatinate the array of probe_trace_event */
+		new_tevs = memcat(*tevs, (*ntevs) * sizeof(**tevs),
+				  *tevs2, ntevs2 * sizeof(**tevs2));
+		if (!new_tevs)
+			ret = -ENOMEM;
+		else {
+			free(*tevs);
+			*tevs = new_tevs;
+			*ntevs += ntevs2;
+		}
+	}
+	if (ret < 0)
+		clear_probe_trace_events(*tevs2, ntevs2);
+	zfree(tevs2);
+
+	return ret;
+}
+
+/*
+ * Try to find probe_trace_event from given probe caches. Return the number
+ * of cached events found, if an error occurs return the error.
+ */
+static int find_cached_events(struct perf_probe_event *pev,
+			      struct probe_trace_event **tevs,
+			      const char *target)
+{
+	struct probe_cache *cache;
+	struct probe_cache_entry *entry;
+	struct probe_trace_event *tmp_tevs = NULL;
+	int ntevs = 0;
+	int ret = 0;
+
+	cache = probe_cache__new(target);
+	/* Return 0 ("not found") if the target has no probe cache. */
+	if (!cache)
+		return 0;
+
+	for_each_probe_cache_entry(entry, cache) {
+		/* Skip the cache entry which has no name */
+		if (!entry->pev.event || !entry->pev.group)
+			continue;
+		if ((!pev->group || strglobmatch(entry->pev.group, pev->group)) &&
+		    strglobmatch(entry->pev.event, pev->event)) {
+			ret = probe_cache_entry__get_event(entry, &tmp_tevs);
+			if (ret > 0)
+				ret = concat_probe_trace_events(tevs, &ntevs,
+								&tmp_tevs, ret);
+			if (ret < 0)
+				break;
+		}
+	}
+	probe_cache__delete(cache);
+	if (ret < 0) {
+		clear_probe_trace_events(*tevs, ntevs);
+		zfree(tevs);
+	} else {
+		ret = ntevs;
+		if (ntevs > 0 && target && target[0] == '/')
+			pev->uprobes = true;
+	}
+
+	return ret;
+}
+
 static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 					      struct probe_trace_event **tevs)
 {
@@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 	struct str_node *node;
 	int ret, i;
 
+	if (pev->sdt)
+		/* For SDT/cached events, we use special search functions */
+		return find_cached_events(pev, tevs, pev->target);
+
 	cache = probe_cache__new(pev->target);
 	if (!cache)
 		return 0;
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index abfb05c..9aed9c3 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)
 	return entry;
 }
 
-/* For the kernel probe caches, pass target = NULL */
+int probe_cache_entry__get_event(struct probe_cache_entry *entry,
+				 struct probe_trace_event **tevs)
+{
+	struct probe_trace_event *tev;
+	struct str_node *node;
+	int ret, i;
+
+	ret = strlist__nr_entries(entry->tevlist);
+	if (ret > probe_conf.max_probes)
+		return -E2BIG;
+
+	*tevs = zalloc(ret * sizeof(*tev));
+	if (!*tevs)
+		return -ENOMEM;
+
+	i = 0;
+	strlist__for_each_entry(node, entry->tevlist) {
+		tev = &(*tevs)[i++];
+		ret = parse_probe_trace_command(node->s, tev);
+		if (ret < 0)
+			break;
+	}
+	return i;
+}
+
+/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */
 static int probe_cache__open(struct probe_cache *pcache, const char *target)
 {
 	char cpath[PATH_MAX];
 	char sbuildid[SBUILD_ID_SIZE];
 	char *dir_name = NULL;
-	bool is_kallsyms = !target;
+	bool is_kallsyms = false;
 	int ret, fd;
 
 	if (target && build_id_cache__cached(target)) {
@@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
 		goto found;
 	}
 
-	if (target)
-		ret = filename__sprintf_build_id(target, sbuildid);
-	else {
+	if (!target || !strcmp(target, DSO__NAME_KALLSYMS)) {
 		target = DSO__NAME_KALLSYMS;
+		is_kallsyms = true;
 		ret = sysfs__sprintf_build_id("/", sbuildid);
-	}
+	} else
+		ret = filename__sprintf_build_id(target, sbuildid);
+
 	if (ret < 0) {
 		pr_debug("Failed to get build-id from %s.\n", target);
 		return ret;
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index d513b34..cafbe1d 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter,
 				  struct strlist *plist);
 int probe_file__del_strlist(int fd, struct strlist *namelist);
 
+int probe_cache_entry__get_event(struct probe_cache_entry *entry,
+				 struct probe_trace_event **tevs);
+
 struct probe_cache *probe_cache__new(const char *target);
 int probe_cache__add_entry(struct probe_cache *pcache,
 			   struct perf_probe_event *pev,

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Search SDT/cached event from all probe caches
  2016-07-12 10:05 ` [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
@ 2016-07-14  7:07   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, brendan.d.gregg, tglx, peterz, hemant, namhyung,
	linux-kernel, mhiramat, acme, mingo, ananth

Commit-ID:  1de7b8bf728fd8d51b0cc644003d0694c6e0feef
Gitweb:     http://git.kernel.org/tip/1de7b8bf728fd8d51b0cc644003d0694c6e0feef
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:28 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:07 -0300

perf probe: Search SDT/cached event from all probe caches

Search SDT/cached event from all probe caches if user doesn't pass any
binary. With this, we don't have to specify target binary for SDT and
named cached events (which start with %).

E.g. without this, a target binary must be passed with -x.

  # perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*

With this change, we don't need it anymore.

  # perf probe -a %sdt_libc:\*

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831792812.17065.2353705982669445313.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 105 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 86 insertions(+), 19 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7b96e68..c63e3b8 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,
 	return 0;
 }
 
-static int __add_probe_trace_events(struct perf_probe_event *pev,
-				     struct probe_trace_event *tevs,
-				     int ntevs, bool allow_suffix)
+static int __open_probe_file_and_namelist(bool uprobe,
+					  struct strlist **namelist)
 {
-	int i, fd, ret;
-	struct probe_trace_event *tev = NULL;
-	struct probe_cache *cache = NULL;
-	struct strlist *namelist;
+	int fd;
 
-	fd = probe_file__open(PF_FL_RW | (pev->uprobes ? PF_FL_UPROBE : 0));
+	fd = probe_file__open(PF_FL_RW | (uprobe ? PF_FL_UPROBE : 0));
 	if (fd < 0)
 		return fd;
 
 	/* Get current event names */
-	namelist = probe_file__get_namelist(fd);
-	if (!namelist) {
+	*namelist = probe_file__get_namelist(fd);
+	if (!(*namelist)) {
 		pr_debug("Failed to get current event list.\n");
-		ret = -ENOMEM;
-		goto close_out;
+		close(fd);
+		return -ENOMEM;
 	}
+	return fd;
+}
+
+static int __add_probe_trace_events(struct perf_probe_event *pev,
+				     struct probe_trace_event *tevs,
+				     int ntevs, bool allow_suffix)
+{
+	int i, fd[2] = {-1, -1}, up, ret;
+	struct probe_trace_event *tev = NULL;
+	struct probe_cache *cache = NULL;
+	struct strlist *namelist[2] = {NULL, NULL};
+
+	up = pev->uprobes ? 1 : 0;
+	fd[up] = __open_probe_file_and_namelist(up, &namelist[up]);
+	if (fd[up] < 0)
+		return fd[up];
 
 	ret = 0;
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
+		up = tev->uprobes ? 1 : 0;
+		if (fd[up] == -1) {	/* Open the kprobe/uprobe_events */
+			fd[up] = __open_probe_file_and_namelist(up,
+								&namelist[up]);
+			if (fd[up] < 0)
+				goto close_out;
+		}
 		/* Skip if the symbol is out of .text or blacklisted */
 		if (!tev->point.symbol && !pev->uprobes)
 			continue;
 
 		/* Set new name for tev (and update namelist) */
-		ret = probe_trace_event__set_name(tev, pev, namelist,
+		ret = probe_trace_event__set_name(tev, pev, namelist[up],
 						  allow_suffix);
 		if (ret < 0)
 			break;
 
-		ret = probe_file__add_event(fd, tev);
+		ret = probe_file__add_event(fd[up], tev);
 		if (ret < 0)
 			break;
 
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		probe_cache__delete(cache);
 	}
 
-	strlist__delete(namelist);
 close_out:
-	close(fd);
+	for (up = 0; up < 2; up++) {
+		strlist__delete(namelist[up]);
+		if (fd[up] >= 0)
+			close(fd[up]);
+	}
 	return ret;
 }
 
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,
 	return ret;
 }
 
+/* Try to find probe_trace_event from all probe caches */
+static int find_cached_events_all(struct perf_probe_event *pev,
+				   struct probe_trace_event **tevs)
+{
+	struct probe_trace_event *tmp_tevs = NULL;
+	struct strlist *bidlist;
+	struct str_node *nd;
+	char *pathname;
+	int ntevs = 0;
+	int ret;
+
+	/* Get the buildid list of all valid caches */
+	bidlist = build_id_cache__list_all(true);
+	if (!bidlist) {
+		ret = -errno;
+		pr_debug("Failed to get buildids: %d\n", ret);
+		return ret;
+	}
+
+	ret = 0;
+	strlist__for_each_entry(nd, bidlist) {
+		pathname = build_id_cache__origname(nd->s);
+		ret = find_cached_events(pev, &tmp_tevs, pathname);
+		/* In the case of cnt == 0, we just skip it */
+		if (ret > 0)
+			ret = concat_probe_trace_events(tevs, &ntevs,
+							&tmp_tevs, ret);
+		free(pathname);
+		if (ret < 0)
+			break;
+	}
+	strlist__delete(bidlist);
+
+	if (ret < 0) {
+		clear_probe_trace_events(*tevs, ntevs);
+		zfree(tevs);
+	} else
+		ret = ntevs;
+
+	return ret;
+}
+
 static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 					      struct probe_trace_event **tevs)
 {
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
 	struct str_node *node;
 	int ret, i;
 
-	if (pev->sdt)
+	if (pev->sdt) {
 		/* For SDT/cached events, we use special search functions */
-		return find_cached_events(pev, tevs, pev->target);
-
+		if (!pev->target)
+			return find_cached_events_all(pev, tevs);
+		else
+			return find_cached_events(pev, tevs, pev->target);
+	}
 	cache = probe_cache__new(pev->target);
 	if (!cache)
 		return 0;

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
  2016-07-13 19:50   ` Arnaldo Carvalho de Melo
@ 2016-07-14  7:08   ` tip-bot for Masami Hiramatsu
  1 sibling, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hpa, brendan.d.gregg, tglx, mhiramat, linux-kernel, hemant,
	ananth, peterz, acme, mingo, namhyung

Commit-ID:  a598180aa1279bac4d24dfc85cd2d78553c4210d
Gitweb:     http://git.kernel.org/tip/a598180aa1279bac4d24dfc85cd2d78553c4210d
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:37 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:08 -0300

perf probe: Support @BUILDID or @FILE suffix for SDT events

Support @BUILDID or @FILE suffix for SDT events. This allows perf to add
probes on SDTs/pre-cached events on given FILE or the file which has
given BUILDID (also, this complements BUILDID.)

For example, both gcc and libstdc++ has same SDTs as below.  If you
would like to add a probe on sdt_libstdcxx:catch on gcc, you can do as
below.

  ----
  # perf list sdt | tail -n 6
    sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27)   [SDT event]
    sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27)     [SDT event]
    sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
  # perf probe -a %sdt_libstdcxx:catch@0cc
  Added new event:
    sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)

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

  	perf record -e sdt_libstdcxx:catch -aR sleep 1
  ----

Committer note:

Doing the full sequence of steps to get the results above:

With a clean build-id cache:

  [root@jouet ~]# rm -rf ~/.debug/
  [root@jouet ~]# perf list sdt

  List of pre-defined events (to be used in -e):

  [root@jouet ~]#

No events whatsoever, then, we can add all events in gcc to the build-id
cache, doing a --add + --dry-run:

  [root@jouet ~]# perf probe --dry-run --cache -x /usr/bin/gcc --add %sdt_libstdcxx:\*
  Added new events:
    sdt_libstdcxx:throw  (on %* in /usr/bin/gcc)
    sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc)
    sdt_libstdcxx:catch  (on %* in /usr/bin/gcc)

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

	perf record -e sdt_libstdcxx:catch -aR sleep 1

  [root@jouet ~]#

It really didn't add any events, it just cached them:

  [root@jouet ~]# perf probe -l
  [root@jouet ~]#

We can see that it was cached as:

  [root@jouet ~]# ls -la ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/
  total 976
  drwxr-xr-x. 2 root root   4096 Jul 13 21:47 .
  drwxr-xr-x. 3 root root   4096 Jul 13 21:47 ..
  -rwxr-xr-x. 4 root root 985912 Jun 22 18:52 elf
  -rw-r--r--. 1 root root    303 Jul 13 21:47 probes
  [root@jouet ~]# file ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/elf
  /root/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2, stripped
  [root@jouet ~]# cat ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/probes
  %sdt_libstdcxx:throw=throw
  p:sdt_libstdcxx/throw /usr/bin/gcc:0x71ffd
  %sdt_libstdcxx:rethrow=rethrow
  p:sdt_libstdcxx/rethrow /usr/bin/gcc:0x720b8
  %sdt_libstdcxx:catch=catch
  p:sdt_libstdcxx/catch /usr/bin/gcc:0x7307f
  %sdt_libgcc:unwind=unwind
  p:sdt_libgcc/unwind /usr/bin/gcc:0x7eec0
  #sdt_libstdcxx:*=%*
  [root@jouet ~]#

Ok, now we can use 'perf probe' to refer to those cached entries as:

  Humm, nope, doing as above we end up with:

  [root@jouet ~]# perf probe -a %sdt_libstdcxx:catch
  Semantic error :* is bad for event name -it must follow C symbol-naming rule.
    Error: Failed to add events.
  [root@jouet ~]#

But it worked at some point, lets try not using --dry-run:

Resetting everything:

  # rm -rf ~/.debug/
  # perf probe -d *:*
  # perf probe -l
  # perf list sdt

    List of pre-defined events (to be used in -e):

  #

Ok, now it cached everything, even things we haven't asked it to
(sdt_libgcc:unwind):

  [root@jouet ~]# perf probe -x /usr/bin/gcc --add %sdt_libstdcxx:\*
  Added new events:
    sdt_libstdcxx:throw  (on %* in /usr/bin/gcc)
    sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc)
    sdt_libstdcxx:catch  (on %* in /usr/bin/gcc)

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

	perf record -e sdt_libstdcxx:catch -aR sleep 1

  [root@jouet ~]# perf list sdt

  List of pre-defined events (to be used in -e):

    sdt_libgcc:unwind                                  [SDT event]
    sdt_libstdcxx:catch                                [SDT event]
    sdt_libstdcxx:rethrow                              [SDT event]
    sdt_libstdcxx:throw                                [SDT event]
  [root@jouet ~]#

And we have the events in place:

  [root@jouet ~]# perf probe -l
    sdt_libstdcxx:catch  (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc)
    sdt_libstdcxx:rethrow (on d_print_subexpr+280@libsupc++/cp-demangle.c in /usr/bin/gcc)
    sdt_libstdcxx:throw  (on d_print_subexpr+93@libsupc++/cp-demangle.c in /usr/bin/gcc)
  [root@jouet ~]#

And trying to use them at least has 'perf trace --event sdt*:*' working.

Then, if we try to add the ones in libstdc++:

  [root@jouet ~]# perf probe -x /usr/lib64/libstdc++.so.6 -a %sdt_libstdcxx:\*
  Error: event "catch" already exists.
   Hint: Remove existing event by 'perf probe -d'
         or force duplicates by 'perf probe -f'
         or set 'force=yes' in BPF source.
    Error: Failed to add events.
  [root@jouet ~]#

Doesn't work, dups, but at least this served to, unbeknownst to the user, add
the SDT probes in /usr/lib64/libstdc++.so.6!

  [root@jouet ~]# perf list sdt

  List of pre-defined events (to be used in -e):

    sdt_libgcc:unwind                                  [SDT event]
    sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
    sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6)   [SDT event]
    sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
    sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
    sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
  [root@jouet ~]#

Now we should be able to get to the original cset comment, if we remove all
SDTs events in place, not from the cache, from the kernel, where it was set up as:

  [root@jouet ~]# ls -la /sys/kernel/debug/tracing/events/sdt_libstdcxx/
  total 0
  drwxr-xr-x.  5 root root 0 Jul 13 22:00 .
  drwxr-xr-x. 80 root root 0 Jul 13 21:56 ..
  drwxr-xr-x.  2 root root 0 Jul 13 22:00 catch
  -rw-r--r--.  1 root root 0 Jul 13 22:00 enable
  -rw-r--r--.  1 root root 0 Jul 13 22:00 filter
  drwxr-xr-x.  2 root root 0 Jul 13 22:00 rethrow
  drwxr-xr-x.  2 root root 0 Jul 13 22:00 throw
  [root@jouet ~]#

  [root@jouet ~]# head -2 /sys/kernel/debug/tracing/events/sdt_libstdcxx/throw/format
  name: throw
  ID: 2059
  [root@jouet ~]#

Now to remove it:

  [root@jouet ~]# perf probe -d sdt_libstdc*:*
  Removed event: sdt_libstdcxx:catch
  Removed event: sdt_libstdcxx:rethrow
  Removed event: sdt_libstdcxx:throw
  [root@jouet ~]#

Which caused:

  [root@jouet ~]# ls -la /sys/kernel/debug/tracing/events/sdt_libstdcxx/
  ls: cannot access '/sys/kernel/debug/tracing/events/sdt_libstdcxx/': No such file or directory
  [root@jouet ~]#

Ok, now we can do:

  [root@jouet ~]# perf list sdt_libstdcxx:catch

  List of pre-defined events (to be used in -e):

    sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
  [root@jouet ~]#

So, these are not really 'pre-defined events', i.e. we can't use them with
'perf record --event':

  [root@jouet ~]# perf record --event sdt_libstdcxx:catch*
  event syntax error: 'sdt_libstdcxx:catch*'
                       \___ unknown tracepoint

  Error:	File /sys/kernel/debug/tracing/events/sdt_libstdcxx/catch* not found.
  Hint:	Perhaps this kernel misses some CONFIG_ setting to enable this feature?.
<SNIP>
  [root@jouet ~]#

To have it really pre-defined we must use perf probe to get its definition from
the cache and set it up in the kernel, creating the tracepoint to _then_ use it
with 'perf record --event':

  [root@jouet ~]# perf probe -a sdt_libstdcxx:catch
  Semantic error :There is non-digit char in line number.
  <SNIP>

Oops, there is another gotcha here, we need that pesky '%' character:

  [root@jouet ~]# perf probe -a %sdt_libstdcxx:catch
  Added new events:
    sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)
    sdt_libstdcxx:catch_1 (on %catch in /usr/lib64/libstdc++.so.6.0.22)

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

	perf record -e sdt_libstdcxx:catch_1 -aR sleep 1

  [root@jouet ~]#

But then we added _two_ events, one with the name we expected, the other one
with a _ added, when doing the analysis we need to pay attention to who maps to
who.

And here is where we get to the point of this patch, which is to be able to
disambiguate those definitions for 'catch' in the build-id cache, but first we need
remove those events we just added:

[root@jouet ~]# perf probe -d %sdt_libstdcxx:catch

Oops, that didn't remove anything, we need to _remove_ that % char in this case:

  [root@jouet ~]# perf probe -d sdt_libstdcxx:catch
  Removed event: sdt_libstdcxx:catch

And we need to remove the other event added, i.e. I forgot to add a * at the end:

  [root@jouet ~]# perf probe -d sdt_libstdcxx:catch*
  Removed event: sdt_libstdcxx:catch_1
  [root@jouet ~]#

Ok, disambiguating it using what is in this patch:

  [root@jouet ~]# perf list sdt_libstdcxx:catch

  List of pre-defined events (to be used in -e):

    sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
  [root@jouet ~]#
  [root@jouet ~]# perf probe -a %sdt_libstdcxx:catch@9a07
  Added new event:
    sdt_libstdcxx:catch  (on %catch in /usr/bin/gcc)

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

	perf record -e sdt_libstdcxx:catch -aR sleep 1

  [root@jouet ~]# perf probe -l
    sdt_libstdcxx:catch  (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc)
  [root@jouet ~]#

Yeah, it works! But we need to try and simplify this :-)

Update: Some aspects of this simplification take place in the following
        patches.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831793746.17065.13065062753978236612.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/build-id.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/build-id.h    |  1 +
 tools/perf/util/probe-event.c | 17 +++++++++++++++--
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 36b4279..5651f3c 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -523,6 +523,49 @@ err_out:
 	goto out_free;
 }
 
+static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		if (!isxdigit(maybe_sbuild_id[i]))
+			return false;
+	}
+	return true;
+}
+
+/* Return the valid complete build-id */
+char *build_id_cache__complement(const char *incomplete_sbuild_id)
+{
+	struct strlist *bidlist;
+	struct str_node *nd, *cand = NULL;
+	char *sbuild_id = NULL;
+	size_t len = strlen(incomplete_sbuild_id);
+
+	if (len >= SBUILD_ID_SIZE ||
+	    !str_is_build_id(incomplete_sbuild_id, len))
+		return NULL;
+
+	bidlist = build_id_cache__list_all(true);
+	if (!bidlist)
+		return NULL;
+
+	strlist__for_each_entry(nd, bidlist) {
+		if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
+			continue;
+		if (cand) {	/* Error: There are more than 2 candidates. */
+			cand = NULL;
+			break;
+		}
+		cand = nd;
+	}
+	if (cand)
+		sbuild_id = strdup(cand->s);
+	strlist__delete(bidlist);
+
+	return sbuild_id;
+}
+
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso)
 {
diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
index 64e740f..d279906 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
 char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
 			       bool is_kallsyms, bool is_vdso);
 struct strlist *build_id_cache__list_all(bool validonly);
+char *build_id_cache__complement(const char *incomplete_sbuild_id);
 int build_id_cache__list_build_ids(const char *pathname,
 				   struct strlist **result);
 bool build_id_cache__cached(const char *sbuild_id);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index c63e3b8..f12081e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	ptr = strpbrk(arg, ";=@+%");
 	if (pev->sdt) {
 		if (ptr) {
-			semantic_error("%s must contain only an SDT event name.\n", arg);
-			return -EINVAL;
+			if (*ptr != '@') {
+				semantic_error("%s must be an SDT name.\n",
+					       arg);
+				return -EINVAL;
+			}
+			/* This must be a target file name or build id */
+			tmp = build_id_cache__complement(ptr + 1);
+			if (tmp) {
+				pev->target = build_id_cache__origname(tmp);
+				free(tmp);
+			} else
+				pev->target = strdup(ptr + 1);
+			if (!pev->target)
+				return -ENOMEM;
+			*ptr = '\0';
 		}
 		ret = parse_perf_probe_event_name(&arg, pev);
 		if (ret == 0) {

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf probe: Support a special SDT probe format
  2016-07-12 10:05 ` [PATCH perf/core 08/10] perf probe: Support a special SDT probe format Masami Hiramatsu
@ 2016-07-14  7:08   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:08 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hemant, namhyung, tglx, ananth, brendan.d.gregg, mhiramat,
	peterz, acme, linux-kernel, hpa, mingo

Commit-ID:  7e9fca51fbf8430e27fb6b29299eda575e3f00cf
Gitweb:     http://git.kernel.org/tip/7e9fca51fbf8430e27fb6b29299eda575e3f00cf
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:46 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:09 -0300

perf probe: Support a special SDT probe format

Support a special SDT probe format which can omit the '%' prefix only if
the SDT group name starts with "sdt_". So, for example both of
"%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable for perf probe
--add.

E.g. without this:

  # perf probe -a sdt_libc:setjmp
  Semantic error :There is non-digit char in line number.
  ...

With this:

  # perf probe -a sdt_libc:setjmp
  Added new event:
    sdt_libc:setjmp      (on %setjmp in /usr/lib64/libc-2.20.so)

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

  	perf record -e sdt_libc:setjmp -aR sleep 1

Suggested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831794674.17065.13359473252168740430.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |  4 +++-
 tools/perf/util/probe-event.c           | 12 ++++++++++--
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 39e3870..736da44 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -152,7 +152,9 @@ Probe points are defined by following syntax.
      [[GROUP:]EVENT=]SRC;PTN [ARG ...]
 
     4) Pre-defined SDT events or cached event with name
-     %[PROVIDER:]SDTEVENT
+     %[sdt_PROVIDER:]SDTEVENT
+     or,
+     sdt_PROVIDER:SDTEVENT
 
 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe.
 Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index f12081e..d4f8835 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1243,9 +1243,17 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 	if (!arg)
 		return -EINVAL;
 
-	if (arg[0] == '%') {
+	/*
+	 * If the probe point starts with '%',
+	 * or starts with "sdt_" and has a ':' but no '=',
+	 * then it should be a SDT/cached probe point.
+	 */
+	if (arg[0] == '%' ||
+	    (!strncmp(arg, "sdt_", 4) &&
+	     !!strchr(arg, ':') && !strchr(arg, '='))) {
 		pev->sdt = true;
-		arg++;
+		if (arg[0] == '%')
+			arg++;
 	}
 
 	ptr = strpbrk(arg, ";=@+%");

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf build: Add sdt feature detection
  2016-07-12 10:05 ` [PATCH perf/core 09/10] perf build: Add sdt feature detection Masami Hiramatsu
@ 2016-07-14  7:09   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:09 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hemant, namhyung, mhiramat, tglx, peterz, acme, brendan.d.gregg,
	mingo, linux-kernel, hpa, ananth

Commit-ID:  e26e63be64a108c1fd12020b93b5b447ffe0532b
Gitweb:     http://git.kernel.org/tip/e26e63be64a108c1fd12020b93b5b447ffe0532b
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:05:56 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:09 -0300

perf build: Add sdt feature detection

This checks whether sys/sdt.h is available or not, which is required for
DTRACE_PROBE().

We can disable this feature by passing NO_SDT=1 when building.

This flag will be used for SDT test case and further SDT events in
perftools.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831795615.17065.17513820540591053933.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/build/Makefile.feature   |  3 ++-
 tools/build/feature/Makefile   |  6 +++++-
 tools/build/feature/test-all.c |  5 +++++
 tools/build/feature/test-sdt.c |  7 +++++++
 tools/perf/Makefile.perf       |  3 +++
 tools/perf/config/Makefile     | 10 ++++++++++
 tools/perf/tests/make          |  3 ++-
 7 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index fe12bee..a120c6b 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -62,7 +62,8 @@ FEATURE_TESTS_BASIC :=			\
 	zlib				\
 	lzma				\
 	get_cpuid			\
-	bpf
+	bpf				\
+	sdt
 
 # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list
 # of all feature tests
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index d6017c1..a0b29a3 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -45,7 +45,8 @@ FILES=					\
 	test-zlib.bin			\
 	test-lzma.bin			\
 	test-bpf.bin			\
-	test-get_cpuid.bin
+	test-get_cpuid.bin		\
+	test-sdt.bin
 
 FILES := $(addprefix $(OUTPUT),$(FILES))
 
@@ -213,6 +214,9 @@ $(OUTPUT)test-get_cpuid.bin:
 $(OUTPUT)test-bpf.bin:
 	$(BUILD)
 
+$(OUTPUT)test-sdt.bin:
+	$(BUILD)
+
 -include $(OUTPUT)*.d
 
 ###############################
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 843aed0..699e436 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -145,6 +145,10 @@
 # include "test-libcrypto.c"
 #undef main
 
+#define main main_test_sdt
+# include "test-sdt.c"
+#undef main
+
 int main(int argc, char *argv[])
 {
 	main_test_libpython();
@@ -178,6 +182,7 @@ int main(int argc, char *argv[])
 	main_test_get_cpuid();
 	main_test_bpf();
 	main_test_libcrypto();
+	main_test_sdt();
 
 	return 0;
 }
diff --git a/tools/build/feature/test-sdt.c b/tools/build/feature/test-sdt.c
new file mode 100644
index 0000000..e4531a6
--- /dev/null
+++ b/tools/build/feature/test-sdt.c
@@ -0,0 +1,7 @@
+#include <sys/sdt.h>
+
+int main(void)
+{
+	DTRACE_PROBE(provider, name);
+	return 0;
+}
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index feb2c66..a129fbc 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBBPF if you do not want BPF support
 #
+# Define NO_SDT if you do not want to define SDT event in perf tools,
+# note that it doesn't disable SDT scanning support.
+#
 # Define FEATURES_DUMP to provide features detection dump file
 # and bypass the feature detection
 
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 5ac4280..24803c5 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -355,6 +355,16 @@ ifndef NO_LIBELF
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
+ifndef NO_SDT
+  ifneq ($(feature-sdt), 1)
+    msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev);
+    NO_SDT := 1;
+  else
+    CFLAGS += -DHAVE_SDT_EVENT
+    $(call detected,CONFIG_SDT_EVENT)
+  endif
+endif
+
 ifdef PERF_HAVE_JITDUMP
   ifndef NO_DWARF
     $(call detected,CONFIG_JITDUMP)
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 51966d9..143f4d5 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -82,6 +82,7 @@ make_no_auxtrace    := NO_AUXTRACE=1
 make_no_libbpf	    := NO_LIBBPF=1
 make_no_libcrypto   := NO_LIBCRYPTO=1
 make_with_babeltrace:= LIBBABELTRACE=1
+make_no_sdt	    := NO_SDT=1
 make_tags           := tags
 make_cscope         := cscope
 make_help           := help
@@ -105,7 +106,7 @@ make_minimal        := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
 make_minimal        += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
 make_minimal        += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
 make_minimal        += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1
-make_minimal        += NO_LIBCRYPTO=1
+make_minimal        += NO_LIBCRYPTO=1 NO_SDT=1
 
 # $(run) contains all available tests
 run := make_pure

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [tip:perf/core] perf test: Add a test case for SDT event
  2016-07-12 10:06 ` [PATCH perf/core 10/10] perf-test: Add a test case for SDT event Masami Hiramatsu
@ 2016-07-14  7:10   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2016-07-14  7:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: hemant, peterz, tglx, ananth, mhiramat, brendan.d.gregg, mingo,
	acme, hpa, linux-kernel, namhyung

Commit-ID:  8e5dc848356ecf6ea8d27d641c4d7ad8d42fe92b
Gitweb:     http://git.kernel.org/tip/8e5dc848356ecf6ea8d27d641c4d7ad8d42fe92b
Author:     Masami Hiramatsu <mhiramat@kernel.org>
AuthorDate: Tue, 12 Jul 2016 19:06:05 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 13 Jul 2016 23:09:10 -0300

perf test: Add a test case for SDT event

Add a basic test case for SDT event support.  This test scans an SDT
event in perftools and check whether the SDT event is correctly stored
into the buildid cache.

Here is an example:

  ----
  $ perf test sdt -v
  47: Test SDT event probing                                   :
  --- start ---
  test child forked, pid 20732
  Found 72 SDTs in /home/mhiramat/ksrc/linux/tools/perf/perf
  Writing cache: %sdt_perf:test_target=test_target
  Cache committed: 0
  symbol:test_target file:(null) line:0 offset:0 return:0 lazy:(null)
  test child finished with 0
  ---- end ----
  Test SDT event probing: Ok
  ----

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/146831796546.17065.1502584370844087537.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/Build          |   1 +
 tools/perf/tests/builtin-test.c |   4 ++
 tools/perf/tests/sdt.c          | 115 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |   1 +
 4 files changed, 121 insertions(+)

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 66a2898..4158422 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -39,6 +39,7 @@ perf-y += stat.o
 perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
+perf-y += sdt.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index c23cbf7..4dd2d05 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -218,6 +218,10 @@ static struct test generic_tests[] = {
 		.func = test__cpu_map_print,
 	},
 	{
+		.desc = "Test SDT event probing",
+		.func = test__sdt_event,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c
new file mode 100644
index 0000000..f59d210
--- /dev/null
+++ b/tools/perf/tests/sdt.c
@@ -0,0 +1,115 @@
+#include <stdio.h>
+#include <sys/epoll.h>
+#include <util/util.h>
+#include <util/evlist.h>
+#include <linux/filter.h>
+#include "tests.h"
+#include "debug.h"
+#include "probe-file.h"
+#include "build-id.h"
+
+/* To test SDT event, we need libelf support to scan elf binary */
+#if defined(HAVE_SDT_EVENT) && defined(HAVE_LIBELF_SUPPORT)
+
+#include <sys/sdt.h>
+
+static int target_function(void)
+{
+	DTRACE_PROBE(perf, test_target);
+	return TEST_OK;
+}
+
+/* Copied from builtin-buildid-cache.c */
+static int build_id_cache__add_file(const char *filename)
+{
+	char sbuild_id[SBUILD_ID_SIZE];
+	u8 build_id[BUILD_ID_SIZE];
+	int err;
+
+	err = filename__read_build_id(filename, &build_id, sizeof(build_id));
+	if (err < 0) {
+		pr_debug("Failed to read build id of %s\n", filename);
+		return err;
+	}
+
+	build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+	err = build_id_cache__add_s(sbuild_id, filename, false, false);
+	if (err < 0)
+		pr_debug("Failed to add build id cache of %s\n", filename);
+	return err;
+}
+
+static char *get_self_path(void)
+{
+	char *buf = calloc(PATH_MAX, sizeof(char));
+
+	if (buf && readlink("/proc/self/exe", buf, PATH_MAX) < 0) {
+		pr_debug("Failed to get correct path of perf\n");
+		free(buf);
+		return NULL;
+	}
+	return buf;
+}
+
+static int search_cached_probe(const char *target,
+			       const char *group, const char *event)
+{
+	struct probe_cache *cache = probe_cache__new(target);
+	int ret = 0;
+
+	if (!cache) {
+		pr_debug("Failed to open probe cache of %s\n", target);
+		return -EINVAL;
+	}
+
+	if (!probe_cache__find_by_name(cache, group, event)) {
+		pr_debug("Failed to find %s:%s in the cache\n", group, event);
+		ret = -ENOENT;
+	}
+	probe_cache__delete(cache);
+
+	return ret;
+}
+
+int test__sdt_event(int subtests __maybe_unused)
+{
+	int ret = TEST_FAIL;
+	char __tempdir[] = "./test-buildid-XXXXXX";
+	char *tempdir = NULL, *myself = get_self_path();
+
+	if (myself == NULL || mkdtemp(__tempdir) == NULL) {
+		pr_debug("Failed to make a tempdir for build-id cache\n");
+		goto error;
+	}
+	/* Note that buildid_dir must be an absolute path */
+	tempdir = realpath(__tempdir, NULL);
+
+	/* At first, scan itself */
+	set_buildid_dir(tempdir);
+	if (build_id_cache__add_file(myself) < 0)
+		goto error_rmdir;
+
+	/* Open a cache and make sure the SDT is stored */
+	if (search_cached_probe(myself, "sdt_perf", "test_target") < 0)
+		goto error_rmdir;
+
+	/* TBD: probing on the SDT event and collect logs */
+
+	/* Call the target and get an event */
+	ret = target_function();
+
+error_rmdir:
+	/* Cleanup temporary buildid dir */
+	rm_rf(tempdir);
+error:
+	free(tempdir);
+	free(myself);
+	return ret;
+}
+#else
+int test__sdt_event(int subtests __maybe_unused)
+{
+	pr_debug("Skip SDT event test because SDT support is not compiled\n");
+	return TEST_SKIP;
+}
+#endif
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 52f9695..a0288f8 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -88,6 +88,7 @@ int test__event_update(int subtest);
 int test__event_times(int subtest);
 int test__backward_ring_buffer(int subtest);
 int test__cpu_map_print(int subtest);
+int test__sdt_event(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
  2016-07-14  0:20         ` Arnaldo Carvalho de Melo
@ 2016-07-14 15:32           ` Masami Hiramatsu
  0 siblings, 0 replies; 30+ messages in thread
From: Masami Hiramatsu @ 2016-07-14 15:32 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: linux-kernel, Namhyung Kim, Peter Zijlstra, Ingo Molnar,
	Hemant Kumar, Ananth N Mavinakayanahalli, Brendan Gregg

On Wed, 13 Jul 2016 21:20:48 -0300
Arnaldo Carvalho de Melo <acme@kernel.org> wrote:

> Em Wed, Jul 13, 2016 at 09:16:32PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
> > > I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
> > 
> > So it is here:
> > 
> > ->  976   T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events
> > 
> > June, 24, you forgot to rebase it for this new cset series, I'm doing
> > that now.

Ah, I just dropped it because this series still not support direct recording yet.
If we show the below SDTs by perf-list, we have to support it on perf-record which
is under developed now.

Thank you,

> 
> Ok, now it works:
> 
> 
> [root@jouet ~]# perf list sdt
> 
> List of pre-defined events (to be used in -e):
> 
>   sdt_libc:lll_lock_wait_private                     [SDT event]
>   sdt_libc:longjmp                                   [SDT event]
>   sdt_libc:longjmp_target                            [SDT event]
>   sdt_libc:memory_arena_new                          [SDT event]
>   sdt_libc:memory_arena_retry                        [SDT event]
>   sdt_libc:memory_arena_reuse                        [SDT event]
>   sdt_libc:memory_arena_reuse_free_list              [SDT event]
>   sdt_libc:memory_arena_reuse_wait                   [SDT event]
>   sdt_libc:memory_calloc_retry                       [SDT event]
>   sdt_libc:memory_heap_free                          [SDT event]
>   sdt_libc:memory_heap_less                          [SDT event]
>   sdt_libc:memory_heap_more                          [SDT event]
>   sdt_libc:memory_heap_new                           [SDT event]
>   sdt_libc:memory_malloc_retry                       [SDT event]
>   sdt_libc:memory_mallopt                            [SDT event]
>   sdt_libc:memory_mallopt_arena_max                  [SDT event]
>   sdt_libc:memory_mallopt_arena_test                 [SDT event]
>   sdt_libc:memory_mallopt_check_action               [SDT event]
>   sdt_libc:memory_mallopt_free_dyn_thresholds        [SDT event]
>   sdt_libc:memory_mallopt_mmap_max                   [SDT event]
>   sdt_libc:memory_mallopt_mmap_threshold             [SDT event]
>   sdt_libc:memory_mallopt_mxfast                     [SDT event]
>   sdt_libc:memory_mallopt_perturb                    [SDT event]
>   sdt_libc:memory_mallopt_top_pad                    [SDT event]
>   sdt_libc:memory_mallopt_trim_threshold             [SDT event]
>   sdt_libc:memory_memalign_retry                     [SDT event]
>   sdt_libc:memory_realloc_retry                      [SDT event]
>   sdt_libc:memory_sbrk_less                          [SDT event]
>   sdt_libc:memory_sbrk_more                          [SDT event]
>   sdt_libc:setjmp                                    [SDT event]
>   sdt_libgcc:unwind                                  [SDT event]
>   sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
>   sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
>   sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6)   [SDT event]
>   sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
>   sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6)     [SDT event]
>   sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
> [root@jouet ~]#


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2016-07-14 15:32 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-12 10:04 [PATCH perf/core 00/10] perf-probe --cache and SDT support Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 01/10] [BUGFIX] perf-probe: Fix to show correct error message for $vars and $params Masami Hiramatsu
2016-07-14  7:05   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 02/10] perf probe: Accept %sdt and %cached event name Masami Hiramatsu
2016-07-14  7:05   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:04 ` [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events Masami Hiramatsu
2016-07-13 19:28   ` Arnaldo Carvalho de Melo
2016-07-14  6:13     ` Masami Hiramatsu
2016-07-14  7:06   ` [tip:perf/core] perf probe: Make --list show " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 04/10] perf: probe-cache: Add for_each_probe_cache_entry() wrapper Masami Hiramatsu
2016-07-14  7:06   ` [tip:perf/core] perf " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events Masami Hiramatsu
2016-07-13 19:36   ` Arnaldo Carvalho de Melo
2016-07-14  7:07   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 06/10] perf probe: Search SDT/cached event from all probe caches Masami Hiramatsu
2016-07-14  7:07   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events Masami Hiramatsu
2016-07-13 19:50   ` Arnaldo Carvalho de Melo
2016-07-14  0:07     ` Arnaldo Carvalho de Melo
2016-07-14  0:16       ` Arnaldo Carvalho de Melo
2016-07-14  0:20         ` Arnaldo Carvalho de Melo
2016-07-14 15:32           ` Masami Hiramatsu
2016-07-14  7:08   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 08/10] perf probe: Support a special SDT probe format Masami Hiramatsu
2016-07-14  7:08   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:05 ` [PATCH perf/core 09/10] perf build: Add sdt feature detection Masami Hiramatsu
2016-07-14  7:09   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2016-07-12 10:06 ` [PATCH perf/core 10/10] perf-test: Add a test case for SDT event Masami Hiramatsu
2016-07-14  7:10   ` [tip:perf/core] perf test: " tip-bot for Masami Hiramatsu
2016-07-14  1:35 ` [PATCH perf/core 00/10] perf-probe --cache and SDT support Arnaldo Carvalho de Melo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).