aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2016-07-12 06:04:43 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-07-13 22:09:05 -0400
commit36a009fe07bdecd201335f982babb8af34b603e2 (patch)
tree5fbbcbbe1835c309924aa8be8f05580ea3814eef
parentf6eb0518f325ef0d6557fbef5c7ebe48a81e74db (diff)
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>
-rw-r--r--tools/perf/Documentation/perf-probe.txt9
-rw-r--r--tools/perf/util/probe-event.c82
-rw-r--r--tools/perf/util/probe-event.h1
-rw-r--r--tools/perf/util/probe-file.c9
4 files changed, 76 insertions, 25 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index 7a258e953252..39e387042098 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.
151 3) Define event based on source file with lazy pattern 151 3) Define event based on source file with lazy pattern
152 [[GROUP:]EVENT=]SRC;PTN [ARG ...] 152 [[GROUP:]EVENT=]SRC;PTN [ARG ...]
153 153
154 4) Pre-defined SDT events or cached event with name
155 %[PROVIDER:]SDTEVENT
154 156
155'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. 157'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.
156Note 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 158Note 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.
158'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. 160'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.
159It 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. 161It 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.
160'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT). 162'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT).
163'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.
164Note 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.
165
166For details of the SDT, see below.
167https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
161 168
162PROBE ARGUMENT 169PROBE ARGUMENT
163-------------- 170--------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
237 244
238SEE ALSO 245SEE ALSO
239-------- 246--------
240linkperf:perf-trace[1], linkperf:perf-record[1] 247linkperf: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 fef9768df429..85f25d41cf8d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1197,6 +1197,34 @@ err:
1197 return err; 1197 return err;
1198} 1198}
1199 1199
1200static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev)
1201{
1202 char *ptr;
1203
1204 ptr = strchr(*arg, ':');
1205 if (ptr) {
1206 *ptr = '\0';
1207 if (!is_c_func_name(*arg))
1208 goto ng_name;
1209 pev->group = strdup(*arg);
1210 if (!pev->group)
1211 return -ENOMEM;
1212 *arg = ptr + 1;
1213 } else
1214 pev->group = NULL;
1215 if (!is_c_func_name(*arg)) {
1216ng_name:
1217 semantic_error("%s is bad for event name -it must "
1218 "follow C symbol-naming rule.\n", *arg);
1219 return -EINVAL;
1220 }
1221 pev->event = strdup(*arg);
1222 if (pev->event == NULL)
1223 return -ENOMEM;
1224
1225 return 0;
1226}
1227
1200/* Parse probepoint definition. */ 1228/* Parse probepoint definition. */
1201static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 1229static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1202{ 1230{
@@ -1204,38 +1232,43 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
1204 char *ptr, *tmp; 1232 char *ptr, *tmp;
1205 char c, nc = 0; 1233 char c, nc = 0;
1206 bool file_spec = false; 1234 bool file_spec = false;
1235 int ret;
1236
1207 /* 1237 /*
1208 * <Syntax> 1238 * <Syntax>
1209 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN] 1239 * perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
1210 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 1240 * perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
1241 * perf probe %[GRP:]SDT_EVENT
1211 */ 1242 */
1212 if (!arg) 1243 if (!arg)
1213 return -EINVAL; 1244 return -EINVAL;
1214 1245
1246 if (arg[0] == '%') {
1247 pev->sdt = true;
1248 arg++;
1249 }
1250
1215 ptr = strpbrk(arg, ";=@+%"); 1251 ptr = strpbrk(arg, ";=@+%");
1216 if (ptr && *ptr == '=') { /* Event name */ 1252 if (pev->sdt) {
1217 *ptr = '\0';
1218 tmp = ptr + 1;
1219 ptr = strchr(arg, ':');
1220 if (ptr) { 1253 if (ptr) {
1221 *ptr = '\0'; 1254 semantic_error("%s must contain only an SDT event name.\n", arg);
1222 if (!is_c_func_name(arg))
1223 goto not_fname;
1224 pev->group = strdup(arg);
1225 if (!pev->group)
1226 return -ENOMEM;
1227 arg = ptr + 1;
1228 } else
1229 pev->group = NULL;
1230 if (!is_c_func_name(arg)) {
1231not_fname:
1232 semantic_error("%s is bad for event name -it must "
1233 "follow C symbol-naming rule.\n", arg);
1234 return -EINVAL; 1255 return -EINVAL;
1235 } 1256 }
1236 pev->event = strdup(arg); 1257 ret = parse_perf_probe_event_name(&arg, pev);
1237 if (pev->event == NULL) 1258 if (ret == 0) {
1238 return -ENOMEM; 1259 if (asprintf(&pev->point.function, "%%%s", pev->event) < 0)
1260 ret = -errno;
1261 }
1262 return ret;
1263 }
1264
1265 if (ptr && *ptr == '=') { /* Event name */
1266 *ptr = '\0';
1267 tmp = ptr + 1;
1268 ret = parse_perf_probe_event_name(&arg, pev);
1269 if (ret < 0)
1270 return ret;
1271
1239 arg = tmp; 1272 arg = tmp;
1240 } 1273 }
1241 1274
@@ -2876,7 +2909,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
2876 2909
2877 entry = probe_cache__find(cache, pev); 2910 entry = probe_cache__find(cache, pev);
2878 if (!entry) { 2911 if (!entry) {
2879 ret = 0; 2912 /* SDT must be in the cache */
2913 ret = pev->sdt ? -ENOENT : 0;
2880 goto out; 2914 goto out;
2881 } 2915 }
2882 2916
@@ -2915,7 +2949,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2915{ 2949{
2916 int ret; 2950 int ret;
2917 2951
2918 if (!pev->group) { 2952 if (!pev->group && !pev->sdt) {
2919 /* Set group name if not given */ 2953 /* Set group name if not given */
2920 if (!pev->uprobes) { 2954 if (!pev->uprobes) {
2921 pev->group = strdup(PERFPROBE_GROUP); 2955 pev->group = strdup(PERFPROBE_GROUP);
@@ -2934,8 +2968,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
2934 2968
2935 /* At first, we need to lookup cache entry */ 2969 /* At first, we need to lookup cache entry */
2936 ret = find_probe_trace_events_from_cache(pev, tevs); 2970 ret = find_probe_trace_events_from_cache(pev, tevs);
2937 if (ret > 0) 2971 if (ret > 0 || pev->sdt) /* SDT can be found only in the cache */
2938 return ret; /* Found in probe cache */ 2972 return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
2939 2973
2940 if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) { 2974 if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
2941 ret = find_probe_trace_events_from_map(pev, tevs); 2975 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 432b690d3f17..e18ea9fe6385 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -85,6 +85,7 @@ struct perf_probe_event {
85 char *group; /* Group name */ 85 char *group; /* Group name */
86 struct perf_probe_point point; /* Probe point */ 86 struct perf_probe_point point; /* Probe point */
87 int nargs; /* Number of arguments */ 87 int nargs; /* Number of arguments */
88 bool sdt; /* SDT/cached event flag */
88 bool uprobes; /* Uprobe event flag */ 89 bool uprobes; /* Uprobe event flag */
89 char *target; /* Target binary */ 90 char *target; /* Target binary */
90 struct perf_probe_arg *args; /* Arguments */ 91 struct perf_probe_arg *args; /* Arguments */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index e705a742ee1e..fc16b172579f 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)
547 return NULL; 547 return NULL;
548 548
549 list_for_each_entry(entry, &pcache->entries, node) { 549 list_for_each_entry(entry, &pcache->entries, node) {
550 if (pev->sdt) {
551 if (entry->pev.event &&
552 streql(entry->pev.event, pev->event) &&
553 (!pev->group ||
554 streql(entry->pev.group, pev->group)))
555 goto found;
556
557 continue;
558 }
550 /* Hit if same event name or same command-string */ 559 /* Hit if same event name or same command-string */
551 if ((pev->event && 560 if ((pev->event &&
552 (streql(entry->pev.group, pev->group) && 561 (streql(entry->pev.group, pev->group) &&