Skip to content

Commit 36a009f

Browse files
mhiramathitachiacmel
authored andcommitted
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 <[email protected]> Signed-off-by: Masami Hiramatsu <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Ananth N Mavinakayanahalli <[email protected]> Cc: Brendan Gregg <[email protected]> Cc: Hemant Kumar <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/146831788372.17065.3645054540325909346.stgit@devbox Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent f6eb051 commit 36a009f

File tree

4 files changed

+76
-25
lines changed

4 files changed

+76
-25
lines changed

tools/perf/Documentation/perf-probe.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,20 @@ Probe points are defined by following syntax.
151151
3) Define event based on source file with lazy pattern
152152
[[GROUP:]EVENT=]SRC;PTN [ARG ...]
153153

154+
4) Pre-defined SDT events or cached event with name
155+
%[PROVIDER:]SDTEVENT
154156

155157
'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.
156158
Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
157159
modules.
158160
'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.
159161
It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern.
160162
'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.
164+
Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events.
165+
166+
For details of the SDT, see below.
167+
https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
161168

162169
PROBE ARGUMENT
163170
--------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc
237244

238245
SEE ALSO
239246
--------
240-
linkperf:perf-trace[1], linkperf:perf-record[1]
247+
linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]

tools/perf/util/probe-event.c

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,45 +1197,78 @@ int parse_line_range_desc(const char *arg, struct line_range *lr)
11971197
return err;
11981198
}
11991199

1200+
static 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)) {
1216+
ng_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+
12001228
/* Parse probepoint definition. */
12011229
static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
12021230
{
12031231
struct perf_probe_point *pp = &pev->point;
12041232
char *ptr, *tmp;
12051233
char c, nc = 0;
12061234
bool file_spec = false;
1235+
int ret;
1236+
12071237
/*
12081238
* <Syntax>
12091239
* perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
12101240
* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
1241+
* perf probe %[GRP:]SDT_EVENT
12111242
*/
12121243
if (!arg)
12131244
return -EINVAL;
12141245

1246+
if (arg[0] == '%') {
1247+
pev->sdt = true;
1248+
arg++;
1249+
}
1250+
12151251
ptr = strpbrk(arg, ";=@+%");
1216-
if (ptr && *ptr == '=') { /* Event name */
1217-
*ptr = '\0';
1218-
tmp = ptr + 1;
1219-
ptr = strchr(arg, ':');
1252+
if (pev->sdt) {
12201253
if (ptr) {
1221-
*ptr = '\0';
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)) {
1231-
not_fname:
1232-
semantic_error("%s is bad for event name -it must "
1233-
"follow C symbol-naming rule.\n", arg);
1254+
semantic_error("%s must contain only an SDT event name.\n", arg);
12341255
return -EINVAL;
12351256
}
1236-
pev->event = strdup(arg);
1237-
if (pev->event == NULL)
1238-
return -ENOMEM;
1257+
ret = parse_perf_probe_event_name(&arg, pev);
1258+
if (ret == 0) {
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+
12391272
arg = tmp;
12401273
}
12411274

@@ -2876,7 +2909,8 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,
28762909

28772910
entry = probe_cache__find(cache, pev);
28782911
if (!entry) {
2879-
ret = 0;
2912+
/* SDT must be in the cache */
2913+
ret = pev->sdt ? -ENOENT : 0;
28802914
goto out;
28812915
}
28822916

@@ -2915,7 +2949,7 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
29152949
{
29162950
int ret;
29172951

2918-
if (!pev->group) {
2952+
if (!pev->group && !pev->sdt) {
29192953
/* Set group name if not given */
29202954
if (!pev->uprobes) {
29212955
pev->group = strdup(PERFPROBE_GROUP);
@@ -2934,8 +2968,8 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
29342968

29352969
/* At first, we need to lookup cache entry */
29362970
ret = find_probe_trace_events_from_cache(pev, tevs);
2937-
if (ret > 0)
2938-
return ret; /* Found in probe cache */
2971+
if (ret > 0 || pev->sdt) /* SDT can be found only in the cache */
2972+
return ret == 0 ? -ENOENT : ret; /* Found in probe cache */
29392973

29402974
if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
29412975
ret = find_probe_trace_events_from_map(pev, tevs);

tools/perf/util/probe-event.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct perf_probe_event {
8585
char *group; /* Group name */
8686
struct perf_probe_point point; /* Probe point */
8787
int nargs; /* Number of arguments */
88+
bool sdt; /* SDT/cached event flag */
8889
bool uprobes; /* Uprobe event flag */
8990
char *target; /* Target binary */
9091
struct perf_probe_arg *args; /* Arguments */

tools/perf/util/probe-file.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)
547547
return NULL;
548548

549549
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+
}
550559
/* Hit if same event name or same command-string */
551560
if ((pev->event &&
552561
(streql(entry->pev.group, pev->group) &&

0 commit comments

Comments
 (0)