From f76ec438d205bbdc124c16b409132c280c5aebff Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Thu, 20 Jan 2011 23:15:39 +0900 Subject: [PATCH] --- yaml --- r: 234367 b: refs/heads/master c: bd09d7b5efeb13965b6725b4a3e9944908bca9d2 h: refs/heads/master i: 234365: 8fdb8a6681bad898f0859503cd55600774c077fa 234363: f7791a2116ae178ea98083e983c2d7fefb25a9d9 234359: 56bf440618c077775c0da49661c214dbc94eed71 234351: c9ea4f158212b00f6fa1333f32521847fa43af86 234335: f084cd5f1f42168f4bbd5538d4838eaa4456d648 234303: 04a31174d48859aad9b3a8fa748fc35c80831c48 234239: c36f953c61472c01e8877eb1b9a0847441a90f60 v: v3 --- [refs] | 2 +- trunk/tools/perf/Documentation/perf-probe.txt | 14 ++++ trunk/tools/perf/builtin-probe.c | 34 ++++++++++ trunk/tools/perf/util/probe-event.c | 66 +++++++++++-------- trunk/tools/perf/util/probe-event.h | 3 +- 5 files changed, 91 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index ae8586c5c4b7..4d77c568779c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 68baa431ec2f14ba7510d4e79bceb6ceaf0d3b74 +refs/heads/master: bd09d7b5efeb13965b6725b4a3e9944908bca9d2 diff --git a/trunk/tools/perf/Documentation/perf-probe.txt b/trunk/tools/perf/Documentation/perf-probe.txt index fcc51fe0195c..32fb18f1695d 100644 --- a/trunk/tools/perf/Documentation/perf-probe.txt +++ b/trunk/tools/perf/Documentation/perf-probe.txt @@ -77,6 +77,12 @@ OPTIONS --funcs:: Show available functions in given module or kernel. +--filter=FILTER:: + (Only for --vars) Set filter for variables. FILTER is a combination of + glob pattern, see FILTER PATTERN for details. + Default FILTER is "!__k???tab_* & !__crc_*". + If several filters are specified, only the last filter is valid. + -f:: --force:: Forcibly add events with existing name. @@ -139,6 +145,14 @@ e.g. This provides some sort of flexibility and robustness to probe point definitions against minor code changes. For example, actual 10th line of schedule() can be moved easily by modifying schedule(), but the same line matching 'rq=cpu_rq*' may still exist in the function.) +FILTER PATTERN +-------------- + The filter pattern is a glob matching pattern(s) to filter variables. + In addition, you can use "!" for specifying filter-out rule. You also can give several rules combined with "&" or "|", and fold those rules as one rule by using "(" ")". + +e.g. + With --filter "foo* | bar*", perf probe -V shows variables which start with "foo" or "bar". + With --filter "!foo* & *bar", perf probe -V shows variables which don't start with "foo" and end with "bar", like "fizzbar". But "foobar" is filtered out. EXAMPLES -------- diff --git a/trunk/tools/perf/builtin-probe.c b/trunk/tools/perf/builtin-probe.c index 6cf708aba7c9..abb423e164c8 100644 --- a/trunk/tools/perf/builtin-probe.c +++ b/trunk/tools/perf/builtin-probe.c @@ -36,6 +36,7 @@ #include "builtin.h" #include "util/util.h" #include "util/strlist.h" +#include "util/strfilter.h" #include "util/symbol.h" #include "util/debug.h" #include "util/debugfs.h" @@ -43,6 +44,7 @@ #include "util/probe-finder.h" #include "util/probe-event.h" +#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*" #define MAX_PATH_LEN 256 /* Session management structure */ @@ -60,6 +62,7 @@ static struct { struct line_range line_range; const char *target_module; int max_probe_points; + struct strfilter *filter; } params; /* Parse an event definition. Note that any error must die. */ @@ -156,6 +159,27 @@ static int opt_show_vars(const struct option *opt __used, return ret; } + +static int opt_set_filter(const struct option *opt __used, + const char *str, int unset __used) +{ + const char *err; + + if (str) { + pr_debug2("Set filter: %s\n", str); + if (params.filter) + strfilter__delete(params.filter); + params.filter = strfilter__new(str, &err); + if (!params.filter) { + pr_err("Filter parse error at %ld.\n", err - str + 1); + pr_err("Source: \"%s\"\n", str); + pr_err(" %*c\n", (int)(err - str + 1), '^'); + return -EINVAL; + } + } + + return 0; +} #endif static const char * const probe_usage[] = { @@ -212,6 +236,10 @@ static const struct option options[] = { "Show accessible variables on PROBEDEF", opt_show_vars), OPT_BOOLEAN('\0', "externs", ¶ms.show_ext_vars, "Show external variables too (with --vars only)"), + OPT_CALLBACK('\0', "filter", NULL, + "[!]FILTER", "Set a variable filter (with --vars only)\n" + "\t\t\t(default: \"" DEFAULT_VAR_FILTER "\")", + opt_set_filter), OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, "file", "vmlinux pathname"), OPT_STRING('s', "source", &symbol_conf.source_prefix, @@ -324,10 +352,16 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) " --add/--del.\n"); usage_with_options(probe_usage, options); } + if (!params.filter) + params.filter = strfilter__new(DEFAULT_VAR_FILTER, + NULL); + ret = show_available_vars(params.events, params.nevents, params.max_probe_points, params.target_module, + params.filter, params.show_ext_vars); + strfilter__delete(params.filter); if (ret < 0) pr_err(" Error: Failed to show vars. (%d)\n", ret); return ret; diff --git a/trunk/tools/perf/util/probe-event.c b/trunk/tools/perf/util/probe-event.c index 859d377a3df3..077e0518f0f7 100644 --- a/trunk/tools/perf/util/probe-event.c +++ b/trunk/tools/perf/util/probe-event.c @@ -451,12 +451,14 @@ int show_line_range(struct line_range *lr, const char *module) } static int show_available_vars_at(int fd, struct perf_probe_event *pev, - int max_vls, bool externs) + int max_vls, struct strfilter *_filter, + bool externs) { char *buf; - int ret, i; + int ret, i, nvars; struct str_node *node; struct variable_list *vls = NULL, *vl; + const char *var; buf = synthesize_perf_probe_point(&pev->point); if (!buf) @@ -464,36 +466,45 @@ static int show_available_vars_at(int fd, struct perf_probe_event *pev, pr_debug("Searching variables at %s\n", buf); ret = find_available_vars_at(fd, pev, &vls, max_vls, externs); - if (ret > 0) { - /* Some variables were found */ - fprintf(stdout, "Available variables at %s\n", buf); - for (i = 0; i < ret; i++) { - vl = &vls[i]; - /* - * A probe point might be converted to - * several trace points. - */ - fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, - vl->point.offset); - free(vl->point.symbol); - if (vl->vars) { - strlist__for_each(node, vl->vars) + if (ret <= 0) { + pr_err("Failed to find variables at %s (%d)\n", buf, ret); + goto end; + } + /* Some variables are found */ + fprintf(stdout, "Available variables at %s\n", buf); + for (i = 0; i < ret; i++) { + vl = &vls[i]; + /* + * A probe point might be converted to + * several trace points. + */ + fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, + vl->point.offset); + free(vl->point.symbol); + nvars = 0; + if (vl->vars) { + strlist__for_each(node, vl->vars) { + var = strchr(node->s, '\t') + 1; + if (strfilter__compare(_filter, var)) { fprintf(stdout, "\t\t%s\n", node->s); - strlist__delete(vl->vars); - } else - fprintf(stdout, "(No variables)\n"); + nvars++; + } + } + strlist__delete(vl->vars); } - free(vls); - } else - pr_err("Failed to find variables at %s (%d)\n", buf, ret); - + if (nvars == 0) + fprintf(stdout, "\t\t(No matched variables)\n"); + } + free(vls); +end: free(buf); return ret; } /* Show available variables on given probe point */ int show_available_vars(struct perf_probe_event *pevs, int npevs, - int max_vls, const char *module, bool externs) + int max_vls, const char *module, + struct strfilter *_filter, bool externs) { int i, fd, ret = 0; @@ -510,7 +521,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, setup_pager(); for (i = 0; i < npevs && ret >= 0; i++) - ret = show_available_vars_at(fd, &pevs[i], max_vls, externs); + ret = show_available_vars_at(fd, &pevs[i], max_vls, _filter, + externs); close(fd); return ret; @@ -556,7 +568,9 @@ int show_line_range(struct line_range *lr __unused, const char *module __unused) int show_available_vars(struct perf_probe_event *pevs __unused, int npevs __unused, int max_vls __unused, - const char *module __unused, bool externs __unused) + const char *module __unused, + struct strfilter *filter __unused, + bool externs __unused) { pr_warning("Debuginfo-analysis is not supported.\n"); return -ENOSYS; diff --git a/trunk/tools/perf/util/probe-event.h b/trunk/tools/perf/util/probe-event.h index 1fb4f18337d3..4e80b2bbc516 100644 --- a/trunk/tools/perf/util/probe-event.h +++ b/trunk/tools/perf/util/probe-event.h @@ -3,6 +3,7 @@ #include #include "strlist.h" +#include "strfilter.h" extern bool probe_event_dry_run; @@ -126,7 +127,7 @@ extern int show_perf_probe_events(void); extern int show_line_range(struct line_range *lr, const char *module); extern int show_available_vars(struct perf_probe_event *pevs, int npevs, int max_probe_points, const char *module, - bool externs); + struct strfilter *filter, bool externs); extern int show_available_funcs(const char *module);