linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points
@ 2015-05-06 12:46 Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error Masami Hiramatsu
                   ` (8 more replies)
  0 siblings, 9 replies; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Hi,

Here is a series of bugfix patches and improvements for perf-probe.
First 5 patches are new for fixing some minor issues on perf probe,
and last 3 are for wildcard support which is just updates of the
patches which I sent before ( https://lkml.org/lkml/2014/10/31/207 ).

I've dropped --output option since it will be done by perf-cache,
but this series doesn't involve perf-cache feature yet. I found some
issues when working on that and decided to send it beforehand.

Thank you,

---

Masami Hiramatsu (8):
      [BUGFIX] perf probe: Fix to close probe_events file in error
      [BUGFIX] perf probe: Fix a typo for the flags of open
      [BUGFIX] perf probe: Fix to return 0 when positive value returned
      [BUGFIX] perf probe: --line checks valid C-style function name
      perf probe: Skip kernel symbols which is out of .text
      perf-probe: Add --no-inlines option to avoid searching inline functions
      perf-probe: Support $params special probe argument
      perf-probe: Support glob wildcards for function name


 tools/perf/Documentation/perf-probe.txt |    6 +-
 tools/perf/builtin-probe.c              |    8 ++
 tools/perf/util/dwarf-aux.c             |   16 ++++
 tools/perf/util/dwarf-aux.h             |    3 +
 tools/perf/util/probe-event.c           |  116 +++++++++++++++++++++----------
 tools/perf/util/probe-event.h           |    4 +
 tools/perf/util/probe-finder.c          |   62 +++++++++++------
 tools/perf/util/probe-finder.h          |    6 +-
 tools/perf/util/util.h                  |    4 +
 9 files changed, 161 insertions(+), 64 deletions(-)


-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering 
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 2/8] [BUGFIX] perf probe: Fix a typo for the flags of open Masami Hiramatsu
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Fix perf-probe to close probe_events file if it failed to
get existing probe's name. This also fix the return error
code to -ENOMEM.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.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 abf5845..230353f 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2384,7 +2384,8 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	namelist = get_probe_trace_event_names(fd, false);
 	if (!namelist) {
 		pr_debug("Failed to get current event list.\n");
-		return -EIO;
+		ret = -ENOMEM;
+		goto close_out;
 	}
 	/* Get kprobe blacklist if exists */
 	if (!pev->uprobes) {
@@ -2467,6 +2468,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 
 	kprobe_blacklist__delete(&blacklist);
 	strlist__delete(namelist);
+close_out:
 	close(fd);
 	return ret;
 }


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

* [PATCH perf/core 2/8] [BUGFIX] perf probe: Fix a typo for the flags of open
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 3/8] [BUGFIX] perf probe: Fix to return 0 when positive value returned Masami Hiramatsu
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Fix to pass O_APPEND by using bit-or with other flags, instead of
passing it as mode.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/util/probe-event.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 230353f..63cb7c5 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1969,7 +1969,7 @@ static int open_probe_events(const char *trace_file, bool readwrite)
 	if (ret >= 0) {
 		pr_debug("Opening %s write=%d\n", buf, readwrite);
 		if (readwrite && !probe_event_dry_run)
-			ret = open(buf, O_RDWR, O_APPEND);
+			ret = open(buf, O_RDWR | O_APPEND, 0);
 		else
 			ret = open(buf, O_RDONLY, 0);
 


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

* [PATCH perf/core 3/8] [BUGFIX] perf probe: Fix to return 0 when positive value returned
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 2/8] [BUGFIX] perf probe: Fix a typo for the flags of open Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 4/8] [BUGFIX] perf probe: --line checks valid C-style function name Masami Hiramatsu
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Fix to return 0 when positive value returned from probe command.

At least --vars can returns a positive value if it found a point.
  ----
  # perf probe --vars vfs_read && echo succeeded! || echo failed!
  Available variables at vfs_read
          @<vfs_read+0>
                  char*   buf
                  loff_t* pos
                  size_t  count
                  struct file*    file
  failed!
  ----

This fixes above problem.
  ----
  # perf probe --vars vfs_read && echo succeeded! || echo failed!
  Available variables at vfs_read
          @<vfs_read+0>
                  char*   buf
                  loff_t* pos
                  size_t  count
                  struct file*    file
  succeeded!
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/builtin-probe.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 53d475b..9c4cf5e 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -523,5 +523,5 @@ int cmd_probe(int argc, const char **argv, const char *prefix)
 		cleanup_params();
 	}
 
-	return ret;
+	return ret < 0 ? ret : 0;
 }


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

* [PATCH perf/core 4/8] [BUGFIX] perf probe: --line checks valid C-style function name
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (2 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 3/8] [BUGFIX] perf probe: Fix to return 0 when positive value returned Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:04   ` [tip:perf/core] perf probe: Make --line checks validate " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 5/8] perf probe: Skip kernel symbols which is out of .text Masami Hiramatsu
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Fix --line to check valid C-style function name and returns
a semantic error if it is not.

For example, previously, --line doesn't support lazy pattern
but it doesn't recognized as a semantic error.

  ----
  # perf probe -L 'func;return*:0-10'
  Specified source line is not found.
    Error: Failed to show lines.
  ----

With this patch, it is correctly handled as a semantic error.
  ----
  # perf probe -L 'func;return*:0-10'
  Semantic error :'func;return*' is not a valid function name.
  ...
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/util/probe-event.c |   35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 63cb7c5..4265f2e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -980,6 +980,18 @@ static int parse_line_num(char **ptr, int *val, const char *what)
 	return 0;
 }
 
+/* Check the name is good for event, group or function */
+static bool is_c_func_name(const char *name)
+{
+	if (!isalpha(*name) && *name != '_')
+		return false;
+	while (*++name != '\0') {
+		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+			return false;
+	}
+	return true;
+}
+
 /*
  * Stuff 'lr' according to the line range described by 'arg'.
  * The line range syntax is described by:
@@ -1048,10 +1060,15 @@ int parse_line_range_desc(const char *arg, struct line_range *lr)
 			goto err;
 		}
 		lr->function = name;
-	} else if (strchr(name, '.'))
+	} else if (strchr(name, '/') || strchr(name, '.'))
 		lr->file = name;
-	else
+	else if (is_c_func_name(name))/* We reuse it for checking funcname */
 		lr->function = name;
+	else {	/* Invalid name */
+		semantic_error("'%s' is not a valid function name.\n", name);
+		err = -EINVAL;
+		goto err;
+	}
 
 	return 0;
 err:
@@ -1059,18 +1076,6 @@ err:
 	return err;
 }
 
-/* Check the name is good for event/group */
-static bool check_event_name(const char *name)
-{
-	if (!isalpha(*name) && *name != '_')
-		return false;
-	while (*++name != '\0') {
-		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
-			return false;
-	}
-	return true;
-}
-
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
@@ -1094,7 +1099,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 			semantic_error("Group name is not supported yet.\n");
 			return -ENOTSUP;
 		}
-		if (!check_event_name(arg)) {
+		if (!is_c_func_name(arg)) {
 			semantic_error("%s is bad for event name -it must "
 				       "follow C symbol-naming rule.\n", arg);
 			return -EINVAL;


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

* [PATCH perf/core 5/8] perf probe: Skip kernel symbols which is out of .text
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (3 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 4/8] [BUGFIX] perf probe: --line checks valid C-style function name Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:05   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions Masami Hiramatsu
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Skip the kernel symbols which is out of .text, e.g. the functions
in .inittext. Those are found in debuginfo/kallsyms, but already
freed from memory.

e.g.
  ----
  # perf probe vfs_caches_init
  vfs_caches_init+0 is out of .text, skip it.
  Probe point 'vfs_caches_init' not found.
    Error: Failed to add events.
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/util/probe-event.c |   31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4265f2e..37a3a8b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -557,8 +557,9 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 					   bool uprobe)
 {
 	struct ref_reloc_sym *reloc_sym;
+	u64 etext_addr;
 	char *tmp;
-	int i;
+	int i, skipped = 0;
 
 	if (uprobe)
 		return add_exec_to_probe_trace_events(tevs, ntevs, module);
@@ -572,19 +573,29 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 		pr_warning("Relocated base symbol is not found!\n");
 		return -EINVAL;
 	}
+	/* Get the address of _etext for checking non-probable text symbol */
+	etext_addr = kernel_get_symbol_address_by_name("_etext", false);
 
 	for (i = 0; i < ntevs; i++) {
 		if (tevs[i].point.address && !tevs[i].point.retprobe) {
-			tmp = strdup(reloc_sym->name);
-			if (!tmp)
-				return -ENOMEM;
+			/* If we found a wrong one, mark it by NULL symbol */
+			if (etext_addr < tevs[i].point.address) {
+				pr_warning("%s+%lu is out of .text, skip it.\n",
+				   tevs[i].point.symbol, tevs[i].point.offset);
+				tmp = NULL;
+				skipped++;
+			} else {
+				tmp = strdup(reloc_sym->name);
+				if (!tmp)
+					return -ENOMEM;
+			}
 			free(tevs[i].point.symbol);
 			tevs[i].point.symbol = tmp;
 			tevs[i].point.offset = tevs[i].point.address -
 					       reloc_sym->unrelocated_addr;
 		}
 	}
-	return 0;
+	return skipped;
 }
 
 /* Try to find perf_probe_event with debuginfo */
@@ -630,11 +641,14 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 		pr_debug("Found %d probe_trace_events.\n", ntevs);
 		ret = post_process_probe_trace_events(*tevs, ntevs,
 							target, pev->uprobes);
-		if (ret < 0) {
+		if (ret < 0 || ret == ntevs) {
 			clear_probe_trace_events(*tevs, ntevs);
 			zfree(tevs);
 		}
-		return ret < 0 ? ret : ntevs;
+		if (ret != ntevs)
+			return ret < 0 ? ret : ntevs;
+		ntevs = 0;
+		/* Fall through */
 	}
 
 	if (ntevs == 0)	{	/* No error but failed to find probe point. */
@@ -2403,6 +2417,9 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
+		/* Skip if the symbol is out of .text (marked previously) */
+		if (!tev->point.symbol)
+			continue;
 		/* Ensure that the address is NOT blacklisted */
 		node = kprobe_blacklist__find_by_address(&blacklist,
 							 tev->point.address);


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

* [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (4 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 5/8] perf probe: Skip kernel symbols which is out of .text Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-06 15:52   ` Arnaldo Carvalho de Melo
  2015-05-06 12:46 ` [PATCH perf/core 7/8] perf-probe: Support $params special probe argument Masami Hiramatsu
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Add --no-inlines(--inlines) option to avoid searching inline
functions.
Searching all functions which matches glob pattern can take a
long time and find a lot of inline functions. With this option
perf-probe searches target on the non-inlined functions.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/Documentation/perf-probe.txt |    4 ++++
 tools/perf/builtin-probe.c              |    6 +++++-
 tools/perf/util/probe-event.c           |   25 ++++++++++++++++---------
 tools/perf/util/probe-event.h           |    3 ++-
 tools/perf/util/probe-finder.c          |    8 +++++---
 tools/perf/util/probe-finder.h          |    3 ++-
 6 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index a272f2e..a1637ce 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -83,6 +83,10 @@ OPTIONS
 	(Only for --vars) Show external defined variables in addition to local
 	variables.
 
+--no-inlines::
+	(Only for --add) Search only for non-inlined functions. The functions
+	which do not have instances are ignored.
+
 -F::
 --funcs[=FILTER]::
 	Show available functions in given module or kernel. With -x/--exec,
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 9c4cf5e..be7f25f 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -53,6 +53,7 @@ static struct {
 	bool force_add;
 	bool show_ext_vars;
 	bool uprobes;
+	bool no_inlines;
 	bool quiet;
 	bool target_used;
 	int nevents;
@@ -382,6 +383,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_CALLBACK('m', "module", NULL, "modname|path",
 		"target module name (for online) or path (for offline)",
 		opt_set_target),
+	OPT_BOOLEAN('\0', "no-inlines", &params.no_inlines,
+		"Don't search inlined functions"),
 #endif
 	OPT__DRY_RUN(&probe_event_dry_run),
 	OPT_INTEGER('\0', "max-probes", &params.max_probe_points,
@@ -501,7 +504,8 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
 
 		ret = add_perf_probe_events(params.events, params.nevents,
 					    params.max_probe_points,
-					    params.force_add);
+					    params.force_add,
+					    params.no_inlines);
 		if (ret < 0) {
 			pr_err_with_code("  Error: Failed to add events.", ret);
 			return ret;
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 37a3a8b..c9805fd 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -601,7 +601,8 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 /* Try to find perf_probe_event with debuginfo */
 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 					  struct probe_trace_event **tevs,
-					  int max_tevs, const char *target)
+					  int max_tevs, const char *target,
+					  bool no_inline)
 {
 	bool need_dwarf = perf_probe_event_need_dwarf(pev);
 	struct perf_probe_point tmp;
@@ -619,13 +620,15 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 
 	pr_debug("Try to find probe point from debuginfo.\n");
 	/* Searching trace events corresponding to a probe event */
-	ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
+	ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs,
+					     no_inline);
 
 	if (ntevs == 0)	{  /* Not found, retry with an alternative */
 		ret = get_alternative_probe_event(dinfo, pev, &tmp, target);
 		if (!ret) {
 			ntevs = debuginfo__find_trace_events(dinfo, pev,
-							     tevs, max_tevs);
+							     tevs, max_tevs,
+							     no_inline);
 			/*
 			 * Write back to the original probe_event for
 			 * setting appropriate (user given) event name
@@ -932,7 +935,8 @@ find_perf_probe_point_from_dwarf(struct probe_trace_point *tp __maybe_unused,
 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 				struct probe_trace_event **tevs __maybe_unused,
 				int max_tevs __maybe_unused,
-				const char *target __maybe_unused)
+				const char *target __maybe_unused,
+				bool no_inline __maybe_unused)
 {
 	if (perf_probe_event_need_dwarf(pev)) {
 		pr_warning("Debuginfo-analysis is not supported.\n");
@@ -2638,8 +2642,9 @@ err_out:
 bool __weak arch__prefers_symtab(void) { return false; }
 
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
-					  struct probe_trace_event **tevs,
-					  int max_tevs, const char *target)
+					 struct probe_trace_event **tevs,
+					 int max_tevs, const char *target,
+					 bool no_inline)
 {
 	int ret;
 
@@ -2659,7 +2664,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 	}
 
 	/* Convert perf_probe_event with debuginfo */
-	ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target);
+	ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, target,
+					     no_inline);
 	if (ret != 0)
 		return ret;	/* Found in debuginfo or got an error */
 
@@ -2673,7 +2679,7 @@ struct __event_package {
 };
 
 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
-			  int max_tevs, bool force_add)
+			  int max_tevs, bool force_add, bool no_inline)
 {
 	int i, j, ret;
 	struct __event_package *pkgs;
@@ -2697,7 +2703,8 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
 		ret  = convert_to_probe_trace_events(pkgs[i].pev,
 						     &pkgs[i].tevs,
 						     max_tevs,
-						     pkgs[i].pev->target);
+						     pkgs[i].pev->target,
+						     no_inline);
 		if (ret < 0)
 			goto end;
 		pkgs[i].ntevs = ret;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index e10aedc..f883670 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -125,7 +125,8 @@ extern int line_range__init(struct line_range *lr);
 extern const char *kernel_get_module_path(const char *module);
 
 extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
-				 int max_probe_points, bool force_add);
+				 int max_probe_points, bool force_add,
+				 bool no_inline);
 extern int del_perf_probe_events(struct strfilter *filter);
 extern int show_perf_probe_events(struct strfilter *filter);
 extern int show_line_range(struct line_range *lr, const char *module,
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 44554c3..a37b439 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -943,7 +943,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 			/* TODO: Check the address in this function */
 			param->retval = call_probe_finder(sp_die, pf);
 		}
-	} else
+	} else if (!pf->no_inline)
 		/* Inlined function: search instances */
 		param->retval = die_walk_instances(sp_die,
 					probe_point_inline_cb, (void *)pf);
@@ -1211,10 +1211,12 @@ end:
 /* Find probe_trace_events specified by perf_probe_event from debuginfo */
 int debuginfo__find_trace_events(struct debuginfo *dbg,
 				 struct perf_probe_event *pev,
-				 struct probe_trace_event **tevs, int max_tevs)
+				 struct probe_trace_event **tevs,
+				 int max_tevs, bool no_inline)
 {
 	struct trace_event_finder tf = {
-			.pf = {.pev = pev, .callback = add_probe_trace_event},
+			.pf = {.pev = pev, .callback = add_probe_trace_event,
+				.no_inline = no_inline},
 			.mod = dbg->mod, .max_tevs = max_tevs};
 	int ret;
 
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index ebf8c8c..996f007 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -38,7 +38,7 @@ extern void debuginfo__delete(struct debuginfo *dbg);
 extern int debuginfo__find_trace_events(struct debuginfo *dbg,
 					struct perf_probe_event *pev,
 					struct probe_trace_event **tevs,
-					int max_tevs);
+					int max_tevs, bool no_inline);
 
 /* Find a perf_probe_point from debuginfo */
 extern int debuginfo__find_probe_point(struct debuginfo *dbg,
@@ -80,6 +80,7 @@ struct probe_finder {
 	Dwarf_Op		*fb_ops;	/* Frame base attribute */
 	struct perf_probe_arg	*pvar;		/* Current target variable */
 	struct probe_trace_arg	*tvar;		/* Current result variable */
+	bool			no_inline;	/* Do not find inlines */
 };
 
 struct trace_event_finder {


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

* [PATCH perf/core 7/8] perf-probe: Support $params special probe argument
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (5 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-10  7:05   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
  2015-05-06 12:46 ` [PATCH perf/core 8/8] perf-probe: Support glob wildcards for function name Masami Hiramatsu
  2015-05-06 16:19 ` [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Arnaldo Carvalho de Melo
  8 siblings, 1 reply; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

$params is similar to $vars but matches only function parameters
not local variables.
Thus, this is useful for tracing function parameter changing
or tracing function call with parameters.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/Documentation/perf-probe.txt |    2 +-
 tools/perf/util/probe-finder.c          |   29 ++++++++++++++++-------------
 tools/perf/util/probe-finder.h          |    3 +++
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index a1637ce..3a8a9ba 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -155,7 +155,7 @@ Each probe argument follows below syntax.
  [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
 
 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
-'$vars' special argument is also available for NAME, it is expanded to the local variables which can access at given probe point.
+'$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters.
 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. You can specify 'string' type only for the local variable or structure member which is an array of or a pointer to 'char' or 'unsigned char' type.
 
 On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid.
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a37b439..ce48719 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1087,6 +1087,7 @@ found:
 struct local_vars_finder {
 	struct probe_finder *pf;
 	struct perf_probe_arg *args;
+	bool vars;
 	int max_args;
 	int nargs;
 	int ret;
@@ -1101,7 +1102,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
 
 	tag = dwarf_tag(die_mem);
 	if (tag == DW_TAG_formal_parameter ||
-	    tag == DW_TAG_variable) {
+	    (tag == DW_TAG_variable && vf->vars)) {
 		if (convert_variable_location(die_mem, vf->pf->addr,
 					      vf->pf->fb_ops, &pf->sp_die,
 					      NULL) == 0) {
@@ -1127,26 +1128,28 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
 	Dwarf_Die die_mem;
 	int i;
 	int n = 0;
-	struct local_vars_finder vf = {.pf = pf, .args = args,
+	struct local_vars_finder vf = {.pf = pf, .args = args, .vars = false,
 				.max_args = MAX_PROBE_ARGS, .ret = 0};
 
 	for (i = 0; i < pf->pev->nargs; i++) {
 		/* var never be NULL */
-		if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
-			pr_debug("Expanding $vars into:");
-			vf.nargs = n;
-			/* Special local variables */
-			die_find_child(sc_die, copy_variables_cb, (void *)&vf,
-				       &die_mem);
-			pr_debug(" (%d)\n", vf.nargs - n);
-			if (vf.ret < 0)
-				return vf.ret;
-			n = vf.nargs;
-		} else {
+		if (strcmp(pf->pev->args[i].var, PROBE_ARG_VARS) == 0)
+			vf.vars = true;
+		else if (strcmp(pf->pev->args[i].var, PROBE_ARG_PARAMS) != 0) {
 			/* Copy normal argument */
 			args[n] = pf->pev->args[i];
 			n++;
+			continue;
 		}
+		pr_debug("Expanding %s into:", pf->pev->args[i].var);
+		vf.nargs = n;
+		/* Special local variables */
+		die_find_child(sc_die, copy_variables_cb, (void *)&vf,
+			       &die_mem);
+		pr_debug(" (%d)\n", vf.nargs - n);
+		if (vf.ret < 0)
+			return vf.ret;
+		n = vf.nargs;
 	}
 	return n;
 }
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index 996f007..13edda6 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -10,6 +10,9 @@
 #define MAX_PROBES		 128
 #define MAX_PROBE_ARGS		 128
 
+#define PROBE_ARG_VARS		"$vars"
+#define PROBE_ARG_PARAMS	"$params"
+
 static inline int is_c_varname(const char *name)
 {
 	/* TODO */


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

* [PATCH perf/core 8/8] perf-probe: Support glob wildcards for function name
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (6 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 7/8] perf-probe: Support $params special probe argument Masami Hiramatsu
@ 2015-05-06 12:46 ` Masami Hiramatsu
  2015-05-06 16:19 ` [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Arnaldo Carvalho de Melo
  8 siblings, 0 replies; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 12:46 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Support glob wildcards for function name when adding
new probes. This will allow us to build caches of
function-entry level information with $params.

e.g.
  ----
  # perf probe --no-inlines --add 'kmalloc* $params'
  Added new events:
    probe:kmalloc_slab   (on kmalloc* with $params)
    probe:kmalloc_large_node (on kmalloc* with $params)
    probe:kmalloc_order_trace (on kmalloc* with $params)

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

        perf record -e probe:kmalloc_order_trace -aR sleep 1

  # perf probe --list
    probe:kmalloc_large_node (on kmalloc_large_node@mm/slub.c with size flags node)
    probe:kmalloc_order_trace (on kmalloc_order_trace@mm/slub.c with size flags order)
    probe:kmalloc_slab   (on kmalloc_slab@mm/slab_common.c with size flags)
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
---
 tools/perf/util/dwarf-aux.c    |   16 ++++++++++++++++
 tools/perf/util/dwarf-aux.h    |    3 +++
 tools/perf/util/probe-event.c  |   19 ++++++++++++++-----
 tools/perf/util/probe-event.h  |    1 +
 tools/perf/util/probe-finder.c |   27 +++++++++++++++++++++------
 tools/perf/util/util.h         |    4 ++++
 6 files changed, 59 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index c34e024..16d46e2 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -139,11 +139,27 @@ int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
 bool die_compare_name(Dwarf_Die *dw_die, const char *tname)
 {
 	const char *name;
+
 	name = dwarf_diename(dw_die);
 	return name ? (strcmp(tname, name) == 0) : false;
 }
 
 /**
+ * die_match_name - Match diename and glob
+ * @dw_die: a DIE
+ * @glob: a string of target glob pattern
+ *
+ * Glob matching the name of @dw_die and @glob. Return false if matching fail.
+ */
+bool die_match_name(Dwarf_Die *dw_die, const char *glob)
+{
+	const char *name;
+
+	name = dwarf_diename(dw_die);
+	return name ? strglobmatch(name, glob) : false;
+}
+
+/**
  * die_get_call_lineno - Get callsite line number of inline-function instance
  * @in_die: a DIE of an inlined function instance
  *
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index af7dbcd..50a3cdc 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -47,6 +47,9 @@ extern bool die_is_func_instance(Dwarf_Die *dw_die);
 /* Compare diename and tname */
 extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname);
 
+/* Matching diename with glob pattern */
+extern bool die_match_name(Dwarf_Die *dw_die, const char *glob);
+
 /* Get callsite line number of inline-function instance */
 extern int die_get_call_lineno(Dwarf_Die *in_die);
 
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index c9805fd..2c3b79f 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -589,7 +589,11 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 				if (!tmp)
 					return -ENOMEM;
 			}
-			free(tevs[i].point.symbol);
+			/* If we have no realname, use symbol for it */
+			if (!tevs[i].point.realname)
+				tevs[i].point.realname = tevs[i].point.symbol;
+			else
+				free(tevs[i].point.symbol);
 			tevs[i].point.symbol = tmp;
 			tevs[i].point.offset = tevs[i].point.address -
 					       reloc_sym->unrelocated_addr;
@@ -1915,6 +1919,7 @@ static void clear_probe_trace_event(struct probe_trace_event *tev)
 	free(tev->event);
 	free(tev->group);
 	free(tev->point.symbol);
+	free(tev->point.realname);
 	free(tev->point.module);
 	for (i = 0; i < tev->nargs; i++) {
 		free(tev->args[i].name);
@@ -2392,6 +2397,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	struct strlist *namelist;
 	LIST_HEAD(blacklist);
 	struct kprobe_blacklist_node *node;
+	bool safename;
 
 	if (pev->uprobes)
 		fd = open_uprobe_events(true);
@@ -2417,6 +2423,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 			pr_debug("No kprobe blacklist support, ignored\n");
 	}
 
+	safename = (pev->point.function && !strisglob(pev->point.function));
 	ret = 0;
 	pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
@@ -2435,10 +2442,10 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 		if (pev->event)
 			event = pev->event;
 		else
-			if (pev->point.function)
+			if (safename)
 				event = pev->point.function;
 			else
-				event = tev->point.symbol;
+				event = tev->point.realname;
 		if (pev->group)
 			group = pev->group;
 		else
@@ -2503,9 +2510,11 @@ static int find_probe_functions(struct map *map, char *name)
 {
 	int found = 0;
 	struct symbol *sym;
+	struct rb_node *tmp;
 
-	map__for_each_symbol_by_name(map, name, sym) {
-		found++;
+	map__for_each_symbol(map, sym, tmp) {
+		if (strglobmatch(sym->name, name))
+			found++;
 	}
 
 	return found;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index f883670..a5ea1fe 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -10,6 +10,7 @@ extern bool probe_event_dry_run;
 
 /* kprobe-tracer and uprobe-tracer tracing point */
 struct probe_trace_point {
+	char		*realname;	/* function real name (if needed) */
 	char		*symbol;	/* Base symbol */
 	char		*module;	/* Module name */
 	unsigned long	offset;		/* Offset from symbol */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index ce48719..6d61411 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -717,7 +717,7 @@ static int find_best_scope_cb(Dwarf_Die *fn_die, void *data)
 	}
 	/* If the function name is given, that's what user expects */
 	if (fsp->function) {
-		if (die_compare_name(fn_die, fsp->function)) {
+		if (die_match_name(fn_die, fsp->function)) {
 			memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die));
 			fsp->found = true;
 			return 1;
@@ -920,13 +920,14 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 
 	/* Check tag and diename */
 	if (!die_is_func_def(sp_die) ||
-	    !die_compare_name(sp_die, pp->function))
+	    !die_match_name(sp_die, pp->function))
 		return DWARF_CB_OK;
 
 	/* Check declared file */
 	if (pp->file && strtailcmp(pp->file, dwarf_decl_file(sp_die)))
 		return DWARF_CB_OK;
 
+	pr_debug("Matched function: %s\n", dwarf_diename(sp_die));
 	pf->fname = dwarf_decl_file(sp_die);
 	if (pp->line) { /* Function relative line */
 		dwarf_decl_line(sp_die, &pf->lno);
@@ -943,10 +944,20 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 			/* TODO: Check the address in this function */
 			param->retval = call_probe_finder(sp_die, pf);
 		}
-	} else if (!pf->no_inline)
+	} else if (!pf->no_inline) {
 		/* Inlined function: search instances */
 		param->retval = die_walk_instances(sp_die,
 					probe_point_inline_cb, (void *)pf);
+		/* This could be a non-existed inline definition */
+		if (param->retval == -ENOENT && strisglob(pp->function))
+			param->retval = 0;
+	}
+
+	/* We need to find other candidates */
+	if (strisglob(pp->function) && param->retval >= 0) {
+		param->retval = 0;	/* We have to clear the result */
+		return DWARF_CB_OK;
+	}
 
 	return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */
 }
@@ -975,7 +986,7 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
 		if (dwarf_tag(param->sp_die) != DW_TAG_subprogram)
 			return DWARF_CB_OK;
 
-		if (die_compare_name(param->sp_die, param->function)) {
+		if (die_match_name(param->sp_die, param->function)) {
 			if (!dwarf_offdie(dbg, gl->cu_offset, param->cu_die))
 				return DWARF_CB_OK;
 
@@ -1028,7 +1039,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
 		return -ENOMEM;
 
 	/* Fastpath: lookup by function name from .debug_pubnames section */
-	if (pp->function) {
+	if (pp->function && !strisglob(pp->function)) {
 		struct pubname_callback_param pubname_param = {
 			.function = pp->function,
 			.file	  = pp->file,
@@ -1177,6 +1188,10 @@ static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf)
 	if (ret < 0)
 		return ret;
 
+	tev->point.realname = strdup(dwarf_diename(sc_die));
+	if (!tev->point.realname)
+		return -ENOMEM;
+
 	pr_debug("Probe point found: %s+%lu\n", tev->point.symbol,
 		 tev->point.offset);
 
@@ -1538,7 +1553,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data)
 		return DWARF_CB_OK;
 
 	if (die_is_func_def(sp_die) &&
-	    die_compare_name(sp_die, lr->function)) {
+	    die_match_name(sp_die, lr->function)) {
 		lf->fname = dwarf_decl_file(sp_die);
 		dwarf_decl_line(sp_die, &lr->offset);
 		pr_debug("fname: %s, lineno:%d\n", lf->fname, lr->offset);
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 1ff23e0..3601ffd 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -257,6 +257,10 @@ char **argv_split(const char *str, int *argcp);
 void argv_free(char **argv);
 bool strglobmatch(const char *str, const char *pat);
 bool strlazymatch(const char *str, const char *pat);
+static inline bool strisglob(const char *str)
+{
+	return strpbrk(str, "*?[") != NULL;
+}
 int strtailcmp(const char *s1, const char *s2);
 char *strxfrchar(char *s, char from, char to);
 unsigned long convert_unit(unsigned long value, char *unit);


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

* Re: [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions
  2015-05-06 12:46 ` [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions Masami Hiramatsu
@ 2015-05-06 15:52   ` Arnaldo Carvalho de Melo
  2015-05-06 23:22     ` Masami Hiramatsu
  0 siblings, 1 reply; 18+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-05-06 15:52 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Em Wed, May 06, 2015 at 09:46:51PM +0900, Masami Hiramatsu escreveu:
> Add --no-inlines(--inlines) option to avoid searching inline
> functions.
> Searching all functions which matches glob pattern can take a
> long time and find a lot of inline functions. With this option
> perf-probe searches target on the non-inlined functions.
> 
>  
>  		ret = add_perf_probe_events(params.events, params.nevents,
>  					    params.max_probe_points,
> -					    params.force_add);
> +					    params.force_add,
> +					    params.no_inlines);

So, there is just one call to this function, and all the parameters come
from the 'param' struct, why not just pass it?

- Arnaldo

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

* Re: [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points
  2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
                   ` (7 preceding siblings ...)
  2015-05-06 12:46 ` [PATCH perf/core 8/8] perf-probe: Support glob wildcards for function name Masami Hiramatsu
@ 2015-05-06 16:19 ` Arnaldo Carvalho de Melo
  8 siblings, 0 replies; 18+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-05-06 16:19 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

Em Wed, May 06, 2015 at 09:46:38PM +0900, Masami Hiramatsu escreveu:
> Hi,
> 
> Here is a series of bugfix patches and improvements for perf-probe.
> First 5 patches are new for fixing some minor issues on perf probe,
> and last 3 are for wildcard support which is just updates of the
> patches which I sent before ( https://lkml.org/lkml/2014/10/31/207 ).
> 
> I've dropped --output option since it will be done by perf-cache,
> but this series doesn't involve perf-cache feature yet. I found some
> issues when working on that and decided to send it beforehand.

Applied all but [6,8]/8, will do after you reply to those.

Tested most of them, added some comments with examples on using some.

Thanks,

- Arnaldo

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

* Re: [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions
  2015-05-06 15:52   ` Arnaldo Carvalho de Melo
@ 2015-05-06 23:22     ` Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: Masami Hiramatsu @ 2015-05-06 23:22 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: ananth, Peter Zijlstra, hemant, Linux Kernel Mailing List,
	David Ahern, namhyung, Jiri Olsa, Ingo Molnar

On 2015/05/07 0:52, Arnaldo Carvalho de Melo wrote:
> Em Wed, May 06, 2015 at 09:46:51PM +0900, Masami Hiramatsu escreveu:
>> Add --no-inlines(--inlines) option to avoid searching inline
>> functions.
>> Searching all functions which matches glob pattern can take a
>> long time and find a lot of inline functions. With this option
>> perf-probe searches target on the non-inlined functions.
>>
>>  
>>  		ret = add_perf_probe_events(params.events, params.nevents,
>>  					    params.max_probe_points,
>> -					    params.force_add);
>> +					    params.force_add,
>> +					    params.no_inlines);
> 
> So, there is just one call to this function, and all the parameters come
> from the 'param' struct, why not just pass it?

Hm, the reason why I don't do that is for readability in
util/probe-event.c side. Passing params to the callee involves
 - export params struct (not be static)
 - callee has to extract required parameters from params.
 - it makes obscure that what parameters will be used in the method.

However, it seems that some of them would be better global configs
like symbol_conf. I'd like to suggest to introduce probe_conf global
config. Is it OK ?

Thank you,

-- 
Masami HIRAMATSU
Linux Technology Research Center, System Productivity Research Dept.
Center for Technology Innovation - Systems Engineering
Hitachi, Ltd., Research & Development Group
E-mail: masami.hiramatsu.pt@hitachi.com

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

* [tip:perf/core] perf probe: Fix to close probe_events file in error
  2015-05-06 12:46 ` [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error Masami Hiramatsu
@ 2015-05-10  7:04   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, tglx, jolsa, hpa, linux-kernel, ananth,
	masami.hiramatsu.pt, peterz, mingo, namhyung, dsahern

Commit-ID:  ae2cb1ac60758e99cec15e9edd68e0d22bfd310e
Gitweb:     http://git.kernel.org/tip/ae2cb1ac60758e99cec15e9edd68e0d22bfd310e
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:40 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:01 -0300

perf probe: Fix to close probe_events file in error

Fix perf-probe to close probe_events file if it failed to get existing
probe's name. This also fix the return error code to -ENOMEM.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: hemant@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/20150506124640.4961.26062.stgit@localhost.localdomain
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 abf5845..230353f 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2384,7 +2384,8 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	namelist = get_probe_trace_event_names(fd, false);
 	if (!namelist) {
 		pr_debug("Failed to get current event list.\n");
-		return -EIO;
+		ret = -ENOMEM;
+		goto close_out;
 	}
 	/* Get kprobe blacklist if exists */
 	if (!pev->uprobes) {
@@ -2467,6 +2468,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 
 	kprobe_blacklist__delete(&blacklist);
 	strlist__delete(namelist);
+close_out:
 	close(fd);
 	return ret;
 }

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

* [tip:perf/core] perf probe: Fix a typo for the flags of open
  2015-05-06 12:46 ` [PATCH perf/core 2/8] [BUGFIX] perf probe: Fix a typo for the flags of open Masami Hiramatsu
@ 2015-05-10  7:04   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: linux-kernel, acme, dsahern, tglx, jolsa, mingo, namhyung, hpa,
	masami.hiramatsu.pt, ananth, peterz

Commit-ID:  b8dc3984c1fce87a36d3247c9f722229692bec72
Gitweb:     http://git.kernel.org/tip/b8dc3984c1fce87a36d3247c9f722229692bec72
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:42 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:01 -0300

perf probe: Fix a typo for the flags of open

Fix to pass O_APPEND by using bit-or with other flags, instead of
passing it as mode.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: hemant@linux.vnet.ibm.com
Link: http://lkml.kernel.org/r/20150506124642.4961.97878.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 230353f..63cb7c5 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1969,7 +1969,7 @@ static int open_probe_events(const char *trace_file, bool readwrite)
 	if (ret >= 0) {
 		pr_debug("Opening %s write=%d\n", buf, readwrite);
 		if (readwrite && !probe_event_dry_run)
-			ret = open(buf, O_RDWR, O_APPEND);
+			ret = open(buf, O_RDWR | O_APPEND, 0);
 		else
 			ret = open(buf, O_RDONLY, 0);
 

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

* [tip:perf/core] perf probe: Fix to return 0 when positive value returned
  2015-05-06 12:46 ` [PATCH perf/core 3/8] [BUGFIX] perf probe: Fix to return 0 when positive value returned Masami Hiramatsu
@ 2015-05-10  7:04   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, dsahern, ananth, peterz, tglx, hemant,
	namhyung, jolsa, hpa, mingo, masami.hiramatsu.pt

Commit-ID:  9bc9f3b6800e8de16f40a2da1d6ded3a391ea01a
Gitweb:     http://git.kernel.org/tip/9bc9f3b6800e8de16f40a2da1d6ded3a391ea01a
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:45 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:01 -0300

perf probe: Fix to return 0 when positive value returned

Fix to return 0 when positive value returned from probe command.

At least --vars can returns a positive value if it found a point.
  ----
  # perf probe --vars vfs_read && echo succeeded! || echo failed!
  Available variables at vfs_read
          @<vfs_read+0>
                  char*   buf
                  loff_t* pos
                  size_t  count
                  struct file*    file
  failed!
  ----

This fixes above problem.
  ----
  # perf probe --vars vfs_read && echo succeeded! || echo failed!
  Available variables at vfs_read
          @<vfs_read+0>
                  char*   buf
                  loff_t* pos
                  size_t  count
                  struct file*    file
  succeeded!
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150506124645.4961.56973.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-probe.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 53d475b..9c4cf5e 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -523,5 +523,5 @@ int cmd_probe(int argc, const char **argv, const char *prefix)
 		cleanup_params();
 	}
 
-	return ret;
+	return ret < 0 ? ret : 0;
 }

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

* [tip:perf/core] perf probe: Make --line checks validate C-style function name
  2015-05-06 12:46 ` [PATCH perf/core 4/8] [BUGFIX] perf probe: --line checks valid C-style function name Masami Hiramatsu
@ 2015-05-10  7:04   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:04 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: namhyung, peterz, linux-kernel, hpa, jolsa, hemant, acme, mingo,
	dsahern, ananth, tglx, masami.hiramatsu.pt

Commit-ID:  573709fdfd668423ba4202c4f1016e3cd7bdd134
Gitweb:     http://git.kernel.org/tip/573709fdfd668423ba4202c4f1016e3cd7bdd134
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:47 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:02 -0300

perf probe: Make --line checks validate C-style function name

Fix --line to check valid C-style function name and returns
a semantic error if it is not.

For example, previously, --line doesn't support lazy pattern
but it doesn't recognized as a semantic error.

  ----
  # perf probe -L 'func;return*:0-10'
  Specified source line is not found.
    Error: Failed to show lines.
  ----

With this patch, it is correctly handled as a semantic error.
  ----
  # perf probe -L 'func;return*:0-10'
  Semantic error :'func;return*' is not a valid function name.
  ...
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150506124647.4961.99473.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 35 ++++++++++++++++++++---------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 63cb7c5..4265f2e 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -980,6 +980,18 @@ static int parse_line_num(char **ptr, int *val, const char *what)
 	return 0;
 }
 
+/* Check the name is good for event, group or function */
+static bool is_c_func_name(const char *name)
+{
+	if (!isalpha(*name) && *name != '_')
+		return false;
+	while (*++name != '\0') {
+		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
+			return false;
+	}
+	return true;
+}
+
 /*
  * Stuff 'lr' according to the line range described by 'arg'.
  * The line range syntax is described by:
@@ -1048,10 +1060,15 @@ int parse_line_range_desc(const char *arg, struct line_range *lr)
 			goto err;
 		}
 		lr->function = name;
-	} else if (strchr(name, '.'))
+	} else if (strchr(name, '/') || strchr(name, '.'))
 		lr->file = name;
-	else
+	else if (is_c_func_name(name))/* We reuse it for checking funcname */
 		lr->function = name;
+	else {	/* Invalid name */
+		semantic_error("'%s' is not a valid function name.\n", name);
+		err = -EINVAL;
+		goto err;
+	}
 
 	return 0;
 err:
@@ -1059,18 +1076,6 @@ err:
 	return err;
 }
 
-/* Check the name is good for event/group */
-static bool check_event_name(const char *name)
-{
-	if (!isalpha(*name) && *name != '_')
-		return false;
-	while (*++name != '\0') {
-		if (!isalpha(*name) && !isdigit(*name) && *name != '_')
-			return false;
-	}
-	return true;
-}
-
 /* Parse probepoint definition. */
 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 {
@@ -1094,7 +1099,7 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 			semantic_error("Group name is not supported yet.\n");
 			return -ENOTSUP;
 		}
-		if (!check_event_name(arg)) {
+		if (!is_c_func_name(arg)) {
 			semantic_error("%s is bad for event name -it must "
 				       "follow C symbol-naming rule.\n", arg);
 			return -EINVAL;

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

* [tip:perf/core] perf probe: Skip kernel symbols which is out of .text
  2015-05-06 12:46 ` [PATCH perf/core 5/8] perf probe: Skip kernel symbols which is out of .text Masami Hiramatsu
@ 2015-05-10  7:05   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: jolsa, ananth, tglx, namhyung, hemant, acme, peterz, mingo,
	linux-kernel, dsahern, hpa, masami.hiramatsu.pt

Commit-ID:  5a51fcd1f30c0f93bb54cec7201a3690032470cb
Gitweb:     http://git.kernel.org/tip/5a51fcd1f30c0f93bb54cec7201a3690032470cb
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:49 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:02 -0300

perf probe: Skip kernel symbols which is out of .text

Skip the kernel symbols which is out of .text, e.g. the functions
in .inittext. Those are found in debuginfo/kallsyms, but already
freed from memory.

e.g.
  ----
  # perf probe vfs_caches_init
  vfs_caches_init+0 is out of .text, skip it.
  Probe point 'vfs_caches_init' not found.
    Error: Failed to add events.
  ----

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150506124649.4961.56249.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c | 31 ++++++++++++++++++++++++-------
 1 file changed, 24 insertions(+), 7 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 4265f2e..37a3a8b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -557,8 +557,9 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 					   bool uprobe)
 {
 	struct ref_reloc_sym *reloc_sym;
+	u64 etext_addr;
 	char *tmp;
-	int i;
+	int i, skipped = 0;
 
 	if (uprobe)
 		return add_exec_to_probe_trace_events(tevs, ntevs, module);
@@ -572,19 +573,29 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs,
 		pr_warning("Relocated base symbol is not found!\n");
 		return -EINVAL;
 	}
+	/* Get the address of _etext for checking non-probable text symbol */
+	etext_addr = kernel_get_symbol_address_by_name("_etext", false);
 
 	for (i = 0; i < ntevs; i++) {
 		if (tevs[i].point.address && !tevs[i].point.retprobe) {
-			tmp = strdup(reloc_sym->name);
-			if (!tmp)
-				return -ENOMEM;
+			/* If we found a wrong one, mark it by NULL symbol */
+			if (etext_addr < tevs[i].point.address) {
+				pr_warning("%s+%lu is out of .text, skip it.\n",
+				   tevs[i].point.symbol, tevs[i].point.offset);
+				tmp = NULL;
+				skipped++;
+			} else {
+				tmp = strdup(reloc_sym->name);
+				if (!tmp)
+					return -ENOMEM;
+			}
 			free(tevs[i].point.symbol);
 			tevs[i].point.symbol = tmp;
 			tevs[i].point.offset = tevs[i].point.address -
 					       reloc_sym->unrelocated_addr;
 		}
 	}
-	return 0;
+	return skipped;
 }
 
 /* Try to find perf_probe_event with debuginfo */
@@ -630,11 +641,14 @@ static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
 		pr_debug("Found %d probe_trace_events.\n", ntevs);
 		ret = post_process_probe_trace_events(*tevs, ntevs,
 							target, pev->uprobes);
-		if (ret < 0) {
+		if (ret < 0 || ret == ntevs) {
 			clear_probe_trace_events(*tevs, ntevs);
 			zfree(tevs);
 		}
-		return ret < 0 ? ret : ntevs;
+		if (ret != ntevs)
+			return ret < 0 ? ret : ntevs;
+		ntevs = 0;
+		/* Fall through */
 	}
 
 	if (ntevs == 0)	{	/* No error but failed to find probe point. */
@@ -2403,6 +2417,9 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,
 	pr_info("Added new event%s\n", (ntevs > 1) ? "s:" : ":");
 	for (i = 0; i < ntevs; i++) {
 		tev = &tevs[i];
+		/* Skip if the symbol is out of .text (marked previously) */
+		if (!tev->point.symbol)
+			continue;
 		/* Ensure that the address is NOT blacklisted */
 		node = kprobe_blacklist__find_by_address(&blacklist,
 							 tev->point.address);

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

* [tip:perf/core] perf probe: Support $params special probe argument
  2015-05-06 12:46 ` [PATCH perf/core 7/8] perf-probe: Support $params special probe argument Masami Hiramatsu
@ 2015-05-10  7:05   ` tip-bot for Masami Hiramatsu
  0 siblings, 0 replies; 18+ messages in thread
From: tip-bot for Masami Hiramatsu @ 2015-05-10  7:05 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: mingo, linux-kernel, ananth, namhyung, jolsa, tglx, hpa, dsahern,
	hemant, masami.hiramatsu.pt, acme, peterz

Commit-ID:  f8bffbf1222a64336a81974fc25fe846656ac53e
Gitweb:     http://git.kernel.org/tip/f8bffbf1222a64336a81974fc25fe846656ac53e
Author:     Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
AuthorDate: Wed, 6 May 2015 21:46:53 +0900
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Fri, 8 May 2015 16:05:03 -0300

perf probe: Support $params special probe argument

$params is similar to $vars but matches only function parameters not
local variables.

Thus, this is useful for tracing function parameter changing or tracing
function call with parameters.

Testing it:

 # perf probe tcp_sendmsg '$params'
 Added new event:
  probe:tcp_sendmsg    (on tcp_sendmsg with $params)

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

	perf record -e probe:tcp_sendmsg -aR sleep 1

 # perf probe -l
  probe:tcp_sendmsg    (on tcp_sendmsg@acme/git/linux/net/ipv4/tcp.c with iocb sk msg size)
 # perf record -a -e probe:*
 press some random letters to generate TCP (sshd) traffic...

 ^C[ perf record: Woken up 1 times to write data ]
 [ perf record: Captured and wrote 0.223 MB perf.data (6 samples) ]

 # perf script
   sshd 6385 [2] 3.907529: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
   sshd 6385 [2] 4.138973: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
   sshd 6385 [2] 4.378966: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
   sshd 6385 [2] 4.603681: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
   sshd 6385 [2] 4.818455: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
   sshd 6385 [2] 5.043603: probe:tcp_sendmsg: iocb=0xffff8800ac4cfe70 sk=0xffff88042196c140 msg=0xffff8800ac4cfda8 size=0x24
 # cat /sys/kernel/debug/tracing/events/probe/tcp_sendmsg/format
 name: tcp_sendmsg
 ID: 1927
 format:
   field:unsigned short common_type;	offset:0;	size:2;	signed:0;
   field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
   field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
   field:int common_pid;	offset:4;	size:4;	signed:1;

   field:unsigned long __probe_ip;	offset:8;	size:8;	signed:0;
   field:u64 iocb;	offset:16;	size:8;	signed:0;
   field:u64 sk;	offset:24;	size:8;	signed:0;
   field:u64 msg;	offset:32;	size:8;	signed:0;
   field:u64 size;	offset:40;	size:8;	signed:0;

 print fmt: "(%lx) iocb=0x%Lx sk=0x%Lx msg=0x%Lx size=0x%Lx", REC->__probe_ip, REC->iocb, REC->sk, REC->msg, REC->size
 #

 Do some system wide tracing of this probe + write syscalls:

 # perf trace -e write --ev probe:* --filter-pids 6385
  462.612 (0.010 ms): bash/19153 write(fd: 1</dev/pts/1>, buf: 0x7f7556c78000, count: 29               ) = 29
  462.701 (0.027 ms): sshd/19152 write(fd: 3<socket:[63117]>, buf: 0x7f78dd12e160, count: 68           ) ...
  462.701 (        ): probe:tcp_sendmsg:(ffffffff8163db30) iocb=0xffff8803ebec7e70 sk=0xffff88042196ab80 msg=0xffff8803ebec7da8 size=0x44)
  462.710 (0.035 ms): sshd/19152  ... [continued]: write()) = 68
  462.787 (0.009 ms): bash/19153 write(fd: 2</dev/pts/1>, buf: 0x7f7556c77000, count: 22               ) = 22
  462.865 (0.002 ms): sshd/19152 write(fd: 3<socket:[63117]>, buf: 0x7f78dd12e160, count: 68           ) ...
  462.865 (        ): probe:tcp_sendmsg:(ffffffff8163db30) iocb=0xffff8803ebec7e70 sk=0xffff88042196ab80 msg=0xffff8803ebec7da8 size=0x44)
  462.873 (0.010 ms): sshd/19152  ... [continued]: write()) = 68

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hemant Kumar <hemant@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20150506124653.4961.59806.stgit@localhost.localdomain
[ Add some examples to the changelog message showing how to use it ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/perf-probe.txt |  2 +-
 tools/perf/util/probe-finder.c          | 29 ++++++++++++++++-------------
 tools/perf/util/probe-finder.h          |  3 +++
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index a272f2e..ad3e355 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -151,7 +151,7 @@ Each probe argument follows below syntax.
  [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
 
 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
-'$vars' special argument is also available for NAME, it is expanded to the local variables which can access at given probe point.
+'$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters.
 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. You can specify 'string' type only for the local variable or structure member which is an array of or a pointer to 'char' or 'unsigned char' type.
 
 On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid.
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index b5bf9d5..63d3389 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1087,6 +1087,7 @@ found:
 struct local_vars_finder {
 	struct probe_finder *pf;
 	struct perf_probe_arg *args;
+	bool vars;
 	int max_args;
 	int nargs;
 	int ret;
@@ -1101,7 +1102,7 @@ static int copy_variables_cb(Dwarf_Die *die_mem, void *data)
 
 	tag = dwarf_tag(die_mem);
 	if (tag == DW_TAG_formal_parameter ||
-	    tag == DW_TAG_variable) {
+	    (tag == DW_TAG_variable && vf->vars)) {
 		if (convert_variable_location(die_mem, vf->pf->addr,
 					      vf->pf->fb_ops, &pf->sp_die,
 					      NULL) == 0) {
@@ -1127,26 +1128,28 @@ static int expand_probe_args(Dwarf_Die *sc_die, struct probe_finder *pf,
 	Dwarf_Die die_mem;
 	int i;
 	int n = 0;
-	struct local_vars_finder vf = {.pf = pf, .args = args,
+	struct local_vars_finder vf = {.pf = pf, .args = args, .vars = false,
 				.max_args = MAX_PROBE_ARGS, .ret = 0};
 
 	for (i = 0; i < pf->pev->nargs; i++) {
 		/* var never be NULL */
-		if (strcmp(pf->pev->args[i].var, "$vars") == 0) {
-			pr_debug("Expanding $vars into:");
-			vf.nargs = n;
-			/* Special local variables */
-			die_find_child(sc_die, copy_variables_cb, (void *)&vf,
-				       &die_mem);
-			pr_debug(" (%d)\n", vf.nargs - n);
-			if (vf.ret < 0)
-				return vf.ret;
-			n = vf.nargs;
-		} else {
+		if (strcmp(pf->pev->args[i].var, PROBE_ARG_VARS) == 0)
+			vf.vars = true;
+		else if (strcmp(pf->pev->args[i].var, PROBE_ARG_PARAMS) != 0) {
 			/* Copy normal argument */
 			args[n] = pf->pev->args[i];
 			n++;
+			continue;
 		}
+		pr_debug("Expanding %s into:", pf->pev->args[i].var);
+		vf.nargs = n;
+		/* Special local variables */
+		die_find_child(sc_die, copy_variables_cb, (void *)&vf,
+			       &die_mem);
+		pr_debug(" (%d)\n", vf.nargs - n);
+		if (vf.ret < 0)
+			return vf.ret;
+		n = vf.nargs;
 	}
 	return n;
 }
diff --git a/tools/perf/util/probe-finder.h b/tools/perf/util/probe-finder.h
index ebf8c8c..f53553d 100644
--- a/tools/perf/util/probe-finder.h
+++ b/tools/perf/util/probe-finder.h
@@ -10,6 +10,9 @@
 #define MAX_PROBES		 128
 #define MAX_PROBE_ARGS		 128
 
+#define PROBE_ARG_VARS		"$vars"
+#define PROBE_ARG_PARAMS	"$params"
+
 static inline int is_c_varname(const char *name)
 {
 	/* TODO */

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

end of thread, other threads:[~2015-05-10  7:06 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 12:46 [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 1/8] [BUGFIX] perf probe: Fix to close probe_events file in error Masami Hiramatsu
2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 2/8] [BUGFIX] perf probe: Fix a typo for the flags of open Masami Hiramatsu
2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 3/8] [BUGFIX] perf probe: Fix to return 0 when positive value returned Masami Hiramatsu
2015-05-10  7:04   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 4/8] [BUGFIX] perf probe: --line checks valid C-style function name Masami Hiramatsu
2015-05-10  7:04   ` [tip:perf/core] perf probe: Make --line checks validate " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 5/8] perf probe: Skip kernel symbols which is out of .text Masami Hiramatsu
2015-05-10  7:05   ` [tip:perf/core] " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 6/8] perf-probe: Add --no-inlines option to avoid searching inline functions Masami Hiramatsu
2015-05-06 15:52   ` Arnaldo Carvalho de Melo
2015-05-06 23:22     ` Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 7/8] perf-probe: Support $params special probe argument Masami Hiramatsu
2015-05-10  7:05   ` [tip:perf/core] perf probe: " tip-bot for Masami Hiramatsu
2015-05-06 12:46 ` [PATCH perf/core 8/8] perf-probe: Support glob wildcards for function name Masami Hiramatsu
2015-05-06 16:19 ` [PATCH perf/core 0/8] perf-probe bugfixes and support wildcard for probe points 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).