perf-probe --cache and SDT support
cover perf-probe --cache and SDT support
Hi,
Here is the 14th version of the patchset for probe-cache and initial SDT support.
Here is the previous v13: https://lkml.org/lkml/2016/7/1/133
This version includes patches which not merged yet. This also adds a bugfix;
- [1/10] Resend the bugfix patch which was sent 4th July.
(https://lkml.org/lkml/2016/7/3/217)
Thank you,
---
Masami Hiramatsu (10):
[BUGFIX] perf-probe: Fix to show correct error message for $vars and $params perf probe: Accept %sdt and %cached event name
perf-probe: Make --list shows only available cached events
perf: probe-cache: Add for_each_probe_cache_entry() wrapper perf probe: Allow wildcard for cached events
perf probe: Search SDT/cached event from all probe caches
perf probe: Support @BUILDID or @FILE suffix for SDT events perf probe: Support a special SDT probe format
perf build: Add sdt feature detection
perf-test: Add a test case for SDT event
tools/perf/Documentation/perf-probe.txt | 11 + tools/perf/Makefile.perf | 3 tools/perf/builtin-probe.c | 2 tools/perf/config/Makefile | 10 + tools/perf/tests/Build | 1 tools/perf/tests/builtin-test.c | 4 tools/perf/tests/make | 3 tools/perf/tests/sdt.c | 115 ++++++++++++ tools/perf/tests/tests.h | 1 tools/perf/util/build-id.c | 76 ++++++++ tools/perf/util/build-id.h | 3 tools/perf/util/probe-event.c | 309 +++++++++++++++++++++++++++---- tools/perf/util/probe-event.h | 1 tools/perf/util/probe-file.c | 57 +++++- tools/perf/util/probe-file.h | 5 + 15 files changed, 542 insertions(+), 59 deletions(-) create mode 100644 tools/perf/tests/sdt.c
--
Masami Hiramatsu
PATCH 1/10 perf-probe: Fix to show correct error message for $vars and $params
Fix to show correct error messages for $vars and $params because those special variables requires debug information to find the real variables or function parameters.
E.g. without this fix;
----
# perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
Failed to write event: Invalid argument
Please upgrade your kernel to at least 3.14 to have access to feature $params
Error: Failed to add events.
----
Perf ends up with an error, but the message is not correct.
With this fix, perf shows correct error message as below.
----
# perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
The /usr/lib64/libc-2.23.so file has no debug information.
Rebuild with -g, or install an appropriate debuginfo package.
Error: Failed to add events.
------- tools/perf/util/probe-event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/util/probe-event.c +3 -1
@@ -1547,7 +1547,9 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)return true;for (i =0 ; i < pev->nargs; i++) -if (is_c_varname (pev->args[i].var)) +if (is_c_varname (pev->args[i].var) || + !strcmp (pev->args[i].var,"$params" ) || + !strcmp (pev->args[i].var,"$vars" ))return true;return false;
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Fix to show correct error message for $vars and $params
perf probe: Fix to show correct error message for $vars and $params
Commit-ID: f6eb0518f325ef0d6557fbef5c7ebe48a81e74db Gitweb: http://git.kernel.org/tip/f6eb0518f325ef0d6557fbef5c7ebe48a81e74db Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:04:34 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:04 -0300
perf probe: Fix to show correct error message for $vars and $params
Fix to show correct error messages for $vars and $params because those special variables requires debug information to find the real variables or function parameters.
E.g. without this fix;
----
# perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
Failed to write event: Invalid argument
Please upgrade your kernel to at least 3.14 to have access to feature $params
Error: Failed to add events.
----Perf ends up with an error, but the message is not correct. With this fix, perf shows correct error message as below.
----
# perf probe -x /lib64/libc-2.23.so getaddrinfo \$params
The /usr/lib64/libc-2.23.so file has no debug information.
Rebuild with -g, or install an appropriate debuginfo package.
Error: Failed to add events.
------- tools/perf/util/probe-event.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
tools/perf/util/probe-event.c +3 -1
@@ -1547,7 +1547,9 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)return true;for (i =0 ; i < pev->nargs; i++) -if (is_c_varname (pev->args[i].var)) +if (is_c_varname (pev->args[i].var) || + !strcmp (pev->args[i].var,"$params" ) || + !strcmp (pev->args[i].var,"$vars" ))return true;return false;
PATCH 2/10 perf probe: Accept %sdt and %cached event name
In reply to Masami HiramatsuFrom: Masami Hiramatsu <[email protected]>
To improbe usability, support %[PROVIDER:]SDTEVENT format to add new probes on SDT and cached events.
e.g.
----
# perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
Added new event:
sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in
/usr/lib/libc-2.17.so)You can now use it in all perf tools, such as:
perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more
sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21
in /usr/lib/libc-2.17.so)
----Note that this is not only for SDT events, but also normal events with event-name.
e.g. define "myevent" on cache (-n doesn't add the real probe)
----
# perf probe -x ./perf --cache -n --add 'myevent=dso__load $params' ---- Reuse the "myevent" from cache as below. ---- # perf probe -x ./perf %myevent ----
---
Changes in v10:
- Update Documentation/perf-probe.txt to add a link about SDT.
Changes in v7:
- Fix a bug to return an error if no SDT/cached events found in cache.
--- tools/perf/Documentation/perf-probe.txt | 9 +++ tools/perf/util/probe-event.c | 82 ++++++++++++++++++++++--------- tools/perf/util/probe-event.h | 1 tools/perf/util/probe-file.c | 9 +++ 4 files changed, 76 insertions(+), 25 deletions(-)
tools/perf/Documentation/perf-probe.txt +8 -1
@@ -151,6 +151,8 @@ Probe points are defined by following syntax. 3) Define event based on source file with lazy pattern [[GROUP:]EVENT=]SRC;PTN [ARG ...] + 4) Pre-defined SDT events or cached event with name + %[PROVIDER:]SDTEVENT 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe. Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
@@ -158,6 +160,11 @@ modules. 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function. It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern. 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT). +'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name. +Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events. + +For details of the SDT, see below. +https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html PROBE ARGUMENT --------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc SEE ALSO -------- -linkperf:perf-trace[1], linkperf:perf-record[1] +linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
tools/perf/util/probe-event.c +58 -24
124 lines not on this page · raw message
tools/perf/util/probe-event.h +1 -0
@@ -85,6 +85,7 @@ struct perf_probe_event {char *group;/* Group name */ struct perf_probe_point point;/* Probe point */ int nargs;/* Number of arguments */ +bool sdt;/* SDT/cached event flag */ bool uprobes;/* Uprobe event flag */ char *target;/* Target binary */ struct perf_probe_arg *args;/* Arguments */
tools/perf/util/probe-file.c +9 -0
@@ -547,6 +547,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)return NULL ;list_for_each_entry (entry, &pcache->entries, node) { +if (pev->sdt) { +if (entry->pev.event && +streql (entry->pev.event, pev->event) && + (!pev->group || +streql (entry->pev.group, pev->group))) + goto found; + +continue ; + }/* Hit if same event name or same command-string */ if ((pev->event && (streql(entry->pev.group, pev->group) &&
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Accept %sdt and %cached event name
perf probe: Accept %sdt and %cached event name
Commit-ID: 36a009fe07bdecd201335f982babb8af34b603e2 Gitweb: http://git.kernel.org/tip/36a009fe07bdecd201335f982babb8af34b603e2 Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:04:43 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:05 -0300
perf probe: Accept %sdt and %cached event name
To improve usability, support %[PROVIDER:]SDTEVENT format to add new probes on SDT and cached events.
e.g.
----
# perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
Added new event:
sdt_libc:lll_lock_wait_private (on %lll_lock_wait_private in /usr/lib/libc-2.17.so)You can now use it in all perf tools, such as:
perf record -e sdt_libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more
sdt_libc:lll_lock_wait_private (on __lll_lock_wait_private+21 in /usr/lib/libc-2.17.so)
----Note that this is not only for SDT events, but also normal events with event-name.
e.g. define "myevent" on cache (-n doesn't add the real probe)
----
# perf probe -x ./perf --cache -n --add 'myevent=dso__load $params' ---- Reuse the "myevent" from cache as below. ---- # perf probe -x ./perf %myevent ----
--- tools/perf/Documentation/perf-probe.txt | 9 +++- tools/perf/util/probe-event.c | 82 +++++++++++++++++++++++---------- tools/perf/util/probe-event.h | 1 + tools/perf/util/probe-file.c | 9 ++++ 4 files changed, 76 insertions(+), 25 deletions(-)
tools/perf/Documentation/perf-probe.txt +8 -1
@@ -151,6 +151,8 @@ Probe points are defined by following syntax. 3) Define event based on source file with lazy pattern [[GROUP:]EVENT=]SRC;PTN [ARG ...] + 4) Pre-defined SDT events or cached event with name + %[PROVIDER:]SDTEVENT 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe. Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
@@ -158,6 +160,11 @@ modules. 'FUNC' specifies a probed function name, and it may have one of the following options; '+OFFS' is the offset from function entry address in bytes, ':RLN' is the relative-line number from function entry line, and '%return' means that it probes function return. And ';PTN' means lazy matching pattern (see LAZY MATCHING). Note that ';PTN' must be the end of the probe point definition. In addition, '@SRC' specifies a source file which has that function. It is also possible to specify a probe point by the source line number or lazy matching by using 'SRC:ALN' or 'SRC;PTN' syntax, where 'SRC' is the source file path, ':ALN' is the line number and ';PTN' is the lazy matching pattern. 'ARG' specifies the arguments of this probe point, (see PROBE ARGUMENT). +'SDTEVENT' and 'PROVIDER' is the pre-defined event name which is defined by user SDT (Statically Defined Tracing) or the pre-cached probes with event name. +Note that before using the SDT event, the target binary (on which SDT events are defined) must be scanned by linkperf:perf-buildid-cache[1] to make SDT events as cached events. + +For details of the SDT, see below. +https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html PROBE ARGUMENT --------------
@@ -237,4 +244,4 @@ Add probes at malloc() function on libc SEE ALSO -------- -linkperf:perf-trace[1], linkperf:perf-record[1] +linkperf:perf-trace[1], linkperf:perf-record[1], linkperf:perf-buildid-cache[1]
tools/perf/util/probe-event.c +58 -24
124 lines not on this page · raw message
tools/perf/util/probe-event.h +1 -0
@@ -85,6 +85,7 @@ struct perf_probe_event {char *group;/* Group name */ struct perf_probe_point point;/* Probe point */ int nargs;/* Number of arguments */ +bool sdt;/* SDT/cached event flag */ bool uprobes;/* Uprobe event flag */ char *target;/* Target binary */ struct perf_probe_arg *args;/* Arguments */
tools/perf/util/probe-file.c +9 -0
@@ -547,6 +547,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)return NULL ;list_for_each_entry (entry, &pcache->entries, node) { +if (pev->sdt) { +if (entry->pev.event && +streql (entry->pev.event, pev->event) && + (!pev->group || +streql (entry->pev.group, pev->group))) + goto found; + +continue ; + }/* Hit if same event name or same command-string */ if ((pev->event && (streql(entry->pev.group, pev->group) &&
PATCH 3/10 perf-probe: Make --list shows only available cached events
In reply to Masami HiramatsuFrom: Masami Hiramatsu <[email protected]>
Make "perf probe --cache --list" shows only available cached events by checking build-id validity.
E.g. without this patch:
----
$ ./perf probe --cache --add oldevent=cmd_probe $ make #(to update ./perf) $ ./perf probe --cache --add newevent=cmd_probe $ ./perf probe --cache --list /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1 probe_perf:oldevent=cmd_probe ---- It shows both of old and new events but user can not use old one. With this; ---- $ ./perf probe --cache -l /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe ---- This show only new event which is on the existing binary.
---
Changes in v13:
- Instead of the perf-list, apply this change for perf-probe --list because of avoiding to confuse user.
Changes in v7:
- Validate build-id via sysfs if it is for kallsyms,
Changes in v4:
- Rename a parameter 'valid' to 'validonly' :)
--- tools/perf/builtin-probe.c | 2 +- tools/perf/util/build-id.c | 33 ++++++++++++++++++++++++++++++++- tools/perf/util/build-id.h | 2 +- tools/perf/util/probe-file.c | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-)
tools/perf/builtin-probe.c +1 -1
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)struct str_node *nd;int ret; - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (false);if (!bidlist) { ret = -errno;pr_debug ("Failed to get buildids: %d\n" , ret);
tools/perf/util/build-id.c +32 -1
@@ -206,6 +206,31 @@ out:return ret; } +/* Check if the given build_id cache is valid on current running system */ +static bool build_id_cache__valid_id (char *sbuild_id) +{ +char real_sbuild_id[SBUILD_ID_SIZE ] ="" ; +char *pathname; +int ret =0 ; +bool result = false; + + pathname =build_id_cache__origname (sbuild_id); +if (!pathname) +return false; + +if (!strcmp (pathname,DSO__NAME_KALLSYMS )) + ret =sysfs__sprintf_build_id ("/" , real_sbuild_id); +else if (pathname[0 ] =='/' ) + ret =filename__sprintf_build_id (pathname, real_sbuild_id); +else + ret = -EINVAL ;/* Should we support other special DSO cache? */ +if (ret >=0 ) + result = (strcmp (sbuild_id, real_sbuild_id) ==0 ); +free (pathname); + +return result; +} +static const char *build_id_cache__basename (bool is_kallsyms,bool is_vdso) {return is_kallsyms ?"kallsyms" : (is_vdso ?"vdso" :"elf" );
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,return (i ==SBUILD_ID_SIZE -3 ) && (d->d_name[i] =='\0' ); } -struct strlist *build_id_cache__list_all (void ) +struct strlist *build_id_cache__list_all (bool validonly) {struct strlist *toplist, *linklist =NULL , *bidlist;struct str_node *nd, *nd2;char *topdir, *linkdir =NULL ;char sbuild_id[SBUILD_ID_SIZE ]; +/* for filename__ functions */ +if (validonly) +symbol__init (NULL ); +/* Open the top-level directory */ if (asprintf (&topdir,"%s/.build-id/" , buildid_dir) <0 )return NULL ;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)if (snprintf (sbuild_id,SBUILD_ID_SIZE ,"%s%s" , nd->s, nd2->s) !=SBUILD_ID_SIZE -1 ) goto err_out; +if (validonly && !build_id_cache__valid_id (sbuild_id)) +continue ;if (strlist__add (bidlist, sbuild_id) <0 ) goto err_out; }
tools/perf/util/build-id.h +1 -1
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);char *build_id_cache__linkname (const char *sbuild_id,char *bf,size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); -struct strlist *build_id_cache__list_all (void ); +struct strlist *build_id_cache__list_all (bool validonly);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);
tools/perf/util/probe-file.c +1 -1
@@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)pr_debug ("list cache with filter: %s\n" , buf);free (buf); - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (true);if (!bidlist) {pr_debug ("Failed to get buildids: %d\n" , errno);return -EINVAL ;
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events
Em Tue, Jul 12, 2016 at 07:04:54PM +0900, Masami Hiramatsu escreveu:
Quoted 4 lines
From: Masami Hiramatsu <[email protected]>
Make "perf probe --cache --list" shows only available cached events by checking build-id validity.
Something is missing here, I tried following these steps and couldn't get to the same results, can you retry them at this point in time, i.e. after applying just the three first patches in this series?
I'm continuing anyway, as I want to check the rest...
- Arnaldo
Quoted 140 lines
E.g. without this patch:
----$ ./perf probe --cache --add oldevent=cmd_probe $ make #(to update ./perf) $ ./perf probe --cache --add newevent=cmd_probe $ ./perf probe --cache --list /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1 probe_perf:oldevent=cmd_probe ---- It shows both of old and new events but user can not use old one. With this; ---- $ ./perf probe --cache -l /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe ---- This show only new event which is on the existing binary.Signed-off-by Masami Hiramatsu <[email protected]>Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v13:
- Instead of the perf-list, apply this change for perf-probe --list because of avoiding to confuse user.
Changes in v7:
- Validate build-id via sysfs if it is for kallsyms,
Changes in v4:
- Rename a parameter 'valid' to 'validonly' :)--- tools/perf/builtin-probe.c | 2 +- tools/perf/util/build-id.c | 33 ++++++++++++++++++++++++++++++++- tools/perf/util/build-id.h | 2 +- tools/perf/util/probe-file.c | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-)tools/perf/builtin-probe.c +1
-1@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)struct str_node *nd;int ret; - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (false);if (!bidlist) { ret = -errno;pr_debug ("Failed to get buildids: %d\n" , ret);tools/perf/util/build-id.c +32
-1@@ -206,6 +206,31 @@ out:return ret; } +/* Check if the given build_id cache is valid on current running system */ +static bool build_id_cache__valid_id (char *sbuild_id) +{ +char real_sbuild_id[SBUILD_ID_SIZE ] ="" ; +char *pathname; +int ret =0 ; +bool result = false; + + pathname =build_id_cache__origname (sbuild_id); +if (!pathname) +return false; + +if (!strcmp (pathname,DSO__NAME_KALLSYMS )) + ret =sysfs__sprintf_build_id ("/" , real_sbuild_id); +else if (pathname[0 ] =='/' ) + ret =filename__sprintf_build_id (pathname, real_sbuild_id); +else + ret = -EINVAL ;/* Should we support other special DSO cache? */ +if (ret >=0 ) + result = (strcmp (sbuild_id, real_sbuild_id) ==0 ); +free (pathname); + +return result; +} +static const char *build_id_cache__basename (bool is_kallsyms,bool is_vdso) {return is_kallsyms ?"kallsyms" : (is_vdso ?"vdso" :"elf" );@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,return (i ==SBUILD_ID_SIZE -3 ) && (d->d_name[i] =='\0' ); } -struct strlist *build_id_cache__list_all (void ) +struct strlist *build_id_cache__list_all (bool validonly) {struct strlist *toplist, *linklist =NULL , *bidlist;struct str_node *nd, *nd2;char *topdir, *linkdir =NULL ;char sbuild_id[SBUILD_ID_SIZE ]; +/* for filename__ functions */ +if (validonly) +symbol__init (NULL ); +/* Open the top-level directory */ if (asprintf (&topdir,"%s/.build-id/" , buildid_dir) <0 )return NULL ;@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)if (snprintf (sbuild_id,SBUILD_ID_SIZE ,"%s%s" , nd->s, nd2->s) !=SBUILD_ID_SIZE -1 ) goto err_out; +if (validonly && !build_id_cache__valid_id (sbuild_id)) +continue ;if (strlist__add (bidlist, sbuild_id) <0 ) goto err_out; }tools/perf/util/build-id.h +1
-1@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);char *build_id_cache__linkname (const char *sbuild_id,char *bf,size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); -struct strlist *build_id_cache__list_all (void ); +struct strlist *build_id_cache__list_all (bool validonly);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);tools/perf/util/probe-file.c +1
-1@@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)pr_debug ("list cache with filter: %s\n" , buf);free (buf); - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (true);if (!bidlist) {pr_debug ("Failed to get buildids: %d\n" , errno);return -EINVAL ;
Re: [PATCH perf/core 03/10] perf-probe: Make --list shows only available cached events
Quoted 9 lines · On Wed, 13 Jul 2016 16:28:37 -0300 Arnaldo Carvalho de Melo <[email protected]>…
Em Tue, Jul 12, 2016 at 07:04:54PM +0900, Masami Hiramatsu escreveu:
Quoted 4 lines
From: Masami Hiramatsu <[email protected]>
Make "perf probe --cache --list" shows only available cached events by checking build-id validity.
Something is missing here, I tried following these steps and couldn't get to the same results, can you retry them at this point in time, i.e. after applying just the three first patches in this series?
Sorry, I missed some steps, see below;
Quoted 8 lines
I'm continuing anyway, as I want to check the rest...
- Arnaldo
Quoted 3 lines
E.g. without this patch:
----$ ./perf probe --cache --add oldevent=cmd_probe
Here, you have to change perf source code so that perf binary build-id is changed.
And make a copy of perf (as perf.old) so that you can get build-id of both binary.
Quoted 1 line
Quoted 1 line
$ make #(to update ./perf)
So, prese ensure that the new perf binary has different build-id.
If both binary has same build-id, you'll see just one cache.
Thank you,
Quoted 136 lines
Quoted 136 lines
$ ./perf probe --cache --add newevent=cmd_probe $ ./perf probe --cache --list /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1 probe_perf:oldevent=cmd_probe ---- It shows both of old and new events but user can not use old one. With this; ---- $ ./perf probe --cache -l /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe ---- This show only new event which is on the existing binary.Signed-off-by Masami Hiramatsu <[email protected]>Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v13:
- Instead of the perf-list, apply this change for perf-probe --list because of avoiding to confuse user.
Changes in v7:
- Validate build-id via sysfs if it is for kallsyms,
Changes in v4:
- Rename a parameter 'valid' to 'validonly' :)--- tools/perf/builtin-probe.c | 2 +- tools/perf/util/build-id.c | 33 ++++++++++++++++++++++++++++++++- tools/perf/util/build-id.h | 2 +- tools/perf/util/probe-file.c | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-)tools/perf/builtin-probe.c +1
-1@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)struct str_node *nd;int ret; - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (false);if (!bidlist) { ret = -errno;pr_debug ("Failed to get buildids: %d\n" , ret);tools/perf/util/build-id.c +32
-1@@ -206,6 +206,31 @@ out:return ret; } +/* Check if the given build_id cache is valid on current running system */ +static bool build_id_cache__valid_id (char *sbuild_id) +{ +char real_sbuild_id[SBUILD_ID_SIZE ] ="" ; +char *pathname; +int ret =0 ; +bool result = false; + + pathname =build_id_cache__origname (sbuild_id); +if (!pathname) +return false; + +if (!strcmp (pathname,DSO__NAME_KALLSYMS )) + ret =sysfs__sprintf_build_id ("/" , real_sbuild_id); +else if (pathname[0 ] =='/' ) + ret =filename__sprintf_build_id (pathname, real_sbuild_id); +else + ret = -EINVAL ;/* Should we support other special DSO cache? */ +if (ret >=0 ) + result = (strcmp (sbuild_id, real_sbuild_id) ==0 ); +free (pathname); + +return result; +} +static const char *build_id_cache__basename (bool is_kallsyms,bool is_vdso) {return is_kallsyms ?"kallsyms" : (is_vdso ?"vdso" :"elf" );@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,return (i ==SBUILD_ID_SIZE -3 ) && (d->d_name[i] =='\0' ); } -struct strlist *build_id_cache__list_all (void ) +struct strlist *build_id_cache__list_all (bool validonly) {struct strlist *toplist, *linklist =NULL , *bidlist;struct str_node *nd, *nd2;char *topdir, *linkdir =NULL ;char sbuild_id[SBUILD_ID_SIZE ]; +/* for filename__ functions */ +if (validonly) +symbol__init (NULL ); +/* Open the top-level directory */ if (asprintf (&topdir,"%s/.build-id/" , buildid_dir) <0 )return NULL ;@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)if (snprintf (sbuild_id,SBUILD_ID_SIZE ,"%s%s" , nd->s, nd2->s) !=SBUILD_ID_SIZE -1 ) goto err_out; +if (validonly && !build_id_cache__valid_id (sbuild_id)) +continue ;if (strlist__add (bidlist, sbuild_id) <0 ) goto err_out; }tools/perf/util/build-id.h +1
-1@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);char *build_id_cache__linkname (const char *sbuild_id,char *bf,size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); -struct strlist *build_id_cache__list_all (void ); +struct strlist *build_id_cache__list_all (bool validonly);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);tools/perf/util/probe-file.c +1
-1@@ -806,7 +806,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)pr_debug ("list cache with filter: %s\n" , buf);free (buf); - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (true);if (!bidlist) {pr_debug ("Failed to get buildids: %d\n" , errno);return -EINVAL ;
Signature · 1 line
Masami Hiramatsu <[email protected]>
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Make --list show only available cached events
In reply to Masami Hiramatsuperf probe: Make --list show only available cached events
Commit-ID: c3492a3a4e58117f18d96125e67b0bed7c4231e1 Gitweb: http://git.kernel.org/tip/c3492a3a4e58117f18d96125e67b0bed7c4231e1 Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:04:54 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:05 -0300
perf probe: Make --list show only available cached events
Make "perf probe --cache --list" show only available cached events by checking build-id validity.
E.g. without this patch:
----
$ ./perf probe --cache --add oldevent=cmd_probe $ make #(to update ./perf) $ ./perf probe --cache --add newevent=cmd_probe $ ./perf probe --cache --list /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe /home/mhiramat/ksrc/linux/tools/perf/perf (c2e44d614e33e1 probe_perf:oldevent=cmd_probe ---- It shows both of old and new events but user can not use old one. With this; ---- $ ./perf probe --cache -l /home/mhiramat/ksrc/linux/tools/perf/perf (061e90539bac69 probe_perf:newevent=cmd_probe ----
This shows only new events which are on the existing binary.
--- tools/perf/builtin-probe.c | 2 +- tools/perf/util/build-id.c | 33 ++++++++++++++++++++++++++++++++- tools/perf/util/build-id.h | 2 +- tools/perf/util/probe-file.c | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-)
tools/perf/builtin-probe.c +1 -1
@@ -370,7 +370,7 @@ static int del_perf_probe_caches(struct strfilter *filter)struct str_node *nd;int ret; - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (false);if (!bidlist) { ret = -errno;pr_debug ("Failed to get buildids: %d\n" , ret);
tools/perf/util/build-id.c +32 -1
@@ -206,6 +206,31 @@ out:return ret; } +/* Check if the given build_id cache is valid on current running system */ +static bool build_id_cache__valid_id (char *sbuild_id) +{ +char real_sbuild_id[SBUILD_ID_SIZE ] ="" ; +char *pathname; +int ret =0 ; +bool result = false; + + pathname =build_id_cache__origname (sbuild_id); +if (!pathname) +return false; + +if (!strcmp (pathname,DSO__NAME_KALLSYMS )) + ret =sysfs__sprintf_build_id ("/" , real_sbuild_id); +else if (pathname[0 ] =='/' ) + ret =filename__sprintf_build_id (pathname, real_sbuild_id); +else + ret = -EINVAL ;/* Should we support other special DSO cache? */ +if (ret >=0 ) + result = (strcmp (sbuild_id, real_sbuild_id) ==0 ); +free (pathname); + +return result; +} +static const char *build_id_cache__basename (bool is_kallsyms,bool is_vdso) {return is_kallsyms ?"kallsyms" : (is_vdso ?"vdso" :"elf" );
@@ -433,13 +458,17 @@ static bool lsdir_bid_tail_filter(const char *name __maybe_unused,return (i ==SBUILD_ID_SIZE -3 ) && (d->d_name[i] =='\0' ); } -struct strlist *build_id_cache__list_all (void ) +struct strlist *build_id_cache__list_all (bool validonly) {struct strlist *toplist, *linklist =NULL , *bidlist;struct str_node *nd, *nd2;char *topdir, *linkdir =NULL ;char sbuild_id[SBUILD_ID_SIZE ]; +/* for filename__ functions */ +if (validonly) +symbol__init (NULL ); +/* Open the top-level directory */ if (asprintf (&topdir,"%s/.build-id/" , buildid_dir) <0 )return NULL ;
@@ -470,6 +499,8 @@ struct strlist *build_id_cache__list_all(void)if (snprintf (sbuild_id,SBUILD_ID_SIZE ,"%s%s" , nd->s, nd2->s) !=SBUILD_ID_SIZE -1 ) goto err_out; +if (validonly && !build_id_cache__valid_id (sbuild_id)) +continue ;if (strlist__add (bidlist, sbuild_id) <0 ) goto err_out; }
tools/perf/util/build-id.h +1 -1
@@ -34,7 +34,7 @@ char *build_id_cache__origname(const char *sbuild_id);char *build_id_cache__linkname (const char *sbuild_id,char *bf,size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); -struct strlist *build_id_cache__list_all (void ); +struct strlist *build_id_cache__list_all (bool validonly);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);
tools/perf/util/probe-file.c +1 -1
@@ -808,7 +808,7 @@ int probe_cache__show_all_caches(struct strfilter *filter)pr_debug ("list cache with filter: %s\n" , buf);free (buf); - bidlist =build_id_cache__list_all (); + bidlist =build_id_cache__list_all (true);if (!bidlist) {pr_debug ("Failed to get buildids: %d\n" , errno);return -EINVAL ;
PATCH 4/10 perf: probe-cache: Add for_each_probe_cache_entry() wrapper
In reply to Masami HiramatsuAdd for_each_probe_cache_entry() wrapper macro
for hiding list in probe_cache.
---
Changes in v10:
- Splitted from "perf probe: Allow wildcard for cached events"
--- tools/perf/util/probe-file.c | 8 ++++---- tools/perf/util/probe-file.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-)
tools/perf/util/probe-file.c +4 -4
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)if (!cmd)return NULL ; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {if (pev->sdt) { if (entry->pev.event && streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache, {struct probe_cache_entry *entry =NULL ; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {/* Hit if same event name or same command-string */ if (streql (entry->pev.group, group) &&streql (entry->pev.event, event))
@@ -746,7 +746,7 @@ int probe_cache__commit(struct probe_cache *pcache)if (ret <0 ) goto out; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) { ret =probe_cache_entry__write (entry, pcache->fd);pr_debug ("Cache committed: %d\n" , ret);if (ret <0 )
@@ -788,7 +788,7 @@ static int probe_cache__show_entries(struct probe_cache *pcache, {struct probe_cache_entry *entry; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {if (probe_cache_entry__compare (entry, filter))printf ("%s\n" , entry->spev); }
tools/perf/util/probe-file.h +2 -0
@@ -21,6 +21,8 @@ struct probe_cache {#define PF_FL_UPROBE 1#define PF_FL_RW 2 +#define for_each_probe_cache_entry (entry, pcache) \ + list_for_each_entry(entry, &pcache->entries, node)int probe_file__open (int flag);int probe_file__open_both (int *kfd,int *ufd,int flag);
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe-cache: Add for_each_probe_cache_entry() wrapper
perf probe-cache: Add for_each_probe_cache_entry() wrapper
Commit-ID: 05bf2c8a2a819132b4a8f35d4315ff22e8e84a20 Gitweb: http://git.kernel.org/tip/05bf2c8a2a819132b4a8f35d4315ff22e8e84a20 Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:04 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:06 -0300
perf probe-cache: Add for_each_probe_cache_entry() wrapper
Add for_each_probe_cache_entry() wrapper macro for hiding list in probe_cache.
--- tools/perf/util/probe-file.c | 8 ++++---- tools/perf/util/probe-file.h | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-)
tools/perf/util/probe-file.c +4 -4
@@ -546,7 +546,7 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)if (!cmd)return NULL ; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {if (pev->sdt) { if (entry->pev.event && streql(entry->pev.event, pev->event) &&
@@ -576,7 +576,7 @@ probe_cache__find_by_name(struct probe_cache *pcache, {struct probe_cache_entry *entry =NULL ; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {/* Hit if same event name or same command-string */ if (streql (entry->pev.group, group) &&streql (entry->pev.event, event))
@@ -748,7 +748,7 @@ int probe_cache__commit(struct probe_cache *pcache)if (ret <0 ) goto out; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) { ret =probe_cache_entry__write (entry, pcache->fd);pr_debug ("Cache committed: %d\n" , ret);if (ret <0 )
@@ -790,7 +790,7 @@ static int probe_cache__show_entries(struct probe_cache *pcache, {struct probe_cache_entry *entry; -list_for_each_entry (entry, &pcache->entries, node) { +for_each_probe_cache_entry (entry, pcache) {if (probe_cache_entry__compare (entry, filter))printf ("%s\n" , entry->spev); }
tools/perf/util/probe-file.h +2 -0
@@ -21,6 +21,8 @@ struct probe_cache {#define PF_FL_UPROBE 1#define PF_FL_RW 2 +#define for_each_probe_cache_entry (entry, pcache) \ + list_for_each_entry(entry, &pcache->entries, node)int probe_file__open (int flag);int probe_file__open_both (int *kfd,int *ufd,int flag);
PATCH 5/10 perf probe: Allow wildcard for cached events
In reply to Masami HiramatsuAllo glob wildcard for reusing cached/SDT events. E.g.
# perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.
---
Changes in v12:
- Rename strlist__for_each to strlist__for_each_entry.
Changes in v10:
- Split off bugfix, adding interface, and target search patches.
- Do not export clear_probe_trace_events().
Changes in v7:
- Continue to search caches if a build-id cache has no probe cache.
- Make probe_cache__open() to accept DSO__NAME_KALLSYMS for kernel.
- Fix to add probes correctly when a wildcard matchs both of uprobes and kprobes.
Changes in v5.1:
- Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)
--- tools/perf/util/probe-event.c | 107 +++++++++++++++++++++++++++++++++++++++-- tools/perf/util/probe-file.c | 38 ++++++++++++--- tools/perf/util/probe-file.h | 3 + 3 files changed, 138 insertions(+), 10 deletions(-)
tools/perf/util/probe-event.c +103 -4
@@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) ptr =strchr (*arg,':' );if (ptr) { *ptr ='\0' ; -if (!is_c_func_name (*arg)) +if (!pev->sdt && !is_c_func_name (*arg)) goto ng_name; pev->group =strdup (*arg);if (!pev->group)
@@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) *arg = ptr +1 ; }else pev->group =NULL ; -if (!is_c_func_name (*arg)) { +if (!pev->sdt && !is_c_func_name (*arg)) { ng_name:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) ret = -ENOMEM ; goto out; } + tev->uprobes = (tp->module[0 ] =='/' ); p++; }else p = argv[1 ];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,int ret;/* If probe_event or trace_event already have the name, reuse it */ -if (pev->event) +if (pev->event && !pev->sdt) event = pev->event;else if (tev->event) event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,else event = tev->point.realname; } -if (pev->group) +if (pev->group && !pev->sdt) group = pev->group;else if (tev->group) group = tev->group;
@@ -2894,6 +2895,100 @@ errout:bool __weak arch__prefers_symtab (void ) {return false; } +/* Concatinate two arrays */ +static void *memcat (void *a,size_t sz_a,void *b,size_t sz_b) +{ +void *ret; + + ret =malloc (sz_a + sz_b); +if (ret) { +memcpy (ret, a, sz_a); +memcpy (ret + sz_a, b, sz_b); + } +return ret; +} + +static int +concat_probe_trace_events (struct probe_trace_event **tevs,int *ntevs, +struct probe_trace_event **tevs2,int ntevs2) +{ +struct probe_trace_event *new_tevs; +int ret =0 ; + +if (ntevs ==0 ) { + *tevs = *tevs2; + *ntevs = ntevs2; + *tevs2 =NULL ; +return 0 ; + } + +if (*ntevs + ntevs2 > probe_conf.max_probes) + ret = -E2BIG ; +else { +/* Concatinate the array of probe_trace_event */ + new_tevs =memcat (*tevs, (*ntevs) *sizeof (**tevs), + *tevs2, ntevs2 *sizeof (**tevs2)); +if (!new_tevs) + ret = -ENOMEM ; +else { +free (*tevs); + *tevs = new_tevs; + *ntevs += ntevs2; + } + } +if (ret <0 ) +clear_probe_trace_events (*tevs2, ntevs2); +zfree (tevs2); + +return ret; +} + +/* +* Try to find probe_trace_event from given probe caches. Return the number +* of cached events found, if an error occurs return the error. +*/ +static int find_cached_events (struct perf_probe_event *pev, +struct probe_trace_event **tevs, +const char *target) +{ +struct probe_cache *cache; +struct probe_cache_entry *entry; +struct probe_trace_event *tmp_tevs =NULL ; +int ntevs =0 ; +int ret =0 ; + + cache =probe_cache__new (target); +/* Return 0 ("not found") if the target has no probe cache. */ +if (!cache) +return 0 ; + +for_each_probe_cache_entry (entry, cache) { +/* Skip the cache entry which has no name */ +if (!entry->pev.event || !entry->pev.group) +continue ; +if ((!pev->group ||strglobmatch (entry->pev.group, pev->group)) && +strglobmatch (entry->pev.event, pev->event)) { + ret =probe_cache_entry__get_event (entry, &tmp_tevs); +if (ret >0 ) + ret =concat_probe_trace_events (tevs, &ntevs, + &tmp_tevs, ret); +if (ret <0 ) +break ; + } + } +probe_cache__delete (cache); +if (ret <0 ) { +clear_probe_trace_events (*tevs, ntevs); +zfree (tevs); + }else { + ret = ntevs; +if (ntevs >0 && target && target[0 ] =='/' ) + pev->uprobes = true; + } + +return ret; +} +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev,struct probe_trace_event **tevs) {
@@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,struct str_node *node;int ret, i; +if (pev->sdt) +/* For SDT/cached events, we use special search functions */ +return find_cached_events (pev, tevs, pev->target); + cache =probe_cache__new (pev->target);if (!cache)return 0 ;
tools/perf/util/probe-file.c +32 -6
@@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)return entry; } -/* For the kernel probe caches, pass target = NULL */ +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs) +{ +struct probe_trace_event *tev; +struct str_node *node; +int ret, i; + + ret =strlist__nr_entries (entry->tevlist); +if (ret > probe_conf.max_probes) +return -E2BIG ; + + *tevs =zalloc (ret *sizeof (*tev)); +if (!*tevs) +return -ENOMEM ; + + i =0 ; +strlist__for_each_entry (node, entry->tevlist) { + tev = &(*tevs)[i++]; + ret =parse_probe_trace_command (node->s, tev); +if (ret <0 ) +break ; + } +return i; +} + +/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ static int probe_cache__open (struct probe_cache *pcache,const char *target) {char cpath[PATH_MAX ];char sbuildid[SBUILD_ID_SIZE ];char *dir_name =NULL ; -bool is_kallsyms = !target; +bool is_kallsyms = false;int ret, fd;if (target &&build_id_cache__cached (target)) {
@@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) goto found; } -if (target) - ret =filename__sprintf_build_id (target, sbuildid); -else { +if (!target || !strcmp (target,DSO__NAME_KALLSYMS )) { target =DSO__NAME_KALLSYMS ; + is_kallsyms = true; ret =sysfs__sprintf_build_id ("/" , sbuildid); - } + }else + ret =filename__sprintf_build_id (target, sbuildid); +if (ret <0 ) {pr_debug ("Failed to get build-id from %s.\n" , target);return ret;
tools/perf/util/probe-file.h +3 -0
@@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter, struct strlist *plist);int probe_file__del_strlist (int fd,struct strlist *namelist); +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs); +struct probe_cache *probe_cache__new (const char *target); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev,
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 05/10] perf probe: Allow wildcard for cached events
Em Tue, Jul 12, 2016 at 07:05:18PM +0900, Masami Hiramatsu escreveu:
Quoted 3 lines
Allo glob wildcard for reusing cached/SDT events. E.g.
# perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
The example message for this could be improved to also use a wildcard :-)
Quoted 260 lines
This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v12:
- Renamestrlist__for_eachtostrlist__for_each_entry.
Changes in v10:
- Split off bugfix, adding interface, and target search patches.
- Do not exportclear_probe_trace_events().
Changes in v7:
- Continue to search caches if a build-id cache has no probe cache.
- Makeprobe_cache__open()to acceptDSO__NAME_KALLSYMSfor kernel.
- Fix to add probes correctly when a wildcard matchs both of uprobes and kprobes.
Changes in v5.1:
- Fix a SEGV bug when a group name is omitted. (Thanks Hemant!)--- tools/perf/util/probe-event.c | 107 +++++++++++++++++++++++++++++++++++++++-- tools/perf/util/probe-file.c | 38 ++++++++++++--- tools/perf/util/probe-file.h | 3 + 3 files changed, 138 insertions(+), 10 deletions(-)tools/perf/util/probe-event.c +103
-4@@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) ptr =strchr (*arg,':' );if (ptr) { *ptr ='\0' ; -if (!is_c_func_name (*arg)) +if (!pev->sdt && !is_c_func_name (*arg)) goto ng_name; pev->group =strdup (*arg);if (!pev->group)@@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) *arg = ptr +1 ; }else pev->group =NULL ; -if (!is_c_func_name (*arg)) { +if (!pev->sdt && !is_c_func_name (*arg)) { ng_name:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , *arg);@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) ret = -ENOMEM ; goto out; } + tev->uprobes = (tp->module[0 ] =='/' ); p++; }else p = argv[1 ];@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,int ret;/* If probe_event or trace_event already have the name, reuse it */ -if (pev->event) +if (pev->event && !pev->sdt) event = pev->event;else if (tev->event) event = tev->event;@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,else event = tev->point.realname; } -if (pev->group) +if (pev->group && !pev->sdt) group = pev->group;else if (tev->group) group = tev->group;@@ -2894,6 +2895,100 @@ errout:bool __weak arch__prefers_symtab (void ) {return false; } +/* Concatinate two arrays */ +static void *memcat (void *a,size_t sz_a,void *b,size_t sz_b) +{ +void *ret; + + ret =malloc (sz_a + sz_b); +if (ret) { +memcpy (ret, a, sz_a); +memcpy (ret + sz_a, b, sz_b); + } +return ret; +} + +static int +concat_probe_trace_events (struct probe_trace_event **tevs,int *ntevs, +struct probe_trace_event **tevs2,int ntevs2) +{ +struct probe_trace_event *new_tevs; +int ret =0 ; + +if (ntevs ==0 ) { + *tevs = *tevs2; + *ntevs = ntevs2; + *tevs2 =NULL ; +return 0 ; + } + +if (*ntevs + ntevs2 > probe_conf.max_probes) + ret = -E2BIG ; +else { +/* Concatinate the array of probe_trace_event */ + new_tevs =memcat (*tevs, (*ntevs) *sizeof (**tevs), + *tevs2, ntevs2 *sizeof (**tevs2)); +if (!new_tevs) + ret = -ENOMEM ; +else { +free (*tevs); + *tevs = new_tevs; + *ntevs += ntevs2; + } + } +if (ret <0 ) +clear_probe_trace_events (*tevs2, ntevs2); +zfree (tevs2); + +return ret; +} + +/* +* Try to find probe_trace_event from given probe caches. Return the number +* of cached events found, if an error occurs return the error. +*/ +static int find_cached_events (struct perf_probe_event *pev, +struct probe_trace_event **tevs, +const char *target) +{ +struct probe_cache *cache; +struct probe_cache_entry *entry; +struct probe_trace_event *tmp_tevs =NULL ; +int ntevs =0 ; +int ret =0 ; + + cache =probe_cache__new (target); +/* Return 0 ("not found") if the target has no probe cache. */ +if (!cache) +return 0 ; + +for_each_probe_cache_entry (entry, cache) { +/* Skip the cache entry which has no name */ +if (!entry->pev.event || !entry->pev.group) +continue ; +if ((!pev->group ||strglobmatch (entry->pev.group, pev->group)) && +strglobmatch (entry->pev.event, pev->event)) { + ret =probe_cache_entry__get_event (entry, &tmp_tevs); +if (ret >0 ) + ret =concat_probe_trace_events (tevs, &ntevs, + &tmp_tevs, ret); +if (ret <0 ) +break ; + } + } +probe_cache__delete (cache); +if (ret <0 ) { +clear_probe_trace_events (*tevs, ntevs); +zfree (tevs); + }else { + ret = ntevs; +if (ntevs >0 && target && target[0 ] =='/' ) + pev->uprobes = true; + } + +return ret; +} +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev,struct probe_trace_event **tevs) {@@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,struct str_node *node;int ret, i; +if (pev->sdt) +/* For SDT/cached events, we use special search functions */ +return find_cached_events (pev, tevs, pev->target); + cache =probe_cache__new (pev->target);if (!cache)return 0 ;tools/perf/util/probe-file.c +32
-6@@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)return entry; } -/* For the kernel probe caches, pass target = NULL */ +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs) +{ +struct probe_trace_event *tev; +struct str_node *node; +int ret, i; + + ret =strlist__nr_entries (entry->tevlist); +if (ret > probe_conf.max_probes) +return -E2BIG ; + + *tevs =zalloc (ret *sizeof (*tev)); +if (!*tevs) +return -ENOMEM ; + + i =0 ; +strlist__for_each_entry (node, entry->tevlist) { + tev = &(*tevs)[i++]; + ret =parse_probe_trace_command (node->s, tev); +if (ret <0 ) +break ; + } +return i; +} + +/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ static int probe_cache__open (struct probe_cache *pcache,const char *target) {char cpath[PATH_MAX ];char sbuildid[SBUILD_ID_SIZE ];char *dir_name =NULL ; -bool is_kallsyms = !target; +bool is_kallsyms = false;int ret, fd;if (target &&build_id_cache__cached (target)) {@@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) goto found; } -if (target) - ret =filename__sprintf_build_id (target, sbuildid); -else { +if (!target || !strcmp (target,DSO__NAME_KALLSYMS )) { target =DSO__NAME_KALLSYMS ; + is_kallsyms = true; ret =sysfs__sprintf_build_id ("/" , sbuildid); - } + }else + ret =filename__sprintf_build_id (target, sbuildid); +if (ret <0 ) {pr_debug ("Failed to get build-id from %s.\n" , target);return ret;tools/perf/util/probe-file.h +3
-0@@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter, struct strlist *plist);int probe_file__del_strlist (int fd,struct strlist *namelist); +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs); +struct probe_cache *probe_cache__new (const char *target); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev,
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Allow wildcard for cached events
In reply to Masami Hiramatsuperf probe: Allow wildcard for cached events
Commit-ID: 42bba263eb58800b6239a0cb35ac17fd29379277 Gitweb: http://git.kernel.org/tip/42bba263eb58800b6239a0cb35ac17fd29379277 Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:18 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:07 -0300
perf probe: Allow wildcard for cached events
Allo glob wildcard for reusing cached/SDT events. E.g.
# perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
This example adds probes for all SDT in libc.
Note that the SDTs must have been scanned by perf buildid-cache.
Committer note:
Using it to check what of those SDT probes would take place when doing a cargo run (rust):
# trace --no-sys --event sdt_libc:* cargo run
0.000 sdt_libc:setjmp:(7f326b69c4d1))
28.423 sdt_libc:setjmp:(7f4b0a5364d1))
29.000 sdt_libc:setjmp:(7f4b0a5364d1))
88.597 sdt_libc:setjmp:(7fc01fd414d1))
89.220 sdt_libc:setjmp:(7fc01fd414d1))
95.501 sdt_libc:setjmp:(7f326b69c4d1))
Running `target/debug/hello_world`
97.110 sdt_libc:setjmp:(7f95e09234d1))
Hello, world!
#--- tools/perf/util/probe-event.c | 107 ++++++++++++++++++++++++++++++++++++++++-- tools/perf/util/probe-file.c | 38 ++++++++++++--- tools/perf/util/probe-file.h | 3 ++ 3 files changed, 138 insertions(+), 10 deletions(-)
tools/perf/util/probe-event.c +103 -4
@@ -1204,7 +1204,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) ptr =strchr (*arg,':' );if (ptr) { *ptr ='\0' ; -if (!is_c_func_name (*arg)) +if (!pev->sdt && !is_c_func_name (*arg)) goto ng_name; pev->group =strdup (*arg);if (!pev->group)
@@ -1212,7 +1212,7 @@ static int parse_perf_probe_event_name(char **arg, struct perf_probe_event *pev) *arg = ptr +1 ; }else pev->group =NULL ; -if (!is_c_func_name (*arg)) { +if (!pev->sdt && !is_c_func_name (*arg)) { ng_name:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , *arg);
@@ -1644,6 +1644,7 @@ int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev) ret = -ENOMEM ; goto out; } + tev->uprobes = (tp->module[0 ] =='/' ); p++; }else p = argv[1 ];
@@ -2518,7 +2519,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,int ret;/* If probe_event or trace_event already have the name, reuse it */ -if (pev->event) +if (pev->event && !pev->sdt) event = pev->event;else if (tev->event) event = tev->event;
@@ -2531,7 +2532,7 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,else event = tev->point.realname; } -if (pev->group) +if (pev->group && !pev->sdt) group = pev->group;else if (tev->group) group = tev->group;
@@ -2894,6 +2895,100 @@ errout:bool __weak arch__prefers_symtab (void ) {return false; } +/* Concatinate two arrays */ +static void *memcat (void *a,size_t sz_a,void *b,size_t sz_b) +{ +void *ret; + + ret =malloc (sz_a + sz_b); +if (ret) { +memcpy (ret, a, sz_a); +memcpy (ret + sz_a, b, sz_b); + } +return ret; +} + +static int +concat_probe_trace_events (struct probe_trace_event **tevs,int *ntevs, +struct probe_trace_event **tevs2,int ntevs2) +{ +struct probe_trace_event *new_tevs; +int ret =0 ; + +if (ntevs ==0 ) { + *tevs = *tevs2; + *ntevs = ntevs2; + *tevs2 =NULL ; +return 0 ; + } + +if (*ntevs + ntevs2 > probe_conf.max_probes) + ret = -E2BIG ; +else { +/* Concatinate the array of probe_trace_event */ + new_tevs =memcat (*tevs, (*ntevs) *sizeof (**tevs), + *tevs2, ntevs2 *sizeof (**tevs2)); +if (!new_tevs) + ret = -ENOMEM ; +else { +free (*tevs); + *tevs = new_tevs; + *ntevs += ntevs2; + } + } +if (ret <0 ) +clear_probe_trace_events (*tevs2, ntevs2); +zfree (tevs2); + +return ret; +} + +/* +* Try to find probe_trace_event from given probe caches. Return the number +* of cached events found, if an error occurs return the error. +*/ +static int find_cached_events (struct perf_probe_event *pev, +struct probe_trace_event **tevs, +const char *target) +{ +struct probe_cache *cache; +struct probe_cache_entry *entry; +struct probe_trace_event *tmp_tevs =NULL ; +int ntevs =0 ; +int ret =0 ; + + cache =probe_cache__new (target); +/* Return 0 ("not found") if the target has no probe cache. */ +if (!cache) +return 0 ; + +for_each_probe_cache_entry (entry, cache) { +/* Skip the cache entry which has no name */ +if (!entry->pev.event || !entry->pev.group) +continue ; +if ((!pev->group ||strglobmatch (entry->pev.group, pev->group)) && +strglobmatch (entry->pev.event, pev->event)) { + ret =probe_cache_entry__get_event (entry, &tmp_tevs); +if (ret >0 ) + ret =concat_probe_trace_events (tevs, &ntevs, + &tmp_tevs, ret); +if (ret <0 ) +break ; + } + } +probe_cache__delete (cache); +if (ret <0 ) { +clear_probe_trace_events (*tevs, ntevs); +zfree (tevs); + }else { + ret = ntevs; +if (ntevs >0 && target && target[0 ] =='/' ) + pev->uprobes = true; + } + +return ret; +} +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev,struct probe_trace_event **tevs) {
@@ -2903,6 +2998,10 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,struct str_node *node;int ret, i; +if (pev->sdt) +/* For SDT/cached events, we use special search functions */ +return find_cached_events (pev, tevs, pev->target); + cache =probe_cache__new (pev->target);if (!cache)return 0 ;
tools/perf/util/probe-file.c +32 -6
@@ -362,13 +362,38 @@ probe_cache_entry__new(struct perf_probe_event *pev)return entry; } -/* For the kernel probe caches, pass target = NULL */ +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs) +{ +struct probe_trace_event *tev; +struct str_node *node; +int ret, i; + + ret =strlist__nr_entries (entry->tevlist); +if (ret > probe_conf.max_probes) +return -E2BIG ; + + *tevs =zalloc (ret *sizeof (*tev)); +if (!*tevs) +return -ENOMEM ; + + i =0 ; +strlist__for_each_entry (node, entry->tevlist) { + tev = &(*tevs)[i++]; + ret =parse_probe_trace_command (node->s, tev); +if (ret <0 ) +break ; + } +return i; +} + +/* For the kernel probe caches, pass target = NULL or DSO__NAME_KALLSYMS */ static int probe_cache__open (struct probe_cache *pcache,const char *target) {char cpath[PATH_MAX ];char sbuildid[SBUILD_ID_SIZE ];char *dir_name =NULL ; -bool is_kallsyms = !target; +bool is_kallsyms = false;int ret, fd;if (target &&build_id_cache__cached (target)) {
@@ -378,12 +403,13 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target) goto found; } -if (target) - ret =filename__sprintf_build_id (target, sbuildid); -else { +if (!target || !strcmp (target,DSO__NAME_KALLSYMS )) { target =DSO__NAME_KALLSYMS ; + is_kallsyms = true; ret =sysfs__sprintf_build_id ("/" , sbuildid); - } + }else + ret =filename__sprintf_build_id (target, sbuildid); +if (ret <0 ) {pr_debug ("Failed to get build-id from %s.\n" , target);return ret;
tools/perf/util/probe-file.h +3 -0
@@ -34,6 +34,9 @@ int probe_file__get_events(int fd, struct strfilter *filter, struct strlist *plist);int probe_file__del_strlist (int fd,struct strlist *namelist); +int probe_cache_entry__get_event (struct probe_cache_entry *entry, +struct probe_trace_event **tevs); +struct probe_cache *probe_cache__new (const char *target); int probe_cache__add_entry(struct probe_cache *pcache, struct perf_probe_event *pev,
PATCH 6/10 perf probe: Search SDT/cached event from all probe caches
In reply to Masami HiramatsuSearch SDT/cached event from all probe caches if user doesn't pass any binary. With this, we don't have to specify target binary for SDT and named cached events (which start with %).
E.g. without this, a target binary must be passed with -x.
# perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
With this change, we don't need it anymore.
# perf probe -a %sdt_libc:\*
---
Changes in v12:
- Rename strlist__for_each to strlist__for_each_entry.
Changes from v10:
- Splitted from "perf probe: Allow wildcard for cached events"
--- tools/perf/util/probe-event.c | 105 ++++++++++++++++++++++++++++++++++------- 1 file changed, 86 insertions(+), 19 deletions(-)
tools/perf/util/probe-event.c +86 -19
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,return 0 ; } -static int __add_probe_trace_events (struct perf_probe_event *pev, -struct probe_trace_event *tevs, -int ntevs,bool allow_suffix) +static int __open_probe_file_and_namelist (bool uprobe, +struct strlist **namelist) { -int i, fd, ret; -struct probe_trace_event *tev =NULL ; -struct probe_cache *cache =NULL ; -struct strlist *namelist; +int fd; - fd =probe_file__open (PF_FL_RW | (pev->uprobes ?PF_FL_UPROBE :0 )); + fd =probe_file__open (PF_FL_RW | (uprobe ?PF_FL_UPROBE :0 ));if (fd <0 )return fd;/* Get current event names */ - namelist =probe_file__get_namelist (fd); -if (!namelist) { + *namelist =probe_file__get_namelist (fd); +if (!(*namelist)) {pr_debug ("Failed to get current event list.\n" ); - ret = -ENOMEM ; - goto close_out; +close (fd); +return -ENOMEM ; } +return fd; +} + +static int __add_probe_trace_events (struct perf_probe_event *pev, +struct probe_trace_event *tevs, +int ntevs,bool allow_suffix) +{ +int i, fd[2 ] = {-1 ,-1 }, up, ret; +struct probe_trace_event *tev =NULL ; +struct probe_cache *cache =NULL ; +struct strlist *namelist[2 ] = {NULL ,NULL }; + + up = pev->uprobes ?1 :0 ; + fd[up] =__open_probe_file_and_namelist (up, &namelist[up]); +if (fd[up] <0 ) +return fd[up]; ret =0 ;for (i =0 ; i < ntevs; i++) { tev = &tevs[i]; + up = tev->uprobes ?1 :0 ; +if (fd[up] ==-1 ) {/* Open the kprobe/uprobe_events */ + fd[up] =__open_probe_file_and_namelist (up, + &namelist[up]); +if (fd[up] <0 ) + goto close_out; + }/* Skip if the symbol is out of .text or blacklisted */ if (!tev->point.symbol && !pev->uprobes)continue ;/* Set new name for tev (and update namelist) */ - ret =probe_trace_event__set_name (tev, pev, namelist, + ret =probe_trace_event__set_name (tev, pev, namelist[up], allow_suffix);if (ret <0 )break ; - ret =probe_file__add_event (fd, tev); + ret =probe_file__add_event (fd[up], tev);if (ret <0 )break ;
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,probe_cache__delete (cache); } -strlist__delete (namelist); close_out: -close (fd); +for (up =0 ; up <2 ; up++) { +strlist__delete (namelist[up]); +if (fd[up] >=0 ) +close (fd[up]); + }return ret; }
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,return ret; } +/* Try to find probe_trace_event from all probe caches */ +static int find_cached_events_all (struct perf_probe_event *pev, +struct probe_trace_event **tevs) +{ +struct probe_trace_event *tmp_tevs =NULL ; +struct strlist *bidlist; +struct str_node *nd; +char *pathname; +int ntevs =0 ; +int ret; + +/* Get the buildid list of all valid caches */ + bidlist =build_id_cache__list_all (true); +if (!bidlist) { + ret = -errno; +pr_debug ("Failed to get buildids: %d\n" , ret); +return ret; + } + + ret =0 ; +strlist__for_each_entry (nd, bidlist) { + pathname =build_id_cache__origname (nd->s); + ret =find_cached_events (pev, &tmp_tevs, pathname); +/* In the case of cnt == 0, we just skip it */ +if (ret >0 ) + ret =concat_probe_trace_events (tevs, &ntevs, + &tmp_tevs, ret); +free (pathname); +if (ret <0 ) +break ; + } +strlist__delete (bidlist); + +if (ret <0 ) { +clear_probe_trace_events (*tevs, ntevs); +zfree (tevs); + }else + ret = ntevs; + +return ret; +} +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev,struct probe_trace_event **tevs) {
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,struct str_node *node;int ret, i; -if (pev->sdt) +if (pev->sdt) {/* For SDT/cached events, we use special search functions */ -return find_cached_events (pev, tevs, pev->target); - +if (!pev->target) +return find_cached_events_all (pev, tevs); +else +return find_cached_events (pev, tevs, pev->target); + } cache =probe_cache__new (pev->target);if (!cache)return 0 ;
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Search SDT/cached event from all probe caches
perf probe: Search SDT/cached event from all probe caches
Commit-ID: 1de7b8bf728fd8d51b0cc644003d0694c6e0feef Gitweb: http://git.kernel.org/tip/1de7b8bf728fd8d51b0cc644003d0694c6e0feef Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:28 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:07 -0300
perf probe: Search SDT/cached event from all probe caches
Search SDT/cached event from all probe caches if user doesn't pass any binary. With this, we don't have to specify target binary for SDT and named cached events (which start with %).
E.g. without this, a target binary must be passed with -x.
# perf probe -x /usr/lib64/libc-2.20.so -a %sdt_libc:\*
With this change, we don't need it anymore.
# perf probe -a %sdt_libc:\*
--- tools/perf/util/probe-event.c | 105 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 19 deletions(-)
tools/perf/util/probe-event.c +86 -19
@@ -2557,41 +2557,60 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,return 0 ; } -static int __add_probe_trace_events (struct perf_probe_event *pev, -struct probe_trace_event *tevs, -int ntevs,bool allow_suffix) +static int __open_probe_file_and_namelist (bool uprobe, +struct strlist **namelist) { -int i, fd, ret; -struct probe_trace_event *tev =NULL ; -struct probe_cache *cache =NULL ; -struct strlist *namelist; +int fd; - fd =probe_file__open (PF_FL_RW | (pev->uprobes ?PF_FL_UPROBE :0 )); + fd =probe_file__open (PF_FL_RW | (uprobe ?PF_FL_UPROBE :0 ));if (fd <0 )return fd;/* Get current event names */ - namelist =probe_file__get_namelist (fd); -if (!namelist) { + *namelist =probe_file__get_namelist (fd); +if (!(*namelist)) {pr_debug ("Failed to get current event list.\n" ); - ret = -ENOMEM ; - goto close_out; +close (fd); +return -ENOMEM ; } +return fd; +} + +static int __add_probe_trace_events (struct perf_probe_event *pev, +struct probe_trace_event *tevs, +int ntevs,bool allow_suffix) +{ +int i, fd[2 ] = {-1 ,-1 }, up, ret; +struct probe_trace_event *tev =NULL ; +struct probe_cache *cache =NULL ; +struct strlist *namelist[2 ] = {NULL ,NULL }; + + up = pev->uprobes ?1 :0 ; + fd[up] =__open_probe_file_and_namelist (up, &namelist[up]); +if (fd[up] <0 ) +return fd[up]; ret =0 ;for (i =0 ; i < ntevs; i++) { tev = &tevs[i]; + up = tev->uprobes ?1 :0 ; +if (fd[up] ==-1 ) {/* Open the kprobe/uprobe_events */ + fd[up] =__open_probe_file_and_namelist (up, + &namelist[up]); +if (fd[up] <0 ) + goto close_out; + }/* Skip if the symbol is out of .text or blacklisted */ if (!tev->point.symbol && !pev->uprobes)continue ;/* Set new name for tev (and update namelist) */ - ret =probe_trace_event__set_name (tev, pev, namelist, + ret =probe_trace_event__set_name (tev, pev, namelist[up], allow_suffix);if (ret <0 )break ; - ret =probe_file__add_event (fd, tev); + ret =probe_file__add_event (fd[up], tev);if (ret <0 )break ;
@@ -2614,9 +2633,12 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,probe_cache__delete (cache); } -strlist__delete (namelist); close_out: -close (fd); +for (up =0 ; up <2 ; up++) { +strlist__delete (namelist[up]); +if (fd[up] >=0 ) +close (fd[up]); + }return ret; }
@@ -2989,6 +3011,48 @@ static int find_cached_events(struct perf_probe_event *pev,return ret; } +/* Try to find probe_trace_event from all probe caches */ +static int find_cached_events_all (struct perf_probe_event *pev, +struct probe_trace_event **tevs) +{ +struct probe_trace_event *tmp_tevs =NULL ; +struct strlist *bidlist; +struct str_node *nd; +char *pathname; +int ntevs =0 ; +int ret; + +/* Get the buildid list of all valid caches */ + bidlist =build_id_cache__list_all (true); +if (!bidlist) { + ret = -errno; +pr_debug ("Failed to get buildids: %d\n" , ret); +return ret; + } + + ret =0 ; +strlist__for_each_entry (nd, bidlist) { + pathname =build_id_cache__origname (nd->s); + ret =find_cached_events (pev, &tmp_tevs, pathname); +/* In the case of cnt == 0, we just skip it */ +if (ret >0 ) + ret =concat_probe_trace_events (tevs, &ntevs, + &tmp_tevs, ret); +free (pathname); +if (ret <0 ) +break ; + } +strlist__delete (bidlist); + +if (ret <0 ) { +clear_probe_trace_events (*tevs, ntevs); +zfree (tevs); + }else + ret = ntevs; + +return ret; +} +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev,struct probe_trace_event **tevs) {
@@ -2998,10 +3062,13 @@ static int find_probe_trace_events_from_cache(struct perf_probe_event *pev,struct str_node *node;int ret, i; -if (pev->sdt) +if (pev->sdt) {/* For SDT/cached events, we use special search functions */ -return find_cached_events (pev, tevs, pev->target); - +if (!pev->target) +return find_cached_events_all (pev, tevs); +else +return find_cached_events (pev, tevs, pev->target); + } cache =probe_cache__new (pev->target);if (!cache)return 0 ;
PATCH 7/10 perf probe: Support @BUILDID or @FILE suffix for SDT events
In reply to Masami HiramatsuSupport @BUILDID or @FILE suffix for SDT events. This allows perf to add probes on SDTs/pre-cached events on given FILE or the file which has given BUILDID (also, this complements BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below. If you would like to add a probe on sdt_libstdcxx:catch on gcc, you can do as below.
----
# perf list sdt | tail -n 6
sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
# perf probe -a %sdt_libstdcxx:catch@0cc
Added new event:
sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
----
---
Changes in v12:
- Rename strlist__for_each to strlist__for_each_entry.
--- tools/perf/util/build-id.c | 43 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/probe-event.c | 17 ++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-)
tools/perf/util/build-id.c +43 -0
@@ -523,6 +523,49 @@ err_out: goto out_free; } +static bool str_is_build_id (const char *maybe_sbuild_id,size_t len) +{ +size_t i; + +for (i =0 ; i < len; i++) { +if (!isxdigit (maybe_sbuild_id[i])) +return false; + } +return true; +} + +/* Return the valid complete build-id */ +char *build_id_cache__complement (const char *incomplete_sbuild_id) +{ +struct strlist *bidlist; +struct str_node *nd, *cand =NULL ; +char *sbuild_id =NULL ; +size_t len =strlen (incomplete_sbuild_id); + +if (len >=SBUILD_ID_SIZE || + !str_is_build_id (incomplete_sbuild_id, len)) +return NULL ; + + bidlist =build_id_cache__list_all (true); +if (!bidlist) +return NULL ; + +strlist__for_each_entry (nd, bidlist) { +if (strncmp (nd->s, incomplete_sbuild_id, len) !=0 ) +continue ; +if (cand) {/* Error: There are more than 2 candidates. */ + cand =NULL ; +break ; + } + cand = nd; + } +if (cand) + sbuild_id =strdup (cand->s); +strlist__delete (bidlist); + +return sbuild_id; +} +char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso) {
tools/perf/util/build-id.h +1 -0
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);struct strlist *build_id_cache__list_all (bool validonly); +char *build_id_cache__complement (const char *incomplete_sbuild_id);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);
tools/perf/util/probe-event.c +15 -2
@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) ptr =strpbrk (arg,";=@+%" );if (pev->sdt) {if (ptr) { -semantic_error ("%s must contain only an SDT event name.\n" , arg); -return -EINVAL ; +if (*ptr !='@' ) { +semantic_error ("%s must be an SDT name.\n" , + arg); +return -EINVAL ; + } +/* This must be a target file name or build id */ + tmp =build_id_cache__complement (ptr +1 ); +if (tmp) { + pev->target =build_id_cache__origname (tmp); +free (tmp); + }else + pev->target =strdup (ptr +1 ); +if (!pev->target) +return -ENOMEM ; + *ptr ='\0' ; } ret =parse_perf_probe_event_name (&arg, pev);if (ret ==0 ) {
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
Em Tue, Jul 12, 2016 at 07:05:37PM +0900, Masami Hiramatsu escreveu:
Quoted 7 lines
Support @BUILDID or @FILE suffix for SDT events. This allows perf to add probes on SDTs/pre-cached events on given FILE or the file which has given BUILDID (also, this complements BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below. If you would like to add a probe on sdt_libstdcxx:catch on gcc, you can do as below.
Ok, how to add those entries?
[root@jouet hello_world]# perf probe -x /usr/bin/gcc -a %sdt_gcc:\*
Error: Failed to add events.
[root@jouet hello_world]# perf probe --verbose -x /usr/bin/gcc -a %sdt_gcc:\* probe-definition(0): %sdt_gcc:*
0 arguments
symbol:throw file:(null) line:0 offset:0 return:0 lazy:(null) symbol:rethrow file:(null) line:0 offset:0 return:0 lazy:(null) symbol:catch file:(null) line:0 offset:0 return:0 lazy:(null) symbol:unwind file:(null) line:0 offset:0 return:0 lazy:(null)
Error: Failed to add events. Reason: No such file or directory (Code: -2)
[root@jouet hello_world]#
Can those messages be improved? What am I missing?
Quoted 121 lines
----
# perf list sdt | tail -n 6 sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) # perf probe -a %sdt_libstdcxx:catch@0cc Added new event: sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
----Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v12:
- Renamestrlist__for_eachtostrlist__for_each_entry.--- tools/perf/util/build-id.c | 43 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/probe-event.c | 17 ++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-)tools/perf/util/build-id.c +43
-0@@ -523,6 +523,49 @@ err_out: goto out_free; } +static bool str_is_build_id (const char *maybe_sbuild_id,size_t len) +{ +size_t i; + +for (i =0 ; i < len; i++) { +if (!isxdigit (maybe_sbuild_id[i])) +return false; + } +return true; +} + +/* Return the valid complete build-id */ +char *build_id_cache__complement (const char *incomplete_sbuild_id) +{ +struct strlist *bidlist; +struct str_node *nd, *cand =NULL ; +char *sbuild_id =NULL ; +size_t len =strlen (incomplete_sbuild_id); + +if (len >=SBUILD_ID_SIZE || + !str_is_build_id (incomplete_sbuild_id, len)) +return NULL ; + + bidlist =build_id_cache__list_all (true); +if (!bidlist) +return NULL ; + +strlist__for_each_entry (nd, bidlist) { +if (strncmp (nd->s, incomplete_sbuild_id, len) !=0 ) +continue ; +if (cand) {/* Error: There are more than 2 candidates. */ + cand =NULL ; +break ; + } + cand = nd; + } +if (cand) + sbuild_id =strdup (cand->s); +strlist__delete (bidlist); + +return sbuild_id; +} +char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso) {tools/perf/util/build-id.h +1
-0@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);struct strlist *build_id_cache__list_all (bool validonly); +char *build_id_cache__complement (const char *incomplete_sbuild_id);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);tools/perf/util/probe-event.c +15
-2@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) ptr =strpbrk (arg,";=@+%" );if (pev->sdt) {if (ptr) { -semantic_error ("%s must contain only an SDT event name.\n" , arg); -return -EINVAL ; +if (*ptr !='@' ) { +semantic_error ("%s must be an SDT name.\n" , + arg); +return -EINVAL ; + } +/* This must be a target file name or build id */ + tmp =build_id_cache__complement (ptr +1 ); +if (tmp) { + pev->target =build_id_cache__origname (tmp); +free (tmp); + }else + pev->target =strdup (ptr +1 ); +if (!pev->target) +return -ENOMEM ; + *ptr ='\0' ; } ret =parse_perf_probe_event_name (&arg, pev);if (ret ==0 ) {
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
Em Wed, Jul 13, 2016 at 04:50:19PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 11 lines
Em Tue, Jul 12, 2016 at 07:05:37PM +0900, Masami Hiramatsu escreveu:
Quoted 7 lines
Support @BUILDID or @FILE suffix for SDT events. This allows perf to add probes on SDTs/pre-cached events on given FILE or the file which has given BUILDID (also, this complements BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below. If you would like to add a probe on sdt_libstdcxx:catch on gcc, you can do as below.Ok, how to add those entries?
Quoted 11 lines
[root@jouet hello_world]# perf probe -x
/usr/bin/gcc-a %sdt_gcc:\*
Error: Failed to add events.
[root@jouet hello_world]# perf probe --verbose -x/usr/bin/gcc-a %sdt_gcc:\* probe-definition(0): %sdt_gcc:*
0 arguments
symbol:throw file:(null) line:0 offset:0 return:0 lazy:(null) symbol:rethrow file:(null) line:0 offset:0 return:0 lazy:(null) symbol:catch file:(null) line:0 offset:0 return:0 lazy:(null) symbol:unwind file:(null) line:0 offset:0 return:0 lazy:(null)
Error: Failed to add events. Reason: No such file or directory (Code: -2)
[root@jouet hello_world]#
So, ok, I managed with:
[root@jouet ~]# perf probe -x /usr/bin/gcc %sdt_libstdcxx:\* Added new events:
sdt_libstdcxx:throw (on %* in /usr/bin/gcc) sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc) sdt_libstdcxx:catch (on %* in /usr/bin/gcc)
You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
[root@jouet ~]#
I then tried to remove the events just created:
# perf probe -d %sdt_libstdcxx:\* #
It tells me nothing, cool, probably it removed it all, then I go and try re-adding them:
[root@jouet ~]# perf probe -x /usr/bin/gcc %sdt_libstdcxx:\*
Error: event "throw" already exists.
Hint: Remove existing event by 'perf probe -d'
or force duplicates by 'perf probe -f'
or set 'force=yes' in BPF source.
Error: Failed to add events.
[root@jouet ~]#
Huh?
Then I tried like you did above, using 'perf list sdt'
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
[root@jouet ~]#
But they appear via 'perf probe -l'
[root@jouet ~]# perf probe -l sdt_libs*
sdt_libstdcxx:catch (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc) sdt_libstdcxx:rethrow (on d_print_subexpr+280@libsupc++/cp-demangle.c in /usr/bin/gcc) sdt_libstdcxx:throw (on d_print_subexpr+93@libsupc++/cp-demangle.c in /usr/bin/gcc)
[root@jouet ~]#
There is no event, then, guessing, I tried removing that %, since I don't see it in the 'perf probe -l' output, so it must've been just some distracting artifact at the time of adding the SDT prove:
[root@jouet ~]# perf probe -d sdt_libstdcxx:\*
Removed event: sdt_libstdcxx:catch
Removed event: sdt_libstdcxx:rethrow
Removed event: sdt_libstdcxx:throw
[root@jouet ~]# perf probe -l sdt_libs*
[root@jouet ~]#
Ok, now it works, but then if I try having both the gcc and libstdc++ ones, I can't:
[root@jouet ~]# perf probe -x /usr/lib64/libstdc++.so.6 %sdt_libstdcxx:\*
Error: event "catch" already exists.
Hint: Remove existing event by 'perf probe -d'
or force duplicates by 'perf probe -f'
or set 'force=yes' in BPF source.
Error: Failed to add events.
So I forced it:
[root@jouet ~]# perf probe -f -x /usr/lib64/libstdc++.so.6 %sdt_libstdcxx:\* Added new events:
sdt_libstdcxx:catch_1 (on %* in /usr/lib64/libstdc++.so.6.0.22) sdt_libstdcxx:throw_1 (on %* in /usr/lib64/libstdc++.so.6.0.22) sdt_libstdcxx:rethrow_1 (on %* in /usr/lib64/libstdc++.so.6.0.22)
You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:rethrow_1 -aR sleep 1
[root@jouet ~]#
If it will rename it, why require -f? Where is the duplicity?
If I go and re-read all the discussion on the thread that lead to these patches, I may figure out all those questions, but then, that would be a lot of info to have in mind :-\
I.e. I would suggest that no -f should be needed, that that "Error: event "catch" already exists" shouldn't be even emitted, since those will be different events, i.e. one is named "sdt_libstdcxx:catch" and the other "sdt_libstdcxx:catch_1"...
But that becomes an usability problem, couldn't it have the basename in it? I.e.:
sdt_gcc_libstdcxx:catch and sdt_libstdc++:catch?
I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
- Arnaldo
Quoted 123 lines
Can those messages be improved? What am I missing?
Quoted 121 lines
----
# perf list sdt | tail -n 6 sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event] sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49) # perf probe -a %sdt_libstdcxx:catch@0cc Added new event: sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
----Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v12:
- Renamestrlist__for_eachtostrlist__for_each_entry.--- tools/perf/util/build-id.c | 43 +++++++++++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/probe-event.c | 17 ++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-)tools/perf/util/build-id.c +43
-0@@ -523,6 +523,49 @@ err_out: goto out_free; } +static bool str_is_build_id (const char *maybe_sbuild_id,size_t len) +{ +size_t i; + +for (i =0 ; i < len; i++) { +if (!isxdigit (maybe_sbuild_id[i])) +return false; + } +return true; +} + +/* Return the valid complete build-id */ +char *build_id_cache__complement (const char *incomplete_sbuild_id) +{ +struct strlist *bidlist; +struct str_node *nd, *cand =NULL ; +char *sbuild_id =NULL ; +size_t len =strlen (incomplete_sbuild_id); + +if (len >=SBUILD_ID_SIZE || + !str_is_build_id (incomplete_sbuild_id, len)) +return NULL ; + + bidlist =build_id_cache__list_all (true); +if (!bidlist) +return NULL ; + +strlist__for_each_entry (nd, bidlist) { +if (strncmp (nd->s, incomplete_sbuild_id, len) !=0 ) +continue ; +if (cand) {/* Error: There are more than 2 candidates. */ + cand =NULL ; +break ; + } + cand = nd; + } +if (cand) + sbuild_id =strdup (cand->s); +strlist__delete (bidlist); + +return sbuild_id; +} +char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso) {tools/perf/util/build-id.h +1
-0@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);struct strlist *build_id_cache__list_all (bool validonly); +char *build_id_cache__complement (const char *incomplete_sbuild_id);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);tools/perf/util/probe-event.c +15
-2@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) ptr =strpbrk (arg,";=@+%" );if (pev->sdt) {if (ptr) { -semantic_error ("%s must contain only an SDT event name.\n" , arg); -return -EINVAL ; +if (*ptr !='@' ) { +semantic_error ("%s must be an SDT name.\n" , + arg); +return -EINVAL ; + } +/* This must be a target file name or build id */ + tmp =build_id_cache__complement (ptr +1 ); +if (tmp) { + pev->target =build_id_cache__origname (tmp); +free (tmp); + }else + pev->target =strdup (ptr +1 ); +if (!pev->target) +return -ENOMEM ; + *ptr ='\0' ; } ret =parse_perf_probe_event_name (&arg, pev);if (ret ==0 ) {
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 1 line
I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
So it is here:
-> 976 T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events
June, 24, you forgot to rebase it for this new cset series, I'm doing that now.
- Arnaldo
Arnaldo Carvalho de Melo
maintainerRe: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
Em Wed, Jul 13, 2016 at 09:16:32PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 1 line
I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
So it is here:
-> 976 T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events
June, 24, you forgot to rebase it for this new cset series, I'm doing that now.
Ok, now it works:
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
sdt_libc:lll_lock_wait_private [SDT event] sdt_libc:longjmp [SDT event] sdt_libc:longjmp_target [SDT event] sdt_libc:memory_arena_new [SDT event] sdt_libc:memory_arena_retry [SDT event] sdt_libc:memory_arena_reuse [SDT event] sdt_libc:memory_arena_reuse_free_list [SDT event] sdt_libc:memory_arena_reuse_wait [SDT event] sdt_libc:memory_calloc_retry [SDT event] sdt_libc:memory_heap_free [SDT event] sdt_libc:memory_heap_less [SDT event] sdt_libc:memory_heap_more [SDT event] sdt_libc:memory_heap_new [SDT event] sdt_libc:memory_malloc_retry [SDT event] sdt_libc:memory_mallopt [SDT event] sdt_libc:memory_mallopt_arena_max [SDT event] sdt_libc:memory_mallopt_arena_test [SDT event] sdt_libc:memory_mallopt_check_action [SDT event] sdt_libc:memory_mallopt_free_dyn_thresholds [SDT event] sdt_libc:memory_mallopt_mmap_max [SDT event] sdt_libc:memory_mallopt_mmap_threshold [SDT event] sdt_libc:memory_mallopt_mxfast [SDT event] sdt_libc:memory_mallopt_perturb [SDT event] sdt_libc:memory_mallopt_top_pad [SDT event] sdt_libc:memory_mallopt_trim_threshold [SDT event] sdt_libc:memory_memalign_retry [SDT event] sdt_libc:memory_realloc_retry [SDT event] sdt_libc:memory_sbrk_less [SDT event] sdt_libc:memory_sbrk_more [SDT event] sdt_libc:setjmp [SDT event] sdt_libgcc:unwind [SDT event] sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
[root@jouet ~]#
Re: [PATCH perf/core 07/10] perf probe: Support @BUILDID or @FILE suffix for SDT events
Quoted 10 lines · On Wed, 13 Jul 2016 21:20:48 -0300 Arnaldo Carvalho de Melo <[email protected]>…
Em Wed, Jul 13, 2016 at 09:16:32PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
Em Wed, Jul 13, 2016 at 09:07:19PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 1 line
I'm going to look my inbox for patches I overlook that added 'perf list sdt'...
So it is here:
-> 976 T 06/24 Masami Hiramats (7.2K) [PATCH perf/core v12 08/16] perf-list: Show SDT and pre-cached events
June, 24, you forgot to rebase it for this new cset series, I'm doing that now.
Ah, I just dropped it because this series still not support direct recording yet. If we show the below SDTs by perf-list, we have to support it on perf-record which is under developed now.
Thank you,
Quoted 46 lines
Ok, now it works:
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
sdt_libc:lll_lock_wait_private [SDT event] sdt_libc:longjmp [SDT event] sdt_libc:longjmp_target [SDT event] sdt_libc:memory_arena_new [SDT event] sdt_libc:memory_arena_retry [SDT event] sdt_libc:memory_arena_reuse [SDT event] sdt_libc:memory_arena_reuse_free_list [SDT event] sdt_libc:memory_arena_reuse_wait [SDT event] sdt_libc:memory_calloc_retry [SDT event] sdt_libc:memory_heap_free [SDT event] sdt_libc:memory_heap_less [SDT event] sdt_libc:memory_heap_more [SDT event] sdt_libc:memory_heap_new [SDT event] sdt_libc:memory_malloc_retry [SDT event] sdt_libc:memory_mallopt [SDT event] sdt_libc:memory_mallopt_arena_max [SDT event] sdt_libc:memory_mallopt_arena_test [SDT event] sdt_libc:memory_mallopt_check_action [SDT event] sdt_libc:memory_mallopt_free_dyn_thresholds [SDT event] sdt_libc:memory_mallopt_mmap_max [SDT event] sdt_libc:memory_mallopt_mmap_threshold [SDT event] sdt_libc:memory_mallopt_mxfast [SDT event] sdt_libc:memory_mallopt_perturb [SDT event] sdt_libc:memory_mallopt_top_pad [SDT event] sdt_libc:memory_mallopt_trim_threshold [SDT event] sdt_libc:memory_memalign_retry [SDT event] sdt_libc:memory_realloc_retry [SDT event] sdt_libc:memory_sbrk_less [SDT event] sdt_libc:memory_sbrk_more [SDT event] sdt_libc:setjmp [SDT event] sdt_libgcc:unwind [SDT event] sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6) [SDT event]sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
[root@jouet ~]#
Signature · 1 line
Masami Hiramatsu <[email protected]>
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Support @BUILDID or @FILE suffix for SDT events
In reply to Masami Hiramatsuperf probe: Support @BUILDID or @FILE suffix for SDT events
Commit-ID: a598180aa1279bac4d24dfc85cd2d78553c4210d Gitweb: http://git.kernel.org/tip/a598180aa1279bac4d24dfc85cd2d78553c4210d Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:37 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:08 -0300
perf probe: Support @BUILDID or @FILE suffix for SDT events
Support @BUILDID or @FILE suffix for SDT events. This allows perf to add probes on SDTs/pre-cached events on given FILE or the file which has given BUILDID (also, this complements BUILDID.)
For example, both gcc and libstdc++ has same SDTs as below. If you would like to add a probe on sdt_libstdcxx:catch on gcc, you can do as below.
----
# perf list sdt | tail -n 6
sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
# perf probe -a %sdt_libstdcxx:catch@0cc
Added new event:
sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
----
Committer note:
Doing the full sequence of steps to get the results above:
With a clean build-id cache:
[root@jouet ~]# rm -rf ~/.debug/
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
[root@jouet ~]#
No events whatsoever, then, we can add all events in gcc to the build-id cache, doing a --add + --dry-run:
[root@jouet ~]# perf probe --dry-run --cache -x /usr/bin/gcc --add %sdt_libstdcxx:\*
Added new events:
sdt_libstdcxx:throw (on %* in /usr/bin/gcc)
sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc)
sdt_libstdcxx:catch (on %* in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
[root@jouet ~]#
It really didn't add any events, it just cached them:
[root@jouet ~]# perf probe -l
[root@jouet ~]#
We can see that it was cached as:
[root@jouet ~]# ls -la ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/
total 976
drwxr-xr-x. 2 root root 4096 Jul 13 21:47 .
drwxr-xr-x. 3 root root 4096 Jul 13 21:47 ..
-rwxr-xr-x. 4 root root 985912 Jun 22 18:52 elf
-rw-r--r--. 1 root root 303 Jul 13 21:47 probes
[root@jouet ~]# file ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/elf
/root/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2, stripped [root@jouet ~]# cat ~/.debug/usr/bin/gcc/9a0730e2bcc6d2a2003d21ac46807e8ee6bcb7c2/probes
%sdt_libstdcxx:throw=throw
p:sdt_libstdcxx/throw /usr/bin/gcc:0x71ffd
%sdt_libstdcxx:rethrow=rethrow
p:sdt_libstdcxx/rethrow /usr/bin/gcc:0x720b8
%sdt_libstdcxx:catch=catch
p:sdt_libstdcxx/catch /usr/bin/gcc:0x7307f
%sdt_libgcc:unwind=unwind
p:sdt_libgcc/unwind /usr/bin/gcc:0x7eec0
#sdt_libstdcxx:*=%*
[root@jouet ~]#
Ok, now we can use 'perf probe' to refer to those cached entries as:
Humm, nope, doing as above we end up with:
[root@jouet ~]# perf probe -a %sdt_libstdcxx:catch
Semantic error :* is bad for event name -it must follow C symbol-naming rule.
Error: Failed to add events.
[root@jouet ~]#
But it worked at some point, lets try not using --dry-run:
Resetting everything:
# rm -rf ~/.debug/ # perf probe -d *:* # perf probe -l # perf list sdt
List of pre-defined events (to be used in -e):
#
Ok, now it cached everything, even things we haven't asked it to (sdt_libgcc:unwind):
[root@jouet ~]# perf probe -x /usr/bin/gcc --add %sdt_libstdcxx:\*
Added new events:
sdt_libstdcxx:throw (on %* in /usr/bin/gcc)
sdt_libstdcxx:rethrow (on %* in /usr/bin/gcc)
sdt_libstdcxx:catch (on %* in /usr/bin/gcc)You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
sdt_libgcc:unwind [SDT event]
sdt_libstdcxx:catch [SDT event]
sdt_libstdcxx:rethrow [SDT event]
sdt_libstdcxx:throw [SDT event][root@jouet ~]#
And we have the events in place:
[root@jouet ~]# perf probe -l
sdt_libstdcxx:catch (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc) sdt_libstdcxx:rethrow (on d_print_subexpr+280@libsupc++/cp-demangle.c in /usr/bin/gcc) sdt_libstdcxx:throw (on d_print_subexpr+93@libsupc++/cp-demangle.c in /usr/bin/gcc)
[root@jouet ~]#
And trying to use them at least has 'perf trace --event sdt*:*' working.
Then, if we try to add the ones in libstdc++:
[root@jouet ~]# perf probe -x /usr/lib64/libstdc++.so.6 -a %sdt_libstdcxx:\*
Error: event "catch" already exists.
Hint: Remove existing event by 'perf probe -d'
or force duplicates by 'perf probe -f'
or set 'force=yes' in BPF source.
Error: Failed to add events.
[root@jouet ~]#
Doesn't work, dups, but at least this served to, unbeknownst to the user, add the SDT probes in /usr/lib64/libstdc++.so.6!
[root@jouet ~]# perf list sdt
List of pre-defined events (to be used in -e):
sdt_libgcc:unwind [SDT event]
sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:rethrow@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event]
sdt_libstdcxx:throw@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event][root@jouet ~]#
Now we should be able to get to the original cset comment, if we remove all SDTs events in place, not from the cache, from the kernel, where it was set up as:
[root@jouet ~]# ls -la /sys/kernel/debug/tracing/events/sdt_libstdcxx/ total 0
drwxr-xr-x. 5 root root 0 Jul 13 22:00 .
drwxr-xr-x. 80 root root 0 Jul 13 21:56 ..
drwxr-xr-x. 2 root root 0 Jul 13 22:00 catch -rw-r--r--. 1 root root 0 Jul 13 22:00 enable -rw-r--r--. 1 root root 0 Jul 13 22:00 filter drwxr-xr-x. 2 root root 0 Jul 13 22:00 rethrow drwxr-xr-x. 2 root root 0 Jul 13 22:00 throw
[root@jouet ~]#
[root@jouet ~]# head -2 /sys/kernel/debug/tracing/events/sdt_libstdcxx/throw/format
name: throw
ID: 2059
[root@jouet ~]#
Now to remove it:
[root@jouet ~]# perf probe -d sdt_libstdc*:*
Removed event: sdt_libstdcxx:catch
Removed event: sdt_libstdcxx:rethrow
Removed event: sdt_libstdcxx:throw
[root@jouet ~]#
Which caused:
[root@jouet ~]# ls -la /sys/kernel/debug/tracing/events/sdt_libstdcxx/
ls: cannot access '/sys/kernel/debug/tracing/events/sdt_libstdcxx/': No such file or directory [root@jouet ~]#
Ok, now we can do:
[root@jouet ~]# perf list sdt_libstdcxx:catch
List of pre-defined events (to be used in -e):
sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event][root@jouet ~]#
So, these are not really 'pre-defined events', i.e. we can't use them with 'perf record --event':
[root@jouet ~]# perf record --event sdt_libstdcxx:catch*
event syntax error: 'sdt_libstdcxx:catch*'
\___ unknown tracepoint Error: File /sys/kernel/debug/tracing/events/sdt_libstdcxx/catch* not found.
Hint: Perhaps this kernel misses some CONFIG_ setting to enable this feature?.
<SNIP>
[root@jouet ~]#
To have it really pre-defined we must use perf probe to get its definition from the cache and set it up in the kernel, creating the tracepoint to _then_ use it with 'perf record --event':
[root@jouet ~]# perf probe -a sdt_libstdcxx:catch Semantic error :There is non-digit char in line number. <SNIP>
Oops, there is another gotcha here, we need that pesky '%' character:
[root@jouet ~]# perf probe -a %sdt_libstdcxx:catch
Added new events:
sdt_libstdcxx:catch (on %catch in /usr/bin/gcc) sdt_libstdcxx:catch_1 (on %catch in /usr/lib64/libstdc++.so.6.0.22)
You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch_1 -aR sleep 1
[root@jouet ~]#
But then we added _two_ events, one with the name we expected, the other one with a _ added, when doing the analysis we need to pay attention to who maps to who.
And here is where we get to the point of this patch, which is to be able to disambiguate those definitions for 'catch' in the build-id cache, but first we need remove those events we just added:
[root@jouet ~]# perf probe -d %sdt_libstdcxx:catch
Oops, that didn't remove anything, we need to _remove_ that % char in this case:
[root@jouet ~]# perf probe -d sdt_libstdcxx:catch Removed event: sdt_libstdcxx:catch
And we need to remove the other event added, i.e. I forgot to add a * at the end:
[root@jouet ~]# perf probe -d sdt_libstdcxx:catch* Removed event: sdt_libstdcxx:catch_1 [root@jouet ~]#
Ok, disambiguating it using what is in this patch:
[root@jouet ~]# perf list sdt_libstdcxx:catch
List of pre-defined events (to be used in -e):
sdt_libstdcxx:catch@/usr/bin/gcc(9a0730e2bcc6) [SDT event]
sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.22(ef2b7066559a) [SDT event] [root@jouet ~]#
[root@jouet ~]# perf probe -a %sdt_libstdcxx:catch@9a07 Added new event:
sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)
You can now use it in all perf tools, such as:
perf record -e sdt_libstdcxx:catch -aR sleep 1
[root@jouet ~]# perf probe -l
sdt_libstdcxx:catch (on execute_cfa_program+1551@../../../libgcc/unwind-dw2.c in /usr/bin/gcc)
[root@jouet ~]#
Yeah, it works! But we need to try and simplify this :-)
Update: Some aspects of this simplification take place in the following
patches.
--- tools/perf/util/build-id.c | 43 +++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 1 + tools/perf/util/probe-event.c | 17 +++++++++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-)
tools/perf/util/build-id.c +43 -0
@@ -523,6 +523,49 @@ err_out: goto out_free; } +static bool str_is_build_id (const char *maybe_sbuild_id,size_t len) +{ +size_t i; + +for (i =0 ; i < len; i++) { +if (!isxdigit (maybe_sbuild_id[i])) +return false; + } +return true; +} + +/* Return the valid complete build-id */ +char *build_id_cache__complement (const char *incomplete_sbuild_id) +{ +struct strlist *bidlist; +struct str_node *nd, *cand =NULL ; +char *sbuild_id =NULL ; +size_t len =strlen (incomplete_sbuild_id); + +if (len >=SBUILD_ID_SIZE || + !str_is_build_id (incomplete_sbuild_id, len)) +return NULL ; + + bidlist =build_id_cache__list_all (true); +if (!bidlist) +return NULL ; + +strlist__for_each_entry (nd, bidlist) { +if (strncmp (nd->s, incomplete_sbuild_id, len) !=0 ) +continue ; +if (cand) {/* Error: There are more than 2 candidates. */ + cand =NULL ; +break ; + } + cand = nd; + } +if (cand) + sbuild_id =strdup (cand->s); +strlist__delete (bidlist); + +return sbuild_id; +} +char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso) {
tools/perf/util/build-id.h +1 -0
@@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);char *build_id_cache__cachedir (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso);struct strlist *build_id_cache__list_all (bool validonly); +char *build_id_cache__complement (const char *incomplete_sbuild_id);int build_id_cache__list_build_ids (const char *pathname,struct strlist **result);bool build_id_cache__cached (const char *sbuild_id);
tools/perf/util/probe-event.c +15 -2
@@ -1251,8 +1251,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) ptr =strpbrk (arg,";=@+%" );if (pev->sdt) {if (ptr) { -semantic_error ("%s must contain only an SDT event name.\n" , arg); -return -EINVAL ; +if (*ptr !='@' ) { +semantic_error ("%s must be an SDT name.\n" , + arg); +return -EINVAL ; + } +/* This must be a target file name or build id */ + tmp =build_id_cache__complement (ptr +1 ); +if (tmp) { + pev->target =build_id_cache__origname (tmp); +free (tmp); + }else + pev->target =strdup (ptr +1 ); +if (!pev->target) +return -ENOMEM ; + *ptr ='\0' ; } ret =parse_perf_probe_event_name (&arg, pev);if (ret ==0 ) {
PATCH 8/10 perf probe: Support a special SDT probe format
In reply to Masami HiramatsuSupport a special SDT probe format which can omit the '%' prefix only if the SDT group name starts with "sdt_". So, for example both of "%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable for perf probe --add.
E.g. without this:
----
# perf probe -a sdt_libc:setjmp
Semantic error :There is non-digit char in line number.
...
----
With this:
----
# perf probe -a sdt_libc:setjmp
Added new event:
sdt_libc:setjmp (on %setjmp in /usr/lib64/libc-2.20.so)You can now use it in all perf tools, such as:
perf record -e sdt_libc:setjmp -aR sleep 1
----
--- tools/perf/Documentation/perf-probe.txt | 4 +++- tools/perf/util/probe-event.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-probe.txt +3 -1
@@ -152,7 +152,9 @@ Probe points are defined by following syntax. [[GROUP:]EVENT=]SRC;PTN [ARG ...] 4) Pre-defined SDT events or cached event with name - %[PROVIDER:]SDTEVENT + %[sdt_PROVIDER:]SDTEVENT + or, + sdt_PROVIDER:SDTEVENT 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe. Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
tools/perf/util/probe-event.c +10 -2
@@ -1243,9 +1243,17 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)if (!arg)return -EINVAL ; -if (arg[0 ] =='%' ) { +/* +* If the probe point starts with '%', +* or starts with "sdt_" and has a ':' but no '=', +* then it should be a SDT/cached probe point. +*/ +if (arg[0 ] =='%' || + (!strncmp (arg,"sdt_" ,4 ) && + !!strchr (arg,':' ) && !strchr (arg,'=' ))) { pev->sdt = true; - arg++; +if (arg[0 ] =='%' ) + arg++; } ptr =strpbrk (arg,";=@+%" );
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Support a special SDT probe format
perf probe: Support a special SDT probe format
Commit-ID: 7e9fca51fbf8430e27fb6b29299eda575e3f00cf Gitweb: http://git.kernel.org/tip/7e9fca51fbf8430e27fb6b29299eda575e3f00cf Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:46 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:09 -0300
perf probe: Support a special SDT probe format
Support a special SDT probe format which can omit the '%' prefix only if the SDT group name starts with "sdt_". So, for example both of "%sdt_libc:setjump" and "sdt_libc:setjump" are acceptable for perf probe --add.
E.g. without this:
# perf probe -a sdt_libc:setjmp Semantic error :There is non-digit char in line number. ...
With this:
# perf probe -a sdt_libc:setjmp
Added new event:
sdt_libc:setjmp (on %setjmp in /usr/lib64/libc-2.20.so)You can now use it in all perf tools, such as:
perf record -e sdt_libc:setjmp -aR sleep 1
--- tools/perf/Documentation/perf-probe.txt | 4 +++- tools/perf/util/probe-event.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-probe.txt +3 -1
@@ -152,7 +152,9 @@ Probe points are defined by following syntax. [[GROUP:]EVENT=]SRC;PTN [ARG ...] 4) Pre-defined SDT events or cached event with name - %[PROVIDER:]SDTEVENT + %[sdt_PROVIDER:]SDTEVENT + or, + sdt_PROVIDER:SDTEVENT 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. You can also specify a group name by 'GROUP', if omitted, set 'probe' is used for kprobe and 'probe_<bin>' is used for uprobe. Note that using existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can hide embedded events in the
tools/perf/util/probe-event.c +10 -2
@@ -1243,9 +1243,17 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)if (!arg)return -EINVAL ; -if (arg[0 ] =='%' ) { +/* +* If the probe point starts with '%', +* or starts with "sdt_" and has a ':' but no '=', +* then it should be a SDT/cached probe point. +*/ +if (arg[0 ] =='%' || + (!strncmp (arg,"sdt_" ,4 ) && + !!strchr (arg,':' ) && !strchr (arg,'=' ))) { pev->sdt = true; - arg++; +if (arg[0 ] =='%' ) + arg++; } ptr =strpbrk (arg,";=@+%" );
PATCH 9/10 perf build: Add sdt feature detection
In reply to Masami HiramatsuThis checks whether sys/sdt.h is available or not, which is required for DTRACE_PROBE().
We can disable this feature by passing NO_SDT=1 when building.
This flag will be used for SDT test case and further SDT events in perftools.
--- tools/perf/Makefile.perf | 3 +++ tools/perf/config/Makefile | 10 ++++++++++ tools/perf/tests/make | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-)
tools/build/Makefile.feature +2 -1
@@ -61,7 +61,8 @@ FEATURE_TESTS_BASIC := \ zlib \ lzma \ get_cpuid \ - bpf + bpf \ + sdt # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list # of all feature tests
tools/build/feature/Makefile +5 -1
@@ -44,7 +44,8 @@ FILES= \ test-zlib.bin \ test-lzma.bin \ test-bpf.bin \ - test-get_cpuid.bin + test-get_cpuid.bin \ + test-sdt.bin FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -209,6 +210,9 @@ $(OUTPUT)test-get_cpuid.bin: $(OUTPUT)test-bpf.bin: $(BUILD) +$(OUTPUT)test-sdt.bin: + $(BUILD) + -include $(OUTPUT)*.d ###############################
tools/build/feature/test-all.c +5 -0
@@ -141,6 +141,10 @@# include "test-libcrypto.c" #undef main +#define main main_test_sdt +# include "test-sdt.c" +#undef main +int main (int argc,char *argv[]) {main_test_libpython ();
@@ -173,6 +177,7 @@ int main(int argc, char *argv[])main_test_get_cpuid ();main_test_bpf ();main_test_libcrypto (); +main_test_sdt ();return 0 ; }
tools/build/feature/test-sdt.c new file +7 -0
@@ -0,0 +1,7 @@ +#include <sys/sdt.h> + +int main (void ) +{ +DTRACE_PROBE (provider, name); +return 0 ; +}
tools/perf/Makefile.perf +3 -0
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak # # Define NO_LIBBPF if you do not want BPF support # +# Define NO_SDT if you do not want to define SDT event in perf tools, +# note that it doesn't disable SDT scanning support. +# # Define FEATURES_DUMP to provide features detection dump file # and bypass the feature detection
tools/perf/config/Makefile +10 -0
@@ -349,6 +349,16 @@ ifndef NO_LIBELF endif # NO_LIBBPF endif # NO_LIBELF +ifndef NO_SDT + ifneq ($(feature-sdt), 1) + msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev); + NO_SDT := 1; + else + CFLAGS += -DHAVE_SDT_EVENT + $(call detected,CONFIG_SDT_EVENT) + endif +endif + ifdef PERF_HAVE_JITDUMP ifndef NO_DWARF $(call detected,CONFIG_JITDUMP)
tools/perf/tests/make +2 -1
@@ -82,6 +82,7 @@ make_no_auxtrace := NO_AUXTRACE=1 make_no_libbpf := NO_LIBBPF=1 make_no_libcrypto := NO_LIBCRYPTO=1 make_with_babeltrace:= LIBBABELTRACE=1 +make_no_sdt := NO_SDT=1 make_tags := tags make_cscope := cscope make_help := help
@@ -105,7 +106,7 @@ make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 -make_minimal += NO_LIBCRYPTO=1 +make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 # $(run) contains all available tests run := make_pure
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf build: Add sdt feature detection
perf build: Add sdt feature detection
Commit-ID: e26e63be64a108c1fd12020b93b5b447ffe0532b Gitweb: http://git.kernel.org/tip/e26e63be64a108c1fd12020b93b5b447ffe0532b Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:05:56 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:09 -0300
perf build: Add sdt feature detection
This checks whether sys/sdt.h is available or not, which is required for DTRACE_PROBE().
We can disable this feature by passing NO_SDT=1 when building.
This flag will be used for SDT test case and further SDT events in perftools.
--- tools/build/Makefile.feature | 3 ++- tools/build/feature/Makefile | 6 +++++- tools/build/feature/test-all.c | 5 +++++ tools/build/feature/test-sdt.c | 7 +++++++ tools/perf/Makefile.perf | 3 +++ tools/perf/config/Makefile | 10 ++++++++++ tools/perf/tests/make | 3 ++- 7 files changed, 34 insertions(+), 3 deletions(-)
tools/build/Makefile.feature +2 -1
@@ -62,7 +62,8 @@ FEATURE_TESTS_BASIC := \ zlib \ lzma \ get_cpuid \ - bpf + bpf \ + sdt # FEATURE_TESTS_BASIC + FEATURE_TESTS_EXTRA is the complete list # of all feature tests
tools/build/feature/Makefile +5 -1
@@ -45,7 +45,8 @@ FILES= \ test-zlib.bin \ test-lzma.bin \ test-bpf.bin \ - test-get_cpuid.bin + test-get_cpuid.bin \ + test-sdt.bin FILES := $(addprefix $(OUTPUT),$(FILES))
@@ -213,6 +214,9 @@ $(OUTPUT)test-get_cpuid.bin: $(OUTPUT)test-bpf.bin: $(BUILD) +$(OUTPUT)test-sdt.bin: + $(BUILD) + -include $(OUTPUT)*.d ###############################
tools/build/feature/test-all.c +5 -0
@@ -145,6 +145,10 @@# include "test-libcrypto.c" #undef main +#define main main_test_sdt +# include "test-sdt.c" +#undef main +int main (int argc,char *argv[]) {main_test_libpython ();
@@ -178,6 +182,7 @@ int main(int argc, char *argv[])main_test_get_cpuid ();main_test_bpf ();main_test_libcrypto (); +main_test_sdt ();return 0 ; }
tools/build/feature/test-sdt.c new file +7 -0
@@ -0,0 +1,7 @@ +#include <sys/sdt.h> + +int main (void ) +{ +DTRACE_PROBE (provider, name); +return 0 ; +}
tools/perf/Makefile.perf +3 -0
@@ -81,6 +81,9 @@ include ../scripts/utilities.mak # # Define NO_LIBBPF if you do not want BPF support # +# Define NO_SDT if you do not want to define SDT event in perf tools, +# note that it doesn't disable SDT scanning support. +# # Define FEATURES_DUMP to provide features detection dump file # and bypass the feature detection
tools/perf/config/Makefile +10 -0
@@ -355,6 +355,16 @@ ifndef NO_LIBELF endif # NO_LIBBPF endif # NO_LIBELF +ifndef NO_SDT + ifneq ($(feature-sdt), 1) + msg := $(warning No sys/sdt.h found, no SDT events are defined, please install systemtap-sdt-devel or systemtap-sdt-dev); + NO_SDT := 1; + else + CFLAGS += -DHAVE_SDT_EVENT + $(call detected,CONFIG_SDT_EVENT) + endif +endif + ifdef PERF_HAVE_JITDUMP ifndef NO_DWARF $(call detected,CONFIG_JITDUMP)
tools/perf/tests/make +2 -1
@@ -82,6 +82,7 @@ make_no_auxtrace := NO_AUXTRACE=1 make_no_libbpf := NO_LIBBPF=1 make_no_libcrypto := NO_LIBCRYPTO=1 make_with_babeltrace:= LIBBABELTRACE=1 +make_no_sdt := NO_SDT=1 make_tags := tags make_cscope := cscope make_help := help
@@ -105,7 +106,7 @@ make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 make_minimal += NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 -make_minimal += NO_LIBCRYPTO=1 +make_minimal += NO_LIBCRYPTO=1 NO_SDT=1 # $(run) contains all available tests run := make_pure
PATCH 10/10 perf-test: Add a test case for SDT event
In reply to Masami HiramatsuAdd a basic test case for SDT event support.
This test scans an SDT event in perftools and
check whether the SDT event is correctly stored
into the buildid cache.
Here is an example:
----
$ perf test sdt -v 47: Test SDT event probing : --- start --- test child forked, pid 20732 Found 72 SDTs in /home/mhiramat/ksrc/linux/tools/perf/perf Writing cache: %sdt_perf:test_target=test_target Cache committed: 0 symbol:test_target file:(null) line:0 offset:0 return:0 lazy:(null) test child finished with 0 ---- end ---- Test SDT event probing: Ok ----
--- tools/perf/tests/Build | 1 tools/perf/tests/builtin-test.c | 4 + tools/perf/tests/sdt.c | 115 +++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 4 files changed, 121 insertions(+) create mode 100644 tools/perf/tests/sdt.c
tools/perf/tests/Build +1 -0
@@ -39,6 +39,7 @@ perf-y += stat.o perf-y += event_update.o perf-y += event-times.o perf-y += backward-ring-buffer.o +perf-y += sdt.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
@@ -218,6 +218,10 @@ static struct test generic_tests[] = { .func = test__cpu_map_print, }, { + .desc = "Test SDT event probing", + .func = test__sdt_event, + }, + { .func = NULL, }, };
tools/perf/tests/sdt.c new file +115 -0
115 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -88,6 +88,7 @@ int test__event_update(int subtest);int test__event_times (int subtest);int test__backward_ring_buffer (int subtest);int test__cpu_map_print (int subtest); +int test__sdt_event (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf test: Add a test case for SDT event
perf test: Add a test case for SDT event
Commit-ID: 8e5dc848356ecf6ea8d27d641c4d7ad8d42fe92b Gitweb: http://git.kernel.org/tip/8e5dc848356ecf6ea8d27d641c4d7ad8d42fe92b Author: Masami Hiramatsu <[email protected]> AuthorDate: Tue, 12 Jul 2016 19:06:05 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 13 Jul 2016 23:09:10 -0300
perf test: Add a test case for SDT event
Add a basic test case for SDT event support. This test scans an SDT event in perftools and check whether the SDT event is correctly stored into the buildid cache.
Here is an example:
----
$ perf test sdt -v 47: Test SDT event probing : --- start --- test child forked, pid 20732 Found 72 SDTs in /home/mhiramat/ksrc/linux/tools/perf/perf Writing cache: %sdt_perf:test_target=test_target Cache committed: 0 symbol:test_target file:(null) line:0 offset:0 return:0 lazy:(null) test child finished with 0 ---- end ---- Test SDT event probing: Ok ----
--- tools/perf/tests/Build | 1 + tools/perf/tests/builtin-test.c | 4 ++ tools/perf/tests/sdt.c | 115 ++++++++++++++++++++++++++++++++++++++++ tools/perf/tests/tests.h | 1 + 4 files changed, 121 insertions(+)
tools/perf/tests/Build +1 -0
@@ -39,6 +39,7 @@ perf-y += stat.o perf-y += event_update.o perf-y += event-times.o perf-y += backward-ring-buffer.o +perf-y += sdt.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
@@ -218,6 +218,10 @@ static struct test generic_tests[] = { .func = test__cpu_map_print, }, { + .desc = "Test SDT event probing", + .func = test__sdt_event, + }, + { .func = NULL, }, };
tools/perf/tests/sdt.c new file +115 -0
115 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -88,6 +88,7 @@ int test__event_update(int subtest);int test__event_times (int subtest);int test__backward_ring_buffer (int subtest);int test__cpu_map_print (int subtest); +int test__sdt_event (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
Arnaldo Carvalho de Melo
maintainerEm Tue, Jul 12, 2016 at 07:04:23PM +0900, Masami Hiramatsu escreveu:
Quoted 6 lines
Hi,
Here is the 14th version of the patchset for probe-cache and initial SDT support.
Here is the previous v13: https://lkml.org/lkml/2016/7/1/133
Ok, applied it and also one that you missed in this set, the one adding 'perf list sdt', that I rebased and tested,
Thanks,
- Arnaldo
Quoted 42 lines
This version includes patches which not merged yet. This also adds a bugfix;
- [1/10] Resend the bugfix patch which was sent 4th July.(https://lkml.org/lkml/2016/7/3/217)Thank you,
---
Masami Hiramatsu (10):
[BUGFIX] perf-probe: Fix to show correct error message for $vars and $params perf probe: Accept %sdt and %cached event name
perf-probe: Make --list shows only available cached events
perf: probe-cache: Addfor_each_probe_cache_entry()wrapper perf probe: Allow wildcard for cached events
perf probe: Search SDT/cached event from all probe caches
perf probe: Support @BUILDID or @FILE suffix for SDT events perf probe: Support a special SDT probe format
perf build: Add sdt feature detection
perf-test: Add a test case for SDT eventtools/perf/Documentation/perf-probe.txt | 11 + tools/perf/Makefile.perf | 3 tools/perf/builtin-probe.c | 2 tools/perf/config/Makefile | 10 + tools/perf/tests/Build | 1 tools/perf/tests/builtin-test.c | 4 tools/perf/tests/make | 3 tools/perf/tests/sdt.c | 115 ++++++++++++ tools/perf/tests/tests.h | 1 tools/perf/util/build-id.c | 76 ++++++++ tools/perf/util/build-id.h | 3 tools/perf/util/probe-event.c | 309 +++++++++++++++++++++++++++---- tools/perf/util/probe-event.h | 1 tools/perf/util/probe-file.c | 57 +++++- tools/perf/util/probe-file.h | 5 + 15 files changed, 542 insertions(+), 59 deletions(-) create mode 100644 tools/perf/tests/sdt.c--
Masami Hiramatsu