perf-probe --cache and SDT support
v2 cover perf-probe --cache and SDT support
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
The perf-probe is useful for debugging, but it strongly depends on the debuginfo. Without debuginfo, it is just a frontend of ftrace's dynamic events. This can usually happen in server farms or on cloud system, since no one wants to distribute big debuginfo packages.
To solve this issue, I had tried to make a pre-analyzed probes ( https://lkml.org/lkml/2014/10/31/207 ) but it has a problm that we can't ensure the probed binary is same as what we analyzed. Arnaldo gave me an idea to reuse build-id cache for that perpose and this series is the first prototype of that.
At the same time, Hemant has started to support SDT probes which also use the cache file of SDT info. So I decided to merge this into the same build-id cache.
In this version, SDT support is still very limited, it works as a part of probe-cache.
In this version, perf probe supports --cache option which means that perf probe manipulate probe caches, for example,
# perf probe --cache --add "probe-desc"
does not only add probe events but also add "probe-desc" and it's result on the cache. (Note that the cached entry is always referred even without --cache)
The --list and --del commands also support --cache. Note that both are only manipulate caches, not real events.
To use SDT, we have to scan the target binary at first by using perf-buildid-cache, e.g.
# perf buildid-cache --add /lib/libc-2.17.so
And perf probe --cache --list shows what SDTs are scanned.
# perf probe --cache --list /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new libc:memory_sbrk_less=memory_sbrk_less libc:memory_arena_reuse_free_list=memory_arena_reuse_free_list libc:memory_arena_reuse=memory_arena_reuse ...
To use the SDT events, perf probe -x BIN %SDTEVENT allows you to add a probe on SDTEVENT@BIN.
# perf probe -x /lib/libc-2.17.so %memory_heap_new
If you define a cached probe with event name, you can also reuse it as same as SDT events.
# perf probe -x ./perf --cache -n 'myevent=dso__load $params'
(Note that "-n" option only updates caches)
To use the above "myevent", you just have to add "%myevent".
# perf probe -x ./perf %myevent
TODOs:
- Show available cached/SDT events by perf-list
- Allow perf-record to use cached/SDT events directly
Thank you,
---
Hemant Kumar (1):
perf/sdt: ELF support for SDT
Masami Hiramatsu (15):
perf probe: Simplify __add_probe_trace_events code
perf probe: Move ftrace probe-event operations to probe-file.c perf probe: Use strbuf for making strings in probe-event.c
perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid perf buildid: Use SBUILD_ID_SIZE macro
perf buildid: Introduce sysfs/filename__sprintf_build_id
perf: Add lsdir to read a directory
perf-buildid-cache: Use lsdir for looking up buildid caches
perf probe: Add --cache option to cache the probe definitions perf probe: Use cache entry if possible
perf probe: Show all cached probes
perf probe: Remove caches when --cache is given
perf probe: Add group name support
perf buildid-cache: Scan and import user SDT events to probe cache perf probe: Accept %sdt and %cached event name
tools/perf/Documentation/perf-probe.txt | 14 tools/perf/builtin-buildid-cache.c | 22 - tools/perf/builtin-buildid-list.c | 28 - tools/perf/builtin-probe.c | 3 tools/perf/util/Build | 1 tools/perf/util/build-id.c | 230 ++++++-- tools/perf/util/build-id.h | 11 tools/perf/util/dso.h | 5 tools/perf/util/probe-event.c | 918 ++++++++++++++----------------- tools/perf/util/probe-event.h | 16 - tools/perf/util/probe-file.c | 763 ++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 46 ++ tools/perf/util/probe-finder.c | 10 tools/perf/util/symbol-elf.c | 252 +++++++++ tools/perf/util/symbol.c | 2 tools/perf/util/symbol.h | 22 + tools/perf/util/util.c | 34 + tools/perf/util/util.h | 4 18 files changed, 1781 insertions(+), 600 deletions(-) create mode 100644 tools/perf/util/probe-file.c create mode 100644 tools/perf/util/probe-file.h
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
RFC PATCH v2 1/16 perf probe: Simplify __add_probe_trace_events code
Simplify the __add_probe_trace_events() code by taking out the probe_trace_event__set_name() and updating show_perf_probe_event()
--- tools/perf/util/probe-event.c | 70 +++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 27 deletions(-)
tools/perf/util/probe-event.c +43 -27
@@ -2478,16 +2478,54 @@ out:free (buf); } +/* Set new name from original perf_probe_event and namelist */ +static int probe_trace_event__set_name (struct probe_trace_event *tev, +struct perf_probe_event *pev, +struct strlist *namelist, +bool allow_suffix) +{ +const char *event, *group; +char buf[64 ]; +int ret; + +if (pev->event) + event = pev->event; +else +if (pev->point.function && !strisglob (pev->point.function)) + event = pev->point.function; +else + event = tev->point.realname; +if (pev->group) + group = pev->group; +else + group =PERFPROBE_GROUP ; + +/* Get an unused new event name */ + ret =get_new_event_name (buf,64 , event, + namelist, allow_suffix); +if (ret <0 ) +return ret; + + event = buf; + + tev->event =strdup (event); + tev->group =strdup (group); +if (tev->event ==NULL || tev->group ==NULL ) +return -ENOMEM ; + +/* Add added event name to namelist */ +strlist__add (namelist, event); +return 0 ; +} +static int __add_probe_trace_events (struct perf_probe_event *pev,struct probe_trace_event *tevs,int ntevs,bool allow_suffix) {int i, fd, ret;struct probe_trace_event *tev =NULL ; -char buf[64 ];const char *event =NULL , *group =NULL ;struct strlist *namelist; -bool safename;if (pev->uprobes) fd =open_uprobe_events (true);
@@ -2507,7 +2545,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, goto close_out; } - safename = (pev->point.function && !strisglob (pev->point.function)); ret =0 ;pr_info ("Added new event%s\n" , (ntevs >1 ) ?"s:" :":" );for (i =0 ; i < ntevs; i++) {
@@ -2516,36 +2553,15 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,if (!tev->point.symbol)continue ; -if (pev->event) - event = pev->event; -else -if (safename) - event = pev->point.function; -else - event = tev->point.realname; -if (pev->group) - group = pev->group; -else - group =PERFPROBE_GROUP ; - -/* Get an unused new event name */ - ret =get_new_event_name (buf,64 , event, - namelist, allow_suffix); +/* Set new name for tev (and update namelist) */ + ret =probe_trace_event__set_name (tev, pev, namelist, + allow_suffix);if (ret <0 )break ; - event = buf; - tev->event =strdup (event); - tev->group =strdup (group); -if (tev->event ==NULL || tev->group ==NULL ) { - ret = -ENOMEM ; -break ; - } ret =write_probe_trace_event (fd, tev);if (ret <0 )break ; -/* Add added event name to namelist */ -strlist__add (namelist, event);/* We use tev's name for showing new events */ show_perf_probe_event(tev->group, tev->event, pev,
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Simplify __add_probe_trace_events code
perf probe: Simplify __add_probe_trace_events code
Commit-ID: a3c9de6280b8d196ab89ca7fad143bfa2a949790 Gitweb: http://git.kernel.org/tip/a3c9de6280b8d196ab89ca7fad143bfa2a949790 Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 15 Jul 2015 18:14:00 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 20 Jul 2015 17:49:49 -0300
perf probe: Simplify __add_probe_trace_events code
Simplify the __add_probe_trace_events() code by taking out the probe_trace_event__set_name() and updating show_perf_probe_event()
--- tools/perf/util/probe-event.c | 70 ++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 27 deletions(-)
tools/perf/util/probe-event.c +43 -27
@@ -2478,16 +2478,54 @@ out:free (buf); } +/* Set new name from original perf_probe_event and namelist */ +static int probe_trace_event__set_name (struct probe_trace_event *tev, +struct perf_probe_event *pev, +struct strlist *namelist, +bool allow_suffix) +{ +const char *event, *group; +char buf[64 ]; +int ret; + +if (pev->event) + event = pev->event; +else +if (pev->point.function && !strisglob (pev->point.function)) + event = pev->point.function; +else + event = tev->point.realname; +if (pev->group) + group = pev->group; +else + group =PERFPROBE_GROUP ; + +/* Get an unused new event name */ + ret =get_new_event_name (buf,64 , event, + namelist, allow_suffix); +if (ret <0 ) +return ret; + + event = buf; + + tev->event =strdup (event); + tev->group =strdup (group); +if (tev->event ==NULL || tev->group ==NULL ) +return -ENOMEM ; + +/* Add added event name to namelist */ +strlist__add (namelist, event); +return 0 ; +} +static int __add_probe_trace_events (struct perf_probe_event *pev,struct probe_trace_event *tevs,int ntevs,bool allow_suffix) {int i, fd, ret;struct probe_trace_event *tev =NULL ; -char buf[64 ];const char *event =NULL , *group =NULL ;struct strlist *namelist; -bool safename;if (pev->uprobes) fd =open_uprobe_events (true);
@@ -2507,7 +2545,6 @@ static int __add_probe_trace_events(struct perf_probe_event *pev, goto close_out; } - safename = (pev->point.function && !strisglob (pev->point.function)); ret =0 ;pr_info ("Added new event%s\n" , (ntevs >1 ) ?"s:" :":" );for (i =0 ; i < ntevs; i++) {
@@ -2516,36 +2553,15 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,if (!tev->point.symbol)continue ; -if (pev->event) - event = pev->event; -else -if (safename) - event = pev->point.function; -else - event = tev->point.realname; -if (pev->group) - group = pev->group; -else - group =PERFPROBE_GROUP ; - -/* Get an unused new event name */ - ret =get_new_event_name (buf,64 , event, - namelist, allow_suffix); +/* Set new name for tev (and update namelist) */ + ret =probe_trace_event__set_name (tev, pev, namelist, + allow_suffix);if (ret <0 )break ; - event = buf; - tev->event =strdup (event); - tev->group =strdup (group); -if (tev->event ==NULL || tev->group ==NULL ) { - ret = -ENOMEM ; -break ; - } ret =write_probe_trace_event (fd, tev);if (ret <0 )break ; -/* Add added event name to namelist */ -strlist__add (namelist, event);/* We use tev's name for showing new events */ show_perf_probe_event(tev->group, tev->event, pev,
RFC PATCH v2 2/16 perf probe: Move ftrace probe-event operations to probe-file.c
In reply to Masami HiramatsuMove ftrace probe-event operations to probe-file.c from probe-event.c.
--- tools/perf/util/Build | 1 tools/perf/util/probe-event.c | 318 +++-------------------------------------- tools/perf/util/probe-event.h | 7 + tools/perf/util/probe-file.c | 302 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 18 ++ 5 files changed, 354 insertions(+), 292 deletions(-) create mode 100644 tools/perf/util/probe-file.c create mode 100644 tools/perf/util/probe-file.h
tools/perf/util/Build +1 -0
@@ -79,6 +79,7 @@ libperf-$(CONFIG_AUXTRACE) += auxtrace.o libperf-y += parse-branch-options.o libperf-$(CONFIG_LIBELF) += symbol-elf.o +libperf-$(CONFIG_LIBELF) += probe-file.o libperf-$(CONFIG_LIBELF) += probe-event.o ifndef CONFIG_LIBELF
tools/perf/util/probe-event.c +26 -292
413 lines not on this page · raw message
tools/perf/util/probe-event.h +7 -0
@@ -109,6 +109,8 @@ struct variable_list {/* Command string to events */ extern int parse_perf_probe_command (const char *cmd,struct perf_probe_event *pev); +extern int parse_probe_trace_command (const char *cmd, +struct probe_trace_event *tev);/* Events to command string */ extern char *synthesize_perf_probe_command (struct perf_probe_event *pev);
@@ -121,6 +123,7 @@ extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);/* Release event contents */ extern void clear_perf_probe_event (struct perf_probe_event *pev); +extern void clear_probe_trace_event (struct probe_trace_event *tev);/* Command string to line-range */ extern int parse_line_range_desc (const char *cmd,struct line_range *lr);
@@ -144,6 +147,10 @@ bool arch__prefers_symtab(void);void arch__fix_tev_from_maps (struct perf_probe_event *pev,struct probe_trace_event *tev,struct map *map); +/* If there is no space to write, returns -E2BIG. */ +int e_snprintf (char *str,size_t size,const char *format, ...) + __attribute__((format (printf,3 ,4 ))); +/* Maximum index number of event-name postfix */ #define MAX_EVENT_INDEX 1024
tools/perf/util/probe-file.c new file +302 -0
302 lines not on this page · raw message
tools/perf/util/probe-file.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef __PROBE_FILE_H +#define __PROBE_FILE_H + +#include "strlist.h" +#include "strfilter.h" +#include "probe-event.h" + +#define PF_FL_UPROBE 1 +#define PF_FL_RW 2 + +int probe_file__open (int flag); +int probe_file__open_both (int *kfd,int *ufd,int flag); +struct strlist *probe_file__get_namelist (int fd); +struct strlist *probe_file__get_rawlist (int fd); +int probe_file__add_event (int fd,struct probe_trace_event *tev); +int probe_file__del_events (int fd,struct strfilter *filter); + +#endif
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf probe: Move ftrace probe-event operations to probe-file.c
perf probe: Move ftrace probe-event operations to probe-file.c
Commit-ID: 92f6c72e7ac40cbf8d12682d1aeeb82c905f2a64 Gitweb: http://git.kernel.org/tip/92f6c72e7ac40cbf8d12682d1aeeb82c905f2a64 Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 15 Jul 2015 18:14:07 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 20 Jul 2015 17:49:49 -0300
perf probe: Move ftrace probe-event operations to probe-file.c
Move ftrace probe-event operations to probe-file.c from probe-event.c.
--- tools/perf/util/Build | 1 + tools/perf/util/probe-event.c | 318 ++++-------------------------------------- tools/perf/util/probe-event.h | 7 + tools/perf/util/probe-file.c | 301 +++++++++++++++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 18 +++ 5 files changed, 353 insertions(+), 292 deletions(-)
tools/perf/util/Build +1 -0
@@ -79,6 +79,7 @@ libperf-$(CONFIG_AUXTRACE) += auxtrace.o libperf-y += parse-branch-options.o libperf-$(CONFIG_LIBELF) += symbol-elf.o +libperf-$(CONFIG_LIBELF) += probe-file.o libperf-$(CONFIG_LIBELF) += probe-event.o ifndef CONFIG_LIBELF
tools/perf/util/probe-event.c +26 -292
413 lines not on this page · raw message
tools/perf/util/probe-event.h +7 -0
@@ -109,6 +109,8 @@ struct variable_list {/* Command string to events */ extern int parse_perf_probe_command (const char *cmd,struct perf_probe_event *pev); +extern int parse_probe_trace_command (const char *cmd, +struct probe_trace_event *tev);/* Events to command string */ extern char *synthesize_perf_probe_command (struct perf_probe_event *pev);
@@ -121,6 +123,7 @@ extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev);/* Release event contents */ extern void clear_perf_probe_event (struct perf_probe_event *pev); +extern void clear_probe_trace_event (struct probe_trace_event *tev);/* Command string to line-range */ extern int parse_line_range_desc (const char *cmd,struct line_range *lr);
@@ -144,6 +147,10 @@ bool arch__prefers_symtab(void);void arch__fix_tev_from_maps (struct perf_probe_event *pev,struct probe_trace_event *tev,struct map *map); +/* If there is no space to write, returns -E2BIG. */ +int e_snprintf (char *str,size_t size,const char *format, ...) + __attribute__((format (printf,3 ,4 ))); +/* Maximum index number of event-name postfix */ #define MAX_EVENT_INDEX 1024
tools/perf/util/probe-file.c new file +301 -0
301 lines not on this page · raw message
tools/perf/util/probe-file.h new file +18 -0
@@ -0,0 +1,18 @@ +#ifndef __PROBE_FILE_H +#define __PROBE_FILE_H + +#include "strlist.h" +#include "strfilter.h" +#include "probe-event.h" + +#define PF_FL_UPROBE 1 +#define PF_FL_RW 2 + +int probe_file__open (int flag); +int probe_file__open_both (int *kfd,int *ufd,int flag); +struct strlist *probe_file__get_namelist (int fd); +struct strlist *probe_file__get_rawlist (int fd); +int probe_file__add_event (int fd,struct probe_trace_event *tev); +int probe_file__del_events (int fd,struct strfilter *filter); + +#endif
RFC PATCH v2 3/16 perf probe: Use strbuf for making strings in probe-event.c
In reply to Masami HiramatsuReplace many fixed-length char array with strbuf to stringify perf_probe_event and probe_trace_event etc. in util/probe-event.c.
---
Changes in v2:
- Make perf_probe_event__sprintf() simpler.
--- tools/perf/util/probe-event.c | 242 ++++++++++++++-------------------------- tools/perf/util/probe-event.h | 3 tools/perf/util/probe-finder.c | 10 +- 3 files changed, 92 insertions(+), 163 deletions(-)
tools/perf/util/probe-event.c +86 -156
@@ -1562,69 +1562,52 @@ out: }/* Compose only probe arg */ -int synthesize_perf_probe_arg (struct perf_probe_arg *pa,char *buf,size_t len) +char *synthesize_perf_probe_arg (struct perf_probe_arg *pa) {struct perf_probe_arg_field *field = pa->field; -int ret; -char *tmp = buf; +struct strbuf buf; +char *ret; +strbuf_init (&buf,64 );if (pa->name && pa->var) - ret =e_snprintf (tmp, len,"%s=%s" , pa->name, pa->var); +strbuf_addf (&buf,"%s=%s" , pa->name, pa->var);else - ret =e_snprintf (tmp, len,"%s" , pa->name ? pa->name : pa->var); -if (ret <=0 ) - goto error; - tmp += ret; - len -= ret; +strbuf_addstr (&buf, pa->name ?: pa->var);while (field) {if (field->name[0 ] =='[' ) - ret =e_snprintf (tmp, len,"%s" , field->name); +strbuf_addstr (&buf, field->name);else - ret =e_snprintf (tmp, len,"%s%s" , - field->ref ?"->" :"." , field->name); -if (ret <=0 ) - goto error; - tmp += ret; - len -= ret; +strbuf_addf (&buf,"%s%s" , field->ref ?"->" :"." , + field->name); field = field->next; } -if (pa->type) { - ret =e_snprintf (tmp, len,":%s" , pa->type); -if (ret <=0 ) - goto error; - tmp += ret; - len -= ret; - } +if (pa->type) +strbuf_addf (&buf,":%s" , pa->type); + + ret =strbuf_detach (&buf,NULL ); +strbuf_release (&buf); -return tmp - buf; -error: -pr_debug ("Failed to synthesize perf probe argument: %d\n" , ret);return ret; }/* Compose only probe point (not argument) */ static char *synthesize_perf_probe_point (struct perf_probe_point *pp) { -char *buf, *tmp; -char offs[32 ] ="" , line[32 ] ="" , file[32 ] ="" ; -int ret, len; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) { - ret = -ENOMEM ; - goto error; - } -if (pp->offset) { - ret =e_snprintf (offs,32 ,"+%lu" , pp->offset); -if (ret <=0 ) - goto error; - } -if (pp->line) { - ret =e_snprintf (line,32 ,":%d" , pp->line); -if (ret <=0 ) - goto error; +struct strbuf buf; +char *tmp; +int len; + +strbuf_init (&buf,64 ); +if (pp->function) { +strbuf_addstr (&buf, pp->function); +if (pp->offset) +strbuf_addf (&buf,"+%lu" , pp->offset); +else if (pp->line) +strbuf_addf (&buf,":%d" , pp->line); +else if (pp->retprobe) +strbuf_addstr (&buf,"%return" ); }if (pp->file) { tmp = pp->file;
@@ -1633,25 +1616,14 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) tmp =strchr (pp->file + len -30 ,'/' ); tmp = tmp ? tmp +1 : pp->file + len -30 ; } - ret =e_snprintf (file,32 ,"@%s" , tmp); -if (ret <=0 ) - goto error; +strbuf_addf (&buf,"@%s" , tmp); +if (!pp->function && pp->line) +strbuf_addf (&buf,":%d" , pp->line); } -if (pp->function) - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s%s%s%s" , pp->function, - offs, pp->retprobe ?"%return" :"" , line, - file); -else - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s" , file, line); -if (ret <=0 ) - goto error; - -return buf; -error: -pr_debug ("Failed to synthesize perf probe point: %d\n" , ret); -free (buf); -return NULL ; + tmp =strbuf_detach (&buf,NULL ); +strbuf_release (&buf); +return tmp; }#if 0
@@ -1680,45 +1652,30 @@ char *synthesize_perf_probe_command(struct perf_probe_event *pev)#endif static int __synthesize_probe_trace_arg_ref (struct probe_trace_arg_ref *ref, -char **buf,size_t *buflen, -int depth) +struct strbuf *buf,int depth) { -int ret;if (ref->next) { depth =__synthesize_probe_trace_arg_ref (ref->next, buf, - buflen, depth +1 ); + depth +1 );if (depth <0 ) goto out; } - - ret =e_snprintf (*buf, *buflen,"%+ld(" , ref->offset); -if (ret <0 ) - depth = ret; -else { - *buf += ret; - *buflen -= ret; - } +strbuf_addf (buf,"%+ld(" , ref->offset); out:return depth; - }static int synthesize_probe_trace_arg (struct probe_trace_arg *arg, -char *buf,size_t buflen) +struct strbuf *buf) {struct probe_trace_arg_ref *ref = arg->ref; -int ret, depth =0 ; -char *tmp = buf; +int depth =0 ;/* Argument name or separator */ if (arg->name) - ret =e_snprintf (buf, buflen," %s=" , arg->name); +strbuf_addf (buf," %s=" , arg->name);else - ret =e_snprintf (buf, buflen," " ); -if (ret <0 ) -return ret; - buf += ret; - buflen -= ret; +strbuf_addch (buf,' ' );/* Special case: @XXX */ if (arg->value[0 ] =='@' && arg->ref)
@@ -1726,86 +1683,58 @@ static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,/* Dereferencing arguments */ if (ref) { - depth =__synthesize_probe_trace_arg_ref (ref, &buf, - &buflen,1 ); + depth =__synthesize_probe_trace_arg_ref (ref, buf,1 );if (depth <0 )return depth; }/* Print argument value */ if (arg->value[0 ] =='@' && arg->ref) - ret =e_snprintf (buf, buflen,"%s%+ld" , arg->value, - arg->ref->offset); +strbuf_addf (buf,"%s%+ld" , arg->value, arg->ref->offset);else - ret =e_snprintf (buf, buflen,"%s" , arg->value); -if (ret <0 ) -return ret; - buf += ret; - buflen -= ret; +strbuf_addstr (buf, arg->value);/* Closing */ -while (depth--) { - ret =e_snprintf (buf, buflen,")" ); -if (ret <0 ) -return ret; - buf += ret; - buflen -= ret; - } +while (depth--) +strbuf_addch (buf,')' );/* Print argument type */ -if (arg->type) { - ret =e_snprintf (buf, buflen,":%s" , arg->type); -if (ret <=0 ) -return ret; - buf += ret; - } +if (arg->type) +strbuf_addf (buf,":%s" , arg->type); -return buf - tmp; +return 0 ; }char *synthesize_probe_trace_command (struct probe_trace_event *tev) {struct probe_trace_point *tp = &tev->point; -char *buf; -int i, len, ret; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) -return NULL ; - - len =e_snprintf (buf,MAX_CMDLEN ,"%c:%s/%s " , tp->retprobe ?'r' :'p' , - tev->group, tev->event); -if (len <=0 ) - goto error; +struct strbuf buf; +char *ret =NULL ; +int i;/* Uprobes must have tp->address and tp->module */ if (tev->uprobes && (!tp->address || !tp->module)) - goto error; +return NULL ; + +strbuf_init (&buf,32 ); +strbuf_addf (&buf,"%c:%s/%s " , tp->retprobe ?'r' :'p' , + tev->group, tev->event);/* Use the tp->address for uprobes */ if (tev->uprobes) - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s:0x%lx" , - tp->module, tp->address); +strbuf_addf (&buf,"%s:0x%lx" , tp->module, tp->address);else - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s%s%s+%lu" , - tp->module ?:"" , tp->module ?":" :"" , - tp->symbol, tp->offset); - -if (ret <=0 ) - goto error; - len += ret; +strbuf_addf (&buf,"%s%s%s+%lu" , tp->module ?:"" , + tp->module ?":" :"" , tp->symbol, tp->offset);for (i =0 ; i < tev->nargs; i++) { - ret =synthesize_probe_trace_arg (&tev->args[i], buf + len, -MAX_CMDLEN - len); -if (ret <=0 ) +if (synthesize_probe_trace_arg (&tev->args[i], &buf) <0 ) goto error; - len += ret; } -return buf; + ret =strbuf_detach (&buf,NULL ); error: -free (buf); -return NULL ; +strbuf_release (&buf); +return ret; } static int find_perf_probe_point_from_map(struct probe_trace_point *tp,
@@ -1883,7 +1812,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,static int convert_to_perf_probe_event (struct probe_trace_event *tev,struct perf_probe_event *pev,bool is_kprobe) { -char buf[64 ] ="" ; +struct strbuf buf =STRBUF_INIT ;int i, ret;/* Convert event/group name */
@@ -1906,9 +1835,10 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,if (tev->args[i].name) pev->args[i].name =strdup (tev->args[i].name);else { - ret =synthesize_probe_trace_arg (&tev->args[i], - buf,64 ); - pev->args[i].name =strdup (buf); +strbuf_init (&buf,32 ); + ret =synthesize_probe_trace_arg (&tev->args[i], &buf); + pev->args[i].name =strbuf_detach (&buf,NULL ); +strbuf_release (&buf); }if (pev->args[i].name ==NULL && ret >=0 ) ret = -ENOMEM ;
@@ -2086,37 +2016,37 @@ static int perf_probe_event__sprintf(const char *group, const char *event,const char *module, struct strbuf *result) { - int i, ret; -char buf[128 ]; -char *place; + int i; +char *buf; -/* Synthesize only event probe point */ - place =synthesize_perf_probe_point (&pev->point); -if (!place) -return -EINVAL ; +if (asprintf (&buf,"%s:%s" , group, event) <0 ) +return -errno; +strbuf_addf (result," %-20s (on " , buf); +free (buf); - ret =e_snprintf (buf,128 ,"%s:%s" , group, event); -if (ret <0 ) - goto out; +/* Synthesize only event probe point */ + buf =synthesize_perf_probe_point (&pev->point); +if (!buf) +return -ENOMEM ; +strbuf_addstr (result, buf); +free (buf); -strbuf_addf (result," %-20s (on %s" , buf, place);if (module)strbuf_addf (result," in %s" , module);if (pev->nargs >0 ) {strbuf_addstr (result," with" );for (i =0 ; i < pev->nargs; i++) { - ret =synthesize_perf_probe_arg (&pev->args[i], - buf,128 ); -if (ret <0 ) - goto out; + buf =synthesize_perf_probe_arg (&pev->args[i]); +if (!buf) +return -ENOMEM ;strbuf_addf (result," %s" , buf); +free (buf); } }strbuf_addch (result,')' ); -out: -free (place); -return ret; + +return 0 ; }/* Show an event */
tools/perf/util/probe-event.h +1 -2
@@ -115,8 +115,7 @@ extern int parse_probe_trace_command(const char *cmd,/* Events to command string */ extern char *synthesize_perf_probe_command (struct perf_probe_event *pev);extern char *synthesize_probe_trace_command (struct probe_trace_event *tev); -extern int synthesize_perf_probe_arg (struct perf_probe_arg *pa,char *buf, -size_t len); +extern char *synthesize_perf_probe_arg (struct perf_probe_arg *pa);/* Check the perf_probe_event needs debuginfo */ extern bool perf_probe_event_need_dwarf (struct perf_probe_event *pev);
tools/perf/util/probe-finder.c +5 -5
@@ -550,7 +550,7 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)static int find_variable (Dwarf_Die *sc_die,struct probe_finder *pf) {Dwarf_Die vr_die; -char buf[32 ], *ptr; +char *buf, *ptr;int ret =0 ;if (!is_c_varname (pf->pvar->var)) {
@@ -575,13 +575,13 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)if (pf->pvar->name) pf->tvar->name =strdup (pf->pvar->name);else { - ret =synthesize_perf_probe_arg (pf->pvar, buf,32 ); -if (ret <0 ) -return ret; + buf =synthesize_perf_probe_arg (pf->pvar); +if (!buf) +return -ENOMEM ; ptr =strchr (buf,':' );/* Change type separator to _ */ if (ptr) *ptr ='_' ; - pf->tvar->name =strdup (buf); + pf->tvar->name = buf; }if (pf->tvar->name ==NULL )return -ENOMEM ;
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 03/16] perf probe: Use strbuf for making strings in probe-event.c
Hi Masami,
Quoted 6 lines · Masami Hiramatsu
Replace many fixed-length char array with strbuf to stringify
perf_probe_eventandprobe_trace_eventetc. inutil/probe-event.c.Signed-off-by Masami Hiramatsu <[email protected]>---
[SNIP]
Review
Quoted 2 lines
(quoted diff) +2
-0+ ret = strbuf_detach(&buf, NULL); + strbuf_release(&buf);
It seems that strbuf_release() is meaningless after strbuf_detach().
Quoted 62 lines
tools/perf/util/probe-event.c +16
-30-return tmp - buf; -error: -pr_debug ("Failed to synthesize perf probe argument: %d\n" , ret);return ret; }/* Compose only probe point (not argument) */ static char *synthesize_perf_probe_point (struct perf_probe_point *pp) { -char *buf, *tmp; -char offs[32 ] ="" , line[32 ] ="" , file[32 ] ="" ; -int ret, len; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) { - ret = -ENOMEM ; - goto error; - } -if (pp->offset) { - ret =e_snprintf (offs,32 ,"+%lu" , pp->offset); -if (ret <=0 ) - goto error; - } -if (pp->line) { - ret =e_snprintf (line,32 ,":%d" , pp->line); -if (ret <=0 ) - goto error; +struct strbuf buf; +char *tmp; +int len; + +strbuf_init (&buf,64 ); +if (pp->function) { +strbuf_addstr (&buf, pp->function); +if (pp->offset) +strbuf_addf (&buf,"+%lu" , pp->offset); +else if (pp->line) +strbuf_addf (&buf,":%d" , pp->line); +else if (pp->retprobe) +strbuf_addstr (&buf,"%return" ); }if (pp->file) { tmp = pp->file;@@ -1633,25 +1616,14 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) tmp =strchr (pp->file + len -30 ,'/' ); tmp = tmp ? tmp +1 : pp->file + len -30 ; } - ret =e_snprintf (file,32 ,"@%s" , tmp); -if (ret <=0 ) - goto error; +strbuf_addf (&buf,"@%s" , tmp); +if (!pp->function && pp->line) +strbuf_addf (&buf,":%d" , pp->line); } -if (pp->function) - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s%s%s%s" , pp->function, - offs, pp->retprobe ?"%return" :"" , line, - file); -else - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s" , file, line);
tools/perf/util/probe-event.c static char *synthesize_perf_probe_point(struct perf_probe_point *pp) · line 1625
Quoted 10 lines
tools/perf/util/probe-event.c +2
-8-if (ret <=0 ) - goto error; - -return buf; -error: -pr_debug ("Failed to synthesize perf probe point: %d\n" , ret); -free (buf); -return NULL ; + tmp =strbuf_detach (&buf,NULL ); +strbuf_release (&buf);
Ditto.
Quoted 2 lines
tools/perf/util/probe-event.c +1
-0+return tmp; }
[SNIP]
Quoted 48 lines
char *synthesize_probe_trace_command(struct
probe_trace_event*tev) {tools/perf/util/probe-event.c +12
-24struct probe_trace_point *tp = &tev->point; -char *buf; -int i, len, ret; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) -return NULL ; - - len =e_snprintf (buf,MAX_CMDLEN ,"%c:%s/%s " , tp->retprobe ?'r' :'p' , - tev->group, tev->event); -if (len <=0 ) - goto error; +struct strbuf buf; +char *ret =NULL ; +int i;/* Uprobes must have tp->address and tp->module */ if (tev->uprobes && (!tp->address || !tp->module)) - goto error; +return NULL ; + +strbuf_init (&buf,32 ); +strbuf_addf (&buf,"%c:%s/%s " , tp->retprobe ?'r' :'p' , + tev->group, tev->event);/* Use the tp->address for uprobes */ if (tev->uprobes) - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s:0x%lx" , - tp->module, tp->address); +strbuf_addf (&buf,"%s:0x%lx" , tp->module, tp->address);else - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s%s%s+%lu" , - tp->module ?:"" , tp->module ?":" :"" , - tp->symbol, tp->offset); - -if (ret <=0 ) - goto error; - len += ret; +strbuf_addf (&buf,"%s%s%s+%lu" , tp->module ?:"" , + tp->module ?":" :"" , tp->symbol, tp->offset);for (i =0 ; i < tev->nargs; i++) { - ret =synthesize_probe_trace_arg (&tev->args[i], buf + len, -MAX_CMDLEN - len); -if (ret <=0 ) +if (synthesize_probe_trace_arg (&tev->args[i], &buf) <0 )
tools/perf/util/probe-event.c static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, · line 1736
Quoted 10 lines
tools/perf/util/probe-event.c +2
-4goto error; - len += ret; } -return buf; + ret =strbuf_detach (&buf,NULL ); error: -free (buf); -return NULL ; +strbuf_release (&buf);
This is necessary for the error path.
Quoted 14 lines
tools/perf/util/probe-event.c +2
-1+return ret; } static int find_perf_probe_point_from_map(struct probe_trace_point *tp,@@ -1883,7 +1812,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,static int convert_to_perf_probe_event (struct probe_trace_event *tev,struct perf_probe_event *pev,bool is_kprobe) { -char buf[64 ] ="" ; +struct strbuf buf =STRBUF_INIT ;int i, ret;/* Convert event/group name */
tools/perf/util/probe-event.c static int convert_to_perf_probe_event(struct probe_trace_event *tev, · line 1841
Quoted 10 lines
tools/perf/util/probe-event.c +4
-3@@ -1906,9 +1835,10 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,if (tev->args[i].name) pev->args[i].name =strdup (tev->args[i].name);else { - ret =synthesize_probe_trace_arg (&tev->args[i], - buf,64 ); - pev->args[i].name =strdup (buf); +strbuf_init (&buf,32 ); + ret =synthesize_probe_trace_arg (&tev->args[i], &buf); + pev->args[i].name =strbuf_detach (&buf,NULL ); +strbuf_release (&buf);
Ditto.
Thanks,
Namhyung
Quoted 3 lines
tools/perf/util/probe-event.c +0
-0}if (pev->args[i].name ==NULL && ret >=0 ) ret = -ENOMEM ;
Re: Re: [RFC PATCH perf/core v2 03/16] perf probe: Use strbuf for making strings in probe-event.c
Quoted 10 lines · Namhyung Kim
Hi Masami,
Quoted 6 lines · Masami Hiramatsu
Replace many fixed-length char array with strbuf to stringify
perf_probe_eventandprobe_trace_eventetc. inutil/probe-event.c.Signed-off-by Masami Hiramatsu <[email protected]>---
Quoted 6 lines
[SNIP]
Review
Quoted 2 lines
(quoted diff) +2
-0+ ret = strbuf_detach(&buf, NULL); + strbuf_release(&buf);It seems that
strbuf_release()is meaningless afterstrbuf_detach().
Ah, right! I'll remove those redundant strbuf_release.
Thanks!
Quoted 184 lines
Quoted 64 lines
tools/perf/util/probe-event.c +16
-30-return tmp - buf; -error: -pr_debug ("Failed to synthesize perf probe argument: %d\n" , ret);return ret; }/* Compose only probe point (not argument) */ static char *synthesize_perf_probe_point (struct perf_probe_point *pp) { -char *buf, *tmp; -char offs[32 ] ="" , line[32 ] ="" , file[32 ] ="" ; -int ret, len; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) { - ret = -ENOMEM ; - goto error; - } -if (pp->offset) { - ret =e_snprintf (offs,32 ,"+%lu" , pp->offset); -if (ret <=0 ) - goto error; - } -if (pp->line) { - ret =e_snprintf (line,32 ,":%d" , pp->line); -if (ret <=0 ) - goto error; +struct strbuf buf; +char *tmp; +int len; + +strbuf_init (&buf,64 ); +if (pp->function) { +strbuf_addstr (&buf, pp->function); +if (pp->offset) +strbuf_addf (&buf,"+%lu" , pp->offset); +else if (pp->line) +strbuf_addf (&buf,":%d" , pp->line); +else if (pp->retprobe) +strbuf_addstr (&buf,"%return" ); }if (pp->file) { tmp = pp->file;@@ -1633,25 +1616,14 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp) tmp =strchr (pp->file + len -30 ,'/' ); tmp = tmp ? tmp +1 : pp->file + len -30 ; } - ret =e_snprintf (file,32 ,"@%s" , tmp); -if (ret <=0 ) - goto error; +strbuf_addf (&buf,"@%s" , tmp); +if (!pp->function && pp->line) +strbuf_addf (&buf,":%d" , pp->line); } -if (pp->function) - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s%s%s%s" , pp->function, - offs, pp->retprobe ?"%return" :"" , line, - file); -else - ret =e_snprintf (buf,MAX_CMDLEN ,"%s%s" , file, line);tools/perf/util/probe-event.c static char *synthesize_perf_probe_point(struct perf_probe_point *pp) · line 1625
Quoted 10 lines
tools/perf/util/probe-event.c +2
-8-if (ret <=0 ) - goto error; - -return buf; -error: -pr_debug ("Failed to synthesize perf probe point: %d\n" , ret); -free (buf); -return NULL ; + tmp =strbuf_detach (&buf,NULL ); +strbuf_release (&buf);Ditto.
Quoted 2 lines
tools/perf/util/probe-event.c +1
-0+return tmp; }[SNIP]
Quoted 48 lines
char *synthesize_probe_trace_command(struct
probe_trace_event*tev) {tools/perf/util/probe-event.c +12
-24struct probe_trace_point *tp = &tev->point; -char *buf; -int i, len, ret; - - buf =zalloc (MAX_CMDLEN ); -if (buf ==NULL ) -return NULL ; - - len =e_snprintf (buf,MAX_CMDLEN ,"%c:%s/%s " , tp->retprobe ?'r' :'p' , - tev->group, tev->event); -if (len <=0 ) - goto error; +struct strbuf buf; +char *ret =NULL ; +int i;/* Uprobes must have tp->address and tp->module */ if (tev->uprobes && (!tp->address || !tp->module)) - goto error; +return NULL ; + +strbuf_init (&buf,32 ); +strbuf_addf (&buf,"%c:%s/%s " , tp->retprobe ?'r' :'p' , + tev->group, tev->event);/* Use the tp->address for uprobes */ if (tev->uprobes) - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s:0x%lx" , - tp->module, tp->address); +strbuf_addf (&buf,"%s:0x%lx" , tp->module, tp->address);else - ret =e_snprintf (buf + len,MAX_CMDLEN - len,"%s%s%s+%lu" , - tp->module ?:"" , tp->module ?":" :"" , - tp->symbol, tp->offset); - -if (ret <=0 ) - goto error; - len += ret; +strbuf_addf (&buf,"%s%s%s+%lu" , tp->module ?:"" , + tp->module ?":" :"" , tp->symbol, tp->offset);for (i =0 ; i < tev->nargs; i++) { - ret =synthesize_probe_trace_arg (&tev->args[i], buf + len, -MAX_CMDLEN - len); -if (ret <=0 ) +if (synthesize_probe_trace_arg (&tev->args[i], &buf) <0 )tools/perf/util/probe-event.c static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, · line 1736
Quoted 10 lines
tools/perf/util/probe-event.c +2
-4goto error; - len += ret; } -return buf; + ret =strbuf_detach (&buf,NULL ); error: -free (buf); -return NULL ; +strbuf_release (&buf);This is necessary for the error path.
Quoted 14 lines
tools/perf/util/probe-event.c +2
-1+return ret; } static int find_perf_probe_point_from_map(struct probe_trace_point *tp,@@ -1883,7 +1812,7 @@ static int convert_to_perf_probe_point(struct probe_trace_point *tp,static int convert_to_perf_probe_event (struct probe_trace_event *tev,struct perf_probe_event *pev,bool is_kprobe) { -char buf[64 ] ="" ; +struct strbuf buf =STRBUF_INIT ;int i, ret;/* Convert event/group name */ tools/perf/util/probe-event.c static int convert_to_perf_probe_event(struct probe_trace_event *tev, · line 1841
Quoted 10 lines
tools/perf/util/probe-event.c +4
-3@@ -1906,9 +1835,10 @@ static int convert_to_perf_probe_event(struct probe_trace_event *tev,if (tev->args[i].name) pev->args[i].name =strdup (tev->args[i].name);else { - ret =synthesize_probe_trace_arg (&tev->args[i], - buf,64 ); - pev->args[i].name =strdup (buf); +strbuf_init (&buf,32 ); + ret =synthesize_probe_trace_arg (&tev->args[i], &buf); + pev->args[i].name =strbuf_detach (&buf,NULL ); +strbuf_release (&buf);Ditto.
Thanks,
Namhyungtools/perf/util/probe-event.c static int convert_to_perf_probe_event(struct probe_trace_event *tev, · line 1844
Quoted 3 lines
tools/perf/util/probe-event.c +0
-0}if (pev->args[i].name ==NULL && ret >=0 ) ret = -ENOMEM ;--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
RFC PATCH v2 4/16 perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid
In reply to Masami HiramatsuUse path/to/bin/buildid/elf instead of path/to/bin/buildid to store corresponding elf binary.
This also stores vdso in buildid/vdso, kallsyms in buildid/kallsyms. Note that the build-id based symlink changes to point to the path/to/bin/buildid, not path/to/bin/buildid/elf.
--- tools/perf/util/build-id.c | 61 ++++++++++++++++++++++++++++++++------------ tools/perf/util/dso.h | 5 ++++ tools/perf/util/symbol.c | 2 + 3 files changed, 50 insertions(+), 18 deletions(-)
tools/perf/util/build-id.c +44 -17
@@ -112,7 +112,8 @@ static int asnprintf(char **strp, size_t size, const char *fmt, ...)return ret; } -static char *build_id__filename (const char *sbuild_id,char *bf,size_t size) +static char *build_id_cache__linkname (const char *sbuild_id,char *bf, +size_t size) {char *tmp = bf; int ret = asnprintf(&bf, size, "%s/.build-id/%.2s/%s", buildid_dir,
@@ -122,15 +123,35 @@ static char *build_id__filename(const char *sbuild_id, char *bf, size_t size)return bf; } +static const char *build_id_cache__basename (bool is_kallsyms,bool is_vdso) +{ +return is_kallsyms ?"kallsyms" : (is_vdso ?"vdso" :"elf" ); +} +char *dso__build_id_filename (const struct dso *dso,char *bf,size_t size) { +bool is_kallsyms =dso__is_kallsyms ((struct dso *)dso); +bool is_vdso =dso__is_vdso ((struct dso *)dso);char build_id_hex[BUILD_ID_SIZE *2 +1 ]; +char *linkname; +bool alloc = (bf ==NULL ); +int ret;if (!dso->has_build_id)return NULL ;build_id__sprintf (dso->build_id,sizeof (dso->build_id), build_id_hex); -return build_id__filename (build_id_hex, bf, size); + linkname =build_id_cache__linkname (build_id_hex,NULL ,0 ); +if (!linkname) +return NULL ; + + ret =asnprintf (&bf, size,"%s/%s" , linkname, +build_id_cache__basename (is_kallsyms, is_vdso)); +if (ret <0 || (!alloc && size < (unsigned int )ret)) + bf =NULL ; +free (linkname); + +return bf; }#define dsos__for_each_with_build_id (pos, head) \
@@ -261,7 +282,8 @@ void disable_buildid_cache(void) }static char *build_id_cache__dirname_from_path (const char *name, -bool is_kallsyms,bool is_vdso) +bool is_kallsyms,bool is_vdso, +const char *sbuild_id) {char *realname = (char *)name, *filename;bool slash = is_kallsyms || is_vdso;
@@ -272,8 +294,9 @@ static char *build_id_cache__dirname_from_path(const char *name,return NULL ; } -if (asprintf (&filename,"%s%s%s" , buildid_dir, slash ?"/" :"" , - is_vdso ?DSO__NAME_VDSO : realname) <0 ) +if (asprintf (&filename,"%s%s%s%s%s" , buildid_dir, slash ?"/" :"" , + is_vdso ?DSO__NAME_VDSO : realname, + sbuild_id ?"/" :"" , sbuild_id ?:"" ) <0 ) filename =NULL ;if (!slash)
@@ -292,7 +315,8 @@ int build_id_cache__list_build_ids(const char *pathname,int ret =0 ; list =strlist__new (true,NULL ); - dir_name =build_id_cache__dirname_from_path (pathname, false, false); + dir_name =build_id_cache__dirname_from_path (pathname, false, false, +NULL );if (!list || !dir_name) { ret = -ENOMEM ; goto out;
@@ -327,7 +351,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, {const size_t size =PATH_MAX ;char *realname =NULL , *filename =NULL , *dir_name =NULL , - *linkname =zalloc (size), *targetname, *tmp; + *linkname =zalloc (size), *tmp;int err =-1 ;if (!is_kallsyms) {
@@ -336,14 +360,17 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } - dir_name =build_id_cache__dirname_from_path (name, is_kallsyms, is_vdso); + dir_name =build_id_cache__dirname_from_path (name, is_kallsyms, + is_vdso, sbuild_id);if (!dir_name) goto out_free;if (mkdir_p (dir_name,0755 )) goto out_free; -if (asprintf (&filename,"%s/%s" , dir_name, sbuild_id) <0 ) { +/* Save the allocated buildid dirname */ +if (asprintf (&filename,"%s/%s" , dir_name, +build_id_cache__basename (is_kallsyms, is_vdso)) <0 ) { filename =NULL ; goto out_free; }
@@ -357,7 +384,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } -if (!build_id__filename (sbuild_id, linkname, size)) +if (!build_id_cache__linkname (sbuild_id, linkname, size)) goto out_free; tmp =strrchr (linkname,'/' ); *tmp ='\0' ;
@@ -366,10 +393,10 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; *tmp ='/' ; - targetname = filename +strlen (buildid_dir) -5 ; -memcpy (targetname,"../.." ,5 ); + tmp = dir_name +strlen (buildid_dir) -5 ; +memcpy (tmp,"../.." ,5 ); -if (symlink (targetname, linkname) ==0 ) +if (symlink (tmp, linkname) ==0 ) err =0 ; out_free:if (!is_kallsyms)
@@ -394,7 +421,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,bool build_id_cache__cached (const char *sbuild_id) {bool ret = false; -char *filename =build_id__filename (sbuild_id,NULL ,0 ); +char *filename =build_id_cache__linkname (sbuild_id,NULL ,0 );if (filename && !access (filename,F_OK )) ret = true;
@@ -413,7 +440,7 @@ int build_id_cache__remove_s(const char *sbuild_id)if (filename ==NULL || linkname ==NULL ) goto out_free; -if (!build_id__filename (sbuild_id, linkname, size)) +if (!build_id_cache__linkname (sbuild_id, linkname, size)) goto out_free;if (access (linkname,F_OK ))
@@ -431,7 +458,7 @@ int build_id_cache__remove_s(const char *sbuild_id) tmp =strrchr (linkname,'/' ) +1 ;snprintf (tmp, size - (tmp - linkname),"%s" , filename); -if (unlink (linkname)) +if (rm_rf (linkname)) goto out_free; err =0 ;
@@ -443,7 +470,7 @@ out_free:static int dso__cache_build_id (struct dso *dso,struct machine *machine) { -bool is_kallsyms = dso->kernel && dso->long_name[0 ] !='/' ; +bool is_kallsyms =dso__is_kallsyms (dso);bool is_vdso =dso__is_vdso (dso);const char *name = dso->long_name;char nm[PATH_MAX ];
tools/perf/util/dso.h +5 -0
@@ -341,6 +341,11 @@ static inline bool dso__is_kcore(struct dso *dso) dso->binary_type ==DSO_BINARY_TYPE__GUEST_KCORE ; } +static inline bool dso__is_kallsyms (struct dso *dso) +{ +return dso->kernel && dso->long_name[0 ] !='/' ; +} +void dso__free_a2l (struct dso *dso);enum dso_type dso__type (struct dso *dso,struct machine *machine);
tools/perf/util/symbol.c +1 -1
@@ -1702,7 +1702,7 @@ static char *dso__find_kallsyms(struct dso *dso, struct map *map)if (!find_matching_kcore (map, path,sizeof (path)))return strdup (path); -scnprintf (path,sizeof (path),"%s/[kernel.kallsyms]/%s" , +scnprintf (path,sizeof (path),"%s/[kernel.kallsyms]/%s/kallsyms" , buildid_dir, sbuild_id);if (access (path,F_OK )) {
RFC PATCH v2 5/16 perf buildid: Use SBUILD_ID_SIZE macro
In reply to Masami HiramatsuIntroduce SBUILD_ID_SIZE macro and use it instead of using BUILD_ID_SIZE * 2 + 1.
--- tools/perf/builtin-buildid-cache.c | 8 ++++---- tools/perf/builtin-buildid-list.c | 4 ++-- tools/perf/util/build-id.c | 4 ++-- tools/perf/util/build-id.h | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-)
tools/perf/builtin-buildid-cache.c +4 -4
@@ -127,7 +127,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,static int build_id_cache__add_kcore (const char *filename,bool force) { -char dir[32 ], sbuildid[BUILD_ID_SIZE *2 +1 ]; +char dir[32 ], sbuildid[SBUILD_ID_SIZE ];char from_dir[PATH_MAX ], to_dir[PATH_MAX ];char *p;
@@ -184,7 +184,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force)static int build_id_cache__add_file (const char *filename) { -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];u8 build_id[BUILD_ID_SIZE ];int err;
@@ -204,7 +204,7 @@ static int build_id_cache__add_file(const char *filename)static int build_id_cache__remove_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];int err;
@@ -276,7 +276,7 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *fstatic int build_id_cache__update_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];int err =0 ;
tools/perf/builtin-buildid-list.c +2 -2
@@ -20,7 +20,7 @@static int sysfs__fprintf_build_id (FILE *fp) {u8 kallsyms_build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];if (sysfs__read_build_id ("/sys/kernel/notes" , kallsyms_build_id,sizeof (kallsyms_build_id)) !=0 )
@@ -35,7 +35,7 @@ static int sysfs__fprintf_build_id(FILE *fp)static int filename__fprintf_build_id (const char *name,FILE *fp) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];if (filename__read_build_id (name, build_id,sizeof (build_id)) !=sizeof (build_id))
tools/perf/util/build-id.c +2 -2
@@ -132,7 +132,7 @@ char *dso__build_id_filename(const struct dso *dso, char *bf, size_t size) {bool is_kallsyms =dso__is_kallsyms ((struct dso *)dso);bool is_vdso =dso__is_vdso ((struct dso *)dso); -char build_id_hex[BUILD_ID_SIZE *2 +1 ]; +char build_id_hex[SBUILD_ID_SIZE ];char *linkname;bool alloc = (bf ==NULL );int ret;
@@ -411,7 +411,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, const char *name, bool is_kallsyms, bool is_vdso) { - char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + char sbuild_id[SBUILD_ID_SIZE];build_id__sprintf (build_id, build_id_size, sbuild_id);
tools/perf/util/build-id.h +2 -1
@@ -1,7 +1,8 @@#ifndef PERF_BUILD_ID_H_ #define PERF_BUILD_ID_H_ 1 -#define BUILD_ID_SIZE 20 +#define BUILD_ID_SIZE 20 +#define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1)#include "tool.h" #include "strlist.h"
Re: [RFC PATCH perf/core v2 05/16] perf buildid: Use SBUILD_ID_SIZE macro
Em Wed, Jul 15, 2015 at 06:14:28PM +0900, Masami Hiramatsu escreveu:
Quoted 2 lines
Introduce
SBUILD_ID_SIZEmacro and use it instead of usingBUILD_ID_SIZE* 2 + 1.
Applied.
- Arnaldo
tip-bot for Masami Hiramatsu
merge bot[tip:perf/core] perf buildid: Use SBUILD_ID_SIZE macro
In reply to Masami Hiramatsuperf buildid: Use SBUILD_ID_SIZE macro
Commit-ID: d77fac7f9e687d137b17296d86d9143c2cccab6a Gitweb: http://git.kernel.org/tip/d77fac7f9e687d137b17296d86d9143c2cccab6a Author: Masami Hiramatsu <[email protected]> AuthorDate: Wed, 15 Jul 2015 18:14:28 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 20 Jul 2015 17:49:50 -0300
perf buildid: Use SBUILD_ID_SIZE macro
Introduce SBUILD_ID_SIZE macro and use it instead of using BUILD_ID_SIZE
* 2 + 1.
--- tools/perf/builtin-buildid-cache.c | 8 ++++---- tools/perf/builtin-buildid-list.c | 4 ++-- tools/perf/util/build-id.c | 4 ++-- tools/perf/util/build-id.h | 3 ++- 4 files changed, 10 insertions(+), 9 deletions(-)
tools/perf/builtin-buildid-cache.c +4 -4
@@ -127,7 +127,7 @@ static int build_id_cache__kcore_existing(const char *from_dir, char *to_dir,static int build_id_cache__add_kcore (const char *filename,bool force) { -char dir[32 ], sbuildid[BUILD_ID_SIZE *2 +1 ]; +char dir[32 ], sbuildid[SBUILD_ID_SIZE ];char from_dir[PATH_MAX ], to_dir[PATH_MAX ];char *p;
@@ -184,7 +184,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force)static int build_id_cache__add_file (const char *filename) { -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];u8 build_id[BUILD_ID_SIZE ];int err;
@@ -204,7 +204,7 @@ static int build_id_cache__add_file(const char *filename)static int build_id_cache__remove_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];int err;
@@ -276,7 +276,7 @@ static int build_id_cache__fprintf_missing(struct perf_session *session, FILE *fstatic int build_id_cache__update_file (const char *filename) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];int err =0 ;
tools/perf/builtin-buildid-list.c +2 -2
@@ -20,7 +20,7 @@static int sysfs__fprintf_build_id (FILE *fp) {u8 kallsyms_build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];if (sysfs__read_build_id ("/sys/kernel/notes" , kallsyms_build_id,sizeof (kallsyms_build_id)) !=0 )
@@ -35,7 +35,7 @@ static int sysfs__fprintf_build_id(FILE *fp)static int filename__fprintf_build_id (const char *name,FILE *fp) {u8 build_id[BUILD_ID_SIZE ]; -char sbuild_id[BUILD_ID_SIZE *2 +1 ]; +char sbuild_id[SBUILD_ID_SIZE ];if (filename__read_build_id (name, build_id,sizeof (build_id)) !=sizeof (build_id))
tools/perf/util/build-id.c +2 -2
@@ -124,7 +124,7 @@ static char *build_id__filename(const char *sbuild_id, char *bf, size_t size)char *dso__build_id_filename (const struct dso *dso,char *bf,size_t size) { -char build_id_hex[BUILD_ID_SIZE *2 +1 ]; +char build_id_hex[SBUILD_ID_SIZE ];if (!dso->has_build_id)return NULL ;
@@ -384,7 +384,7 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, const char *name, bool is_kallsyms, bool is_vdso) { - char sbuild_id[BUILD_ID_SIZE * 2 + 1]; + char sbuild_id[SBUILD_ID_SIZE];build_id__sprintf (build_id, build_id_size, sbuild_id);
tools/perf/util/build-id.h +2 -1
@@ -1,7 +1,8 @@#ifndef PERF_BUILD_ID_H_ #define PERF_BUILD_ID_H_ 1 -#define BUILD_ID_SIZE 20 +#define BUILD_ID_SIZE 20 +#define SBUILD_ID_SIZE (BUILD_ID_SIZE * 2 + 1)#include "tool.h" #include "strlist.h"
RFC PATCH v2 6/16 perf buildid: Introduce sysfs/filename__sprintf_build_id
In reply to Masami HiramatsuIntroduce sysfs/filename__sprintf_build_id for consolidating similar code.
--- tools/perf/builtin-buildid-cache.c | 14 ++------------ tools/perf/builtin-buildid-list.c | 24 ++++++++++-------------- tools/perf/util/build-id.c | 32 ++++++++++++++++++++++++++++++++ tools/perf/util/build-id.h | 3 +++ 4 files changed, 47 insertions(+), 26 deletions(-)
tools/perf/builtin-buildid-cache.c +2 -12
@@ -25,8 +25,6 @@static int build_id_cache__kcore_buildid (const char *proc_dir,char *sbuildid) {char root_dir[PATH_MAX ]; -char notes[PATH_MAX ]; -u8 build_id[BUILD_ID_SIZE ];char *p;strlcpy (root_dir, proc_dir,sizeof (root_dir));
@@ -35,15 +33,7 @@ static int build_id_cache__kcore_buildid(const char *proc_dir, char *sbuildid)if (!p)return -1 ; *p ='\0' ; - -scnprintf (notes,sizeof (notes),"%s/sys/kernel/notes" , root_dir); - -if (sysfs__read_build_id (notes, build_id,sizeof (build_id))) -return -1 ; - -build_id__sprintf (build_id,sizeof (build_id), sbuildid); - -return 0 ; +return sysfs__sprintf_build_id (root_dir, sbuildid); }static int build_id_cache__kcore_dir (char *dir,size_t sz)
@@ -138,7 +128,7 @@ static int build_id_cache__add_kcore(const char *filename, bool force)return -1 ; *p ='\0' ; -if (build_id_cache__kcore_buildid (from_dir, sbuildid)) +if (build_id_cache__kcore_buildid (from_dir, sbuildid) <0 )return -1 ; scnprintf(to_dir, sizeof(to_dir), "%s/[kernel.kcore]/%s",
tools/perf/builtin-buildid-list.c +10 -14
@@ -19,29 +19,25 @@static int sysfs__fprintf_build_id (FILE *fp) { -u8 kallsyms_build_id[BUILD_ID_SIZE ];char sbuild_id[SBUILD_ID_SIZE ]; +int ret; -if (sysfs__read_build_id ("/sys/kernel/notes" , kallsyms_build_id, -sizeof (kallsyms_build_id)) !=0 ) -return -1 ; + ret =sysfs__sprintf_build_id ("/" , sbuild_id); +if (ret !=sizeof (sbuild_id)) +return ret <0 ? ret : -EINVAL ; -build_id__sprintf (kallsyms_build_id,sizeof (kallsyms_build_id), - sbuild_id); -fprintf (fp,"%s\n" , sbuild_id); -return 0 ; +return fprintf (fp,"%s\n" , sbuild_id); }static int filename__fprintf_build_id (const char *name,FILE *fp) { -u8 build_id[BUILD_ID_SIZE ];char sbuild_id[SBUILD_ID_SIZE ]; +int ret; -if (filename__read_build_id (name, build_id, -sizeof (build_id)) !=sizeof (build_id)) -return 0 ; + ret =filename__sprintf_build_id (name, sbuild_id); +if (ret !=sizeof (sbuild_id)) +return ret <0 ? ret : -EINVAL ; -build_id__sprintf (build_id,sizeof (build_id), sbuild_id);return fprintf (fp,"%s\n" , sbuild_id); }
@@ -63,7 +59,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)/* * See if this is an ELF file first: */ -if (filename__fprintf_build_id (input_name, stdout)) +if (filename__fprintf_build_id (input_name, stdout) >0 ) goto out; session =perf_session__new (&file, false, &build_id__mark_dso_hit_ops);
tools/perf/util/build-id.c +32 -0
@@ -93,6 +93,38 @@ int build_id__sprintf(const u8 *build_id, int len, char *bf)return raw - build_id; } +int sysfs__sprintf_build_id (const char *root_dir,char *sbuild_id) +{ +char notes[PATH_MAX ]; +u8 build_id[BUILD_ID_SIZE ]; +int ret; + +if (!root_dir) + root_dir ="" ; + +scnprintf (notes,sizeof (notes),"%s/sys/kernel/notes" , root_dir); + + ret =sysfs__read_build_id (notes, build_id,sizeof (build_id)); +if (ret <0 ) +return ret; + +return build_id__sprintf (build_id,sizeof (build_id), sbuild_id); +} + +int filename__sprintf_build_id (const char *pathname,char *sbuild_id) +{ +u8 build_id[BUILD_ID_SIZE ]; +int ret; + + ret =filename__read_build_id (pathname, build_id,sizeof (build_id)); +if (ret <0 ) +return ret; +else if (ret !=sizeof (build_id)) +return -EINVAL ; + +return build_id__sprintf (build_id,sizeof (build_id), sbuild_id); +} +/* asnprintf consolidates asprintf and snprintf */ static int asnprintf (char **strp,size_t size,const char *fmt, ...) {
tools/perf/util/build-id.h +3 -0
@@ -12,6 +12,9 @@ extern struct perf_tool build_id__mark_dso_hit_ops;struct dso ;int build_id__sprintf (const u8 *build_id,int len,char *bf); +int sysfs__sprintf_build_id (const char *root_dir,char *sbuild_id); +int filename__sprintf_build_id (const char *pathname,char *sbuild_id); +char *dso__build_id_filename (const struct dso *dso,char *bf,size_t size); int build_id__mark_dso_hit(struct perf_tool *tool, union perf_event *event,
RFC PATCH v2 7/16 perf: Add lsdir to read a directory
In reply to Masami HiramatsuAs a utility function, add lsdir() which reads given directory and store entry name into a strlist. lsdir accepts a filter function so that user can filter out unneeded entries.
--- tools/perf/util/util.c | 34 ++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 4 ++++ 2 files changed, 38 insertions(+)
tools/perf/util/util.c +34 -0
@@ -115,6 +115,40 @@ int rm_rf(char *path)return rmdir (path); } +/* A filter which removes dot files */ +bool lsdir_no_dot_filter (const char *dirname__maybe_unused ,struct dirent *d) +{ +return d->d_name[0 ] !='.' ; +} + +/* lsdir reads a directory and store it in strlist */ +struct strlist *lsdir (const char *dirname, +bool (*filter)(const char *,struct dirent *)) +{ +struct strlist *list =NULL ; +DIR *dir; +struct dirent *d; + + dir =opendir (dirname); +if (!dir) +return NULL ; + + list =strlist__new (true,NULL ); +if (!list) { + errno = -ENOMEM ; + goto out; + } + +while ((d =readdir (dir)) !=NULL ) { +if (!filter ||filter (dirname, d)) +strlist__add (list, d->d_name); + } + +out: +closedir (dir); +return list; +} +static int slow_copyfile (const char *from,const char *to) {int err =-1 ;
tools/perf/util/util.h +4 -0
@@ -79,6 +79,7 @@#include <termios.h> #include <linux/bitops.h> #include <termios.h> +#include "strlist.h" extern const char *graph_line;extern const char *graph_dotted_line;
@@ -250,6 +251,9 @@ static inline int sane_case(int x, int high)int mkdir_p (char *path,mode_t mode);int rm_rf (char *path); +struct strlist *lsdir (const char *dirname, +bool (*filter)(const char *,struct dirent *)); +bool lsdir_no_dot_filter (const char *dirname__maybe_unused ,struct dirent *d);int copyfile (const char *from,const char *to);int copyfile_mode (const char *from,const char *to,mode_t mode);int copyfile_offset (int fromfd,loff_t from_ofs,int tofd,loff_t to_ofs,u64 size);
RFC PATCH v2 8/16 perf-buildid-cache: Use lsdir for looking up buildid caches
In reply to Masami HiramatsuUse new lsdir() for looking up buildid caches. This changes logic a bit to ignore all dot files, since the build-id cache must not start with dot.
--- tools/perf/util/build-id.c | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-)
tools/perf/util/build-id.c +5 -25
@@ -342,38 +342,18 @@ int build_id_cache__list_build_ids(const char *pathname, {struct strlist *list;char *dir_name; -DIR *dir; -struct dirent *d;int ret =0 ; - list =strlist__new (true,NULL ); dir_name =build_id_cache__dirname_from_path (pathname, false, false,NULL ); -if (!list || !dir_name) { - ret = -ENOMEM ; - goto out; - } +if (!dir_name) +return -ENOMEM ; -/* List up all dirents */ - dir =opendir (dir_name); -if (!dir) { + list =lsdir (dir_name, lsdir_no_dot_filter); +if (!list) ret = -errno; - goto out; - } - -while ((d =readdir (dir)) !=NULL ) { -if (!strcmp (d->d_name,"." ) || !strcmp (d->d_name,".." )) -continue ; -strlist__add (list, d->d_name); - } -closedir (dir); - -out: + *result = list;free (dir_name); -if (ret) -strlist__delete (list); -else - *result = list;return ret; }
RFC PATCH v2 9/16 perf probe: Add --cache option to cache the probe definitions
In reply to Masami HiramatsuAdd --cache option to cache the probe definitions. This just saves the result of the dwarf analysis to probe cache.
---
Changes in v2:
- Update documentations/perf-probe.txt.
--- tools/perf/Documentation/perf-probe.txt | 4 tools/perf/builtin-probe.c | 1 tools/perf/util/build-id.c | 13 + tools/perf/util/build-id.h | 2 tools/perf/util/probe-event.c | 136 ++++++++++++-- tools/perf/util/probe-event.h | 5 + tools/perf/util/probe-file.c | 298 +++++++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 20 ++ 8 files changed, 447 insertions(+), 32 deletions(-)
tools/perf/Documentation/perf-probe.txt +4 -0
@@ -109,6 +109,10 @@ OPTIONS Dry run. With this option, --add and --del doesn't execute actual adding and removal operations. +--cache:: + Cache the probes (with --add option). Any events which successfully added + are also stored in the cache file. + --max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128.
tools/perf/builtin-probe.c +1 -0
@@ -396,6 +396,7 @@ __cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) opt_set_filter),OPT_CALLBACK ('x' ,"exec" ,NULL ,"executable|path" ,"target executable name or path" , opt_set_target), +OPT_BOOLEAN (0 ,"cache" , &probe_conf.cache,"Manipulate probe cache" ),OPT_BOOLEAN (0 ,"demangle" , &symbol_conf.demangle,"Enable symbol demangling" ), OPT_BOOLEAN(0, "demangle-kernel", &symbol_conf.demangle_kernel,
tools/perf/util/build-id.c +6 -7
@@ -313,9 +313,8 @@ void disable_buildid_cache(void) no_buildid_cache = true; } -static char *build_id_cache__dirname_from_path (const char *name, -bool is_kallsyms,bool is_vdso, -const char *sbuild_id) +char *build_id_cache__dirname_from_path (const char *sbuild_id,const char *name, +bool is_kallsyms,bool is_vdso) {char *realname = (char *)name, *filename;bool slash = is_kallsyms || is_vdso;
@@ -344,8 +343,8 @@ int build_id_cache__list_build_ids(const char *pathname,char *dir_name;int ret =0 ; - dir_name =build_id_cache__dirname_from_path (pathname, false, false, -NULL ); + dir_name =build_id_cache__dirname_from_path (NULL , pathname, + false, false);if (!dir_name)return -ENOMEM ;
@@ -372,8 +371,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } - dir_name =build_id_cache__dirname_from_path (name, is_kallsyms, - is_vdso, sbuild_id); + dir_name =build_id_cache__dirname_from_path (sbuild_id, name, + is_kallsyms, is_vdso);if (!dir_name) goto out_free;
tools/perf/util/build-id.h +2 -0
@@ -27,6 +27,8 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits);int perf_session__write_buildid_table (struct perf_session *session,int fd);int perf_session__cache_build_ids (struct perf_session *session); +char *build_id_cache__dirname_from_path (const char *sbuild_id,const char *name, +bool is_kallsyms,bool is_vdso);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 +111 -25
198 lines not on this page · raw message
tools/perf/util/probe-event.h +5 -0
@@ -12,6 +12,7 @@ struct probe_conf {bool show_location_range;bool force_add;bool no_inlines; +bool cache;int max_probes; };extern struct probe_conf probe_conf;
@@ -116,6 +117,10 @@ extern int parse_probe_trace_command(const char *cmd,extern char *synthesize_perf_probe_command (struct perf_probe_event *pev);extern char *synthesize_probe_trace_command (struct probe_trace_event *tev);extern char *synthesize_perf_probe_arg (struct perf_probe_arg *pa); +char *synthesize_perf_probe_point (struct perf_probe_point *pp); + +int perf_probe_event__copy (struct perf_probe_event *dst, +struct perf_probe_event *src);/* Check the perf_probe_event needs debuginfo */ extern bool perf_probe_event_need_dwarf (struct perf_probe_event *pev);
tools/perf/util/probe-file.c +298 -0
307 lines not on this page · raw message
tools/perf/util/probe-file.h +20 -0
@@ -15,4 +15,24 @@ struct strlist *probe_file__get_rawlist(int fd);int probe_file__add_event (int fd,struct probe_trace_event *tev);int probe_file__del_events (int fd,struct strfilter *filter); +/* Cache of probe definitions */ +struct probe_cache_entry { +struct list_head list; +struct perf_probe_event pev; +char *spev; +struct strlist *tevlist; +}; + +struct probe_cache { +int fd; +struct list_head list; +}; + +struct probe_cache *probe_cache__new (const char *target); +int probe_cache__add_entry (struct probe_cache *pcache, +struct perf_probe_event *pev, +struct probe_trace_event *tevs,int ntevs); +int probe_cache__commit (struct probe_cache *pcache); +void probe_cache__delete (struct probe_cache *pcache); +#endif
RFC PATCH v2 10/16 perf probe: Use cache entry if possible
In reply to Masami HiramatsuBefore analyzing debuginfo, try to find a corresponding entry from probe cache always. This does not depend on --cache, the --cache enables to store/update cache, but looking up the cache is always enabled.
---
Changes in v2:
- Reuse tev->event and tev->group as base event name if possible, since when using the cache entry with wildcard, pev will not have its name/symbol.
- Do not skip trace events whose tev->point.symbol == NULL if pev->uprobes is set, since cached uprobe event doesn't know the original symbols.
- Fix to set tev->uprobes attribute flag from the pev->uprobes.
--- tools/perf/util/probe-event.c | 70 ++++++++++++++++++++++++++++++++++++++++- tools/perf/util/probe-file.c | 20 +++++++++++- tools/perf/util/probe-file.h | 5 ++- 3 files changed, 91 insertions(+), 4 deletions(-)
tools/perf/util/probe-event.c +68 -2
@@ -2310,13 +2310,18 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev,if (pev->event) event = pev->event; -else +else if (tev->event) + event = tev->event; +else {if (pev->point.function && !strisglob (pev->point.function)) event = pev->point.function;else event = tev->point.realname; + }if (pev->group) group = pev->group; +else if (tev->group) + group = tev->group;else group =PERFPROBE_GROUP ;
@@ -2366,7 +2371,7 @@ static int __add_probe_trace_events(struct perf_probe_event *pev,for (i =0 ; i < ntevs; i++) { tev = &tevs[i];/* Skip if the symbol is out of .text or blacklisted */ -if (!tev->point.symbol) +if (!tev->point.symbol && !pev->uprobes)continue ;/* Set new name for tev (and update namelist) */
@@ -2589,6 +2594,62 @@ err_out:bool __weak arch__prefers_symtab (void ) {return false; } +static int find_probe_trace_events_from_cache (struct perf_probe_event *pev, +struct probe_trace_event **tevs) +{ +struct probe_cache *cache; +struct probe_cache_entry *entry; +struct probe_trace_event *tev; +struct str_node *node; +int ret, i; + + cache =probe_cache__new (pev->target); +if (!cache) +return 0 ; + + entry =probe_cache__find (cache, pev); + +if (!entry && !pev->event && + (!pev->point.file && pev->point.function && !pev->point.retprobe && + !pev->point.line && !pev->point.offset && !pev->point.lazy_line)) { + entry =probe_cache__find_by_name (cache, pev->group, + pev->point.function); + } +if (!entry) { + ret =0 ; + goto out; + } + + ret =strlist__nr_entries (entry->tevlist); +if (ret > probe_conf.max_probes) { +pr_debug ("Too many entries matched in the cache of %s\n" , + pev->target ? :"kernel" ); + ret = -E2BIG ; + goto out; + } + + *tevs =zalloc (ret *sizeof (*tev)); +if (!*tevs) { + ret = -ENOMEM ; + goto out; + } + + i =0 ; +strlist__for_each (node, entry->tevlist) { + tev = &(*tevs)[i++]; + ret =parse_probe_trace_command (node->s, tev); +if (ret <0 ) + goto out; +/* Set the uprobes attribute as same as original */ + tev->uprobes = pev->uprobes; + } + ret = i; + +out: +probe_cache__delete (cache); +return ret; +} +static int convert_to_probe_trace_events (struct perf_probe_event *pev,struct probe_trace_event **tevs) {
@@ -2603,6 +2664,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, } } +/* At first, we need to lookup cache entry */ + ret =find_probe_trace_events_from_cache (pev, tevs); +if (ret >0 ) +return ret;/* Found in probe cache */ +if (arch__prefers_symtab () && !perf_probe_event_need_dwarf (pev)) { ret =find_probe_trace_events_from_map (pev, tevs);if (ret >0 )
tools/perf/util/probe-file.c +19 -1
@@ -481,7 +481,7 @@ static bool streql(const char *a, const char *b)return !strcmp (a, b); } -static struct probe_cache_entry * +struct probe_cache_entry *probe_cache__find (struct probe_cache *pcache,struct perf_probe_event *pev) {struct probe_cache_entry *entry =NULL ;
@@ -506,6 +506,24 @@ found:return entry; } +struct probe_cache_entry * +probe_cache__find_by_name (struct probe_cache *pcache, +const char *group,const char *event) +{ +struct probe_cache_entry *entry =NULL ; + +list_for_each_entry (entry, &pcache->list, list) { +/* Hit if same event name or same command-string */ +if (streql (entry->pev.group, group) && +streql (entry->pev.event, event)) + goto found; + } + entry =NULL ; + +found: +return entry; +} +int probe_cache__add_entry (struct probe_cache *pcache,struct perf_probe_event *pev,struct probe_trace_event *tevs,int ntevs)
tools/perf/util/probe-file.h +4 -1
@@ -34,5 +34,8 @@ int probe_cache__add_entry(struct probe_cache *pcache, struct probe_trace_event *tevs, int ntevs);int probe_cache__commit (struct probe_cache *pcache);void probe_cache__delete (struct probe_cache *pcache); - +struct probe_cache_entry *probe_cache__find (struct probe_cache *pcache, +struct perf_probe_event *pev); +struct probe_cache_entry *probe_cache__find_by_name (struct probe_cache *pcache, +const char *group,const char *event);#endif
RFC PATCH v2 11/16 perf probe: Show all cached probes
In reply to Masami Hiramatsuperf probe --list shows all cached probes when --cache is given. Each caches are shown with on which binary that probed. e.g.
-----
# perf probe --cache vfs_read \$params # perf probe --cache -x /lib64/libc-2.17.so getaddrinfo \$params # ./perf probe --cache --list /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1): vfs_read $params /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc): getaddrinfo $params ----- Note that $params requires debuginfo.
---
Changes in v2:
- Fix to ignore if build-id list is failed to get with -ENOENT, since this can happen when ~/.debug is not initialized.
- Do not show binary name if there is no cached entries.
- Update perf-probe.txt too.
--- tools/perf/Documentation/perf-probe.txt | 8 ++- tools/perf/builtin-probe.c | 2 - tools/perf/util/build-id.c | 79 ++++++++++++++++++++++++++++++- tools/perf/util/build-id.h | 3 + tools/perf/util/probe-event.c | 3 + tools/perf/util/probe-file.c | 65 +++++++++++++++++++++++++- tools/perf/util/probe-file.h | 1 7 files changed, 154 insertions(+), 7 deletions(-)
tools/perf/Documentation/perf-probe.txt +6 -2
@@ -67,7 +67,10 @@ OPTIONS -l:: --list[=[GROUP:]EVENT]:: - List up current probe events. This can also accept filtering patterns of event names. + List up current probe events. This can also accept filtering patterns of + event names. + When this is used with --cache, perf shows all cached probes instead of + the live probes. -L:: --line=::
@@ -110,8 +113,9 @@ OPTIONS adding and removal operations. --cache:: - Cache the probes (with --add option). Any events which successfully added + (With --add) Cache the probes. Any events which successfully added are also stored in the cache file. + (With --list) Show cached probes. --max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128.
tools/perf/builtin-probe.c +1 -1
@@ -44,7 +44,7 @@#define DEFAULT_VAR_FILTER "!__k???tab_* & !__crc_*"#define DEFAULT_FUNC_FILTER "!_*" -#define DEFAULT_LIST_FILTER "*:*" +#define DEFAULT_LIST_FILTER "*"/* Session management structure */ static struct {
tools/perf/util/build-id.c +77 -2
97 lines not on this page · raw message
tools/perf/util/build-id.h +3 -0
@@ -27,8 +27,11 @@ bool perf_session__read_build_ids(struct perf_session *session, bool with_hits);int perf_session__write_buildid_table (struct perf_session *session,int fd);int perf_session__cache_build_ids (struct perf_session *session); +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__dirname_from_path (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso); +int build_id_cache__list_all (struct strlist **result);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 +3 -0
@@ -2210,6 +2210,9 @@ int show_perf_probe_events(struct strfilter *filter)setup_pager (); +if (probe_conf.cache) +return probe_cache__show_all_caches (filter); + ret =init_symbol_maps (false);if (ret <0 )return ret;
tools/perf/util/probe-file.c +63 -2
84 lines not on this page · raw message
tools/perf/util/probe-file.h +1 -0
@@ -38,4 +38,5 @@ struct probe_cache_entry *probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev);struct probe_cache_entry *probe_cache__find_by_name (struct probe_cache *pcache,const char *group,const char *event); +int probe_cache__show_all_caches (struct strfilter *filter);#endif
RFC PATCH v2 12/16 perf probe: Remove caches when --cache is given
In reply to Masami Hiramatsuperf-probe --del removes caches when --cache is given. Note that the delete pattern is not same as normal events.
If you cached probes with event name, --del "eventname" works as expected. However, if you skipped it, the cached probes doesn't have actual event name. In that case
--del "probe-desc" is required (wildcard is acceptable).
For example a cache entry has the probe-desc "vfs_read $params", you can remove it with --del 'vfs_read*'.
-----
# perf probe --cache --list /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1): vfs_read $params /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc): getaddrinfo $params
# perf probe --cache --del vfs_read\* Removed event: probe:vfs_read
# perf probe --cache --list /[kernel.kallsyms] (1466a0a250b5d0070c6d0f03c5fed30b237970a1): /usr/lib64/libc-2.17.so (c31ffe7942bfd77b2fca8f9bd5709d387a86d3bc): getaddrinfo $params -----
---
Changes in v2:
- Update perf-probe.txt
--- tools/perf/Documentation/perf-probe.txt | 1 + tools/perf/util/probe-event.c | 26 ++++++++++++++++++++++++ tools/perf/util/probe-file.c | 33 +++++++++++++++++++++++-------- tools/perf/util/probe-file.h | 2 ++ 4 files changed, 54 insertions(+), 8 deletions(-)
tools/perf/Documentation/perf-probe.txt +1 -0
@@ -116,6 +116,7 @@ OPTIONS (With --add) Cache the probes. Any events which successfully added are also stored in the cache file. (With --list) Show cached probes. + (With --del) Remove cached probes. --max-probes=NUM:: Set the maximum number of probe points for an event. Default is 128.
tools/perf/util/probe-event.c +26 -0
@@ -2746,6 +2746,30 @@ end:return ret; } +static int del_perf_probe_caches (struct strfilter *filter) +{ +struct probe_cache *cache; +struct strlist *bidlist; +struct str_node *nd; +int ret; + + ret =build_id_cache__list_all (&bidlist); +if (ret <0 ) { +pr_debug ("Failed to get buildids: %d\n" , ret); +return ret; + } + +strlist__for_each (nd, bidlist) { + cache =probe_cache__new (nd->s); +if (!cache) +continue ; +probe_cache__remove_entries (cache, filter); +probe_cache__commit (cache); +probe_cache__delete (cache); + } +return 0 ; +} +int del_perf_probe_events (struct strfilter *filter) {int ret, ret2, ufd =-1 , kfd =-1 ;
@@ -2755,6 +2779,8 @@ int del_perf_probe_events(struct strfilter *filter)return -EINVAL ;pr_debug ("Delete filter: \'%s\'\n" , str); +if (probe_conf.cache) +return del_perf_probe_caches (filter);/* Get current event names */ ret =probe_file__open_both (&kfd, &ufd,PF_FL_RW );
tools/perf/util/probe-file.c +25 -8
@@ -371,7 +371,6 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)return ret; } } - dir_name =build_id_cache__dirname_from_path (sbuildid, target, is_kallsyms, false); found:
@@ -627,19 +626,37 @@ out:return ret; } +static bool probe_cache_entry__compare (struct probe_cache_entry *entry, +struct strfilter *filter) +{ +char buf[128 ], *ptr = entry->spev; + +if (entry->pev.event) { +snprintf (buf,128 ,"%s:%s" , entry->pev.group, entry->pev.event); + ptr = buf; + } +return strfilter__compare (filter, ptr); +} + +int probe_cache__remove_entries (struct probe_cache *pcache, +struct strfilter *filter) +{ +struct probe_cache_entry *entry, *tmp; + +list_for_each_entry_safe (entry, tmp, &pcache->list, list) { +if (probe_cache_entry__compare (entry, filter)) +probe_cache_entry__delete (entry); + } +return 0 ; +} +static int probe_cache__show_entries (struct probe_cache *pcache,struct strfilter *filter) {struct probe_cache_entry *entry; -char buf[128 ], *ptr;list_for_each_entry (entry, &pcache->list, list) { -if (entry->pev.event) { - ptr = buf; -snprintf (buf,128 ,"%s:%s" , entry->pev.group, entry->pev.event); - }else - ptr = entry->spev; -if (strfilter__compare (filter, ptr)) +if (probe_cache_entry__compare (entry, filter))printf ("%s\n" , entry->spev); }return 0 ;
tools/perf/util/probe-file.h +2 -0
@@ -34,6 +34,8 @@ int probe_cache__add_entry(struct probe_cache *pcache, struct probe_trace_event *tevs, int ntevs);int probe_cache__commit (struct probe_cache *pcache);void probe_cache__delete (struct probe_cache *pcache); +int probe_cache__remove_entries (struct probe_cache *pcache, +struct strfilter *filter);struct probe_cache_entry *probe_cache__find (struct probe_cache *pcache,struct perf_probe_event *pev); struct probe_cache_entry *probe_cache__find_by_name(struct probe_cache *pcache,
RFC PATCH v2 13/16 perf/sdt: ELF support for SDT
In reply to Masami HiramatsuFrom: Hemant Kumar <[email protected]>
This patch serves the initial support to identify and list SDT events in binaries. When programs containing SDT markers are compiled, gcc with the help of assembler directives identifies them and places them in the section ".note.stapsdt". To find these markers from the binaries, one needs to traverse through this section and parse the relevant details like the name, type and location of the marker. Also, the original location could be skewed due to the effect of prelinking. If that is the case, the locations need to be adjusted.
The functions in this patch open a given ELF, find out the SDT section, parse the relevant details, adjust the location (if necessary) and populate them in a list.
A typical note entry in ".note.stapsdt" section is as follows :
|--nhdr.n_namesz--|
------------------------------------
| nhdr | "stapsdt" |
----- |----------------------------------|
| | <location> <base_address> |
| | <semaphore> |
nhdr.n_descsize | "provider_name" "note_name" |
| | <args> |
----- |----------------------------------|
| nhdr | "stapsdt" |
|...The above shows an excerpt from the section ".note.stapsdt". 'nhdr' is a structure which has the note name size (n_namesz), note description size (n_desc_sz) and note type (n_type). So, in order to parse the note note info, we need nhdr to tell us where to start from. As can be seen from <sys/sdt.h>, the name of the SDT notes given is "stapsdt". But this is not the identifier of the note.
After that, we go to description of the note to find out its location, the address of the ".stapsdt.base" section and the semaphore address. Then, we find the provider name and the SDT marker name and then follow the arguments.
--- tools/perf/util/symbol-elf.c | 252 ++++++++++++++++++++++++++++++++++++++++++ tools/perf/util/symbol.h | 22 ++++ 2 files changed, 274 insertions(+)
tools/perf/util/symbol-elf.c +252 -0
@@ -1775,6 +1775,258 @@ void kcore_extract__delete(struct kcore_extract *kce)unlink (kce->extract_filename); } +/** +* populate_sdt_note : Parse raw data and identify SDT note +* @elf: elf of the opened file +* @data: raw data of a section with description offset applied +* @len: note description size +* @type: type of the note +* @sdt_notes: List to add the SDT note +* +* Responsible for parsing the @data in section .note.stapsdt in @elf and +* if its an SDT note, it appends to @sdt_notes list. +*/ +static int populate_sdt_note (Elf **elf,const char *data,size_t len, +struct list_head *sdt_notes) +{ +const char *provider, *name; +struct sdt_note *tmp =NULL ; +GElf_Ehdr ehdr; +GElf_Addr base_off =0 ; +GElf_Shdr shdr; +int ret = -EINVAL ; + +union { +Elf64_Addr a64[NR_ADDR ]; +Elf32_Addr a32[NR_ADDR ]; + } buf; + +Elf_Data dst = { + .d_buf = &buf, .d_type =ELF_T_ADDR , .d_version =EV_CURRENT , + .d_size =gelf_fsize ((*elf),ELF_T_ADDR ,NR_ADDR ,EV_CURRENT ), + .d_off =0 , .d_align =0 + }; +Elf_Data src = { + .d_buf = (void *) data, .d_type =ELF_T_ADDR , + .d_version =EV_CURRENT , .d_size = dst.d_size, .d_off =0 , + .d_align =0 + }; + + tmp = (struct sdt_note *)calloc (1 ,sizeof (struct sdt_note )); +if (!tmp) { + ret = -ENOMEM ; + goto out_err; + } + +INIT_LIST_HEAD (&tmp->note_list); + +if (len < dst.d_size +3 ) + goto out_free_note; + +/* Translation from file representation to memory representation */ +if (gelf_xlatetom (*elf, &dst, &src, +elf_getident (*elf,NULL )[EI_DATA ]) ==NULL ) { +pr_err ("gelf_xlatetom : %s\n" ,elf_errmsg (-1 )); + goto out_free_note; + } + +/* Populate the fields of sdt_note */ + provider = data + dst.d_size; + + name = (const char *)memchr (provider,'\0' , data + len - provider); +if (name++ ==NULL ) + goto out_free_note; + + tmp->provider =strdup (provider); +if (!tmp->provider) { + ret = -ENOMEM ; + goto out_free_note; + } + tmp->name =strdup (name); +if (!tmp->name) { + ret = -ENOMEM ; + goto out_free_prov; + } + +if (gelf_getclass (*elf) ==ELFCLASS32 ) { +memcpy (&tmp->addr, &buf,3 *sizeof (Elf32_Addr)); + tmp->bit32 = true; + }else { +memcpy (&tmp->addr, &buf,3 *sizeof (Elf64_Addr)); + tmp->bit32 = false; + } + +if (!gelf_getehdr (*elf, &ehdr)) { +pr_debug ("%s : cannot get elf header.\n" , __func__); + ret = -EBADF ; + goto out_free_name; + } + +/* Adjust the prelink effect : +* Find out the .stapsdt.base section. +* This scn will help us to handle prelinking (if present). +* Compare the retrieved file offset of the base section with the +* base address in the description of the SDT note. If its different, +* then accordingly, adjust the note location. +*/ +if (elf_section_by_name (*elf, &ehdr, &shdr,SDT_BASE_SCN ,NULL )) { + base_off = shdr.sh_offset; +if (base_off) { +if (tmp->bit32) + tmp->addr.a32[0 ] = tmp->addr.a32[0 ] + base_off - + tmp->addr.a32[1 ]; +else + tmp->addr.a64[0 ] = tmp->addr.a64[0 ] + base_off - + tmp->addr.a64[1 ]; + } + } + +list_add_tail (&tmp->note_list, sdt_notes); +return 0 ; + +out_free_name: +free (tmp->name); +out_free_prov: +free (tmp->provider); +out_free_note: +free (tmp); +out_err: +return ret; +} + +/** +* construct_sdt_notes_list : constructs a list of SDT notes +* @elf : elf to look into +* @sdt_notes : empty list_head +* +* Scans the sections in 'elf' for the section +* .note.stapsdt. It, then calls populate_sdt_note to find +* out the SDT events and populates the 'sdt_notes'. +*/ +static int construct_sdt_notes_list (Elf *elf,struct list_head *sdt_notes) +{ +GElf_Ehdr ehdr; +Elf_Scn *scn =NULL ; +Elf_Data *data; +GElf_Shdr shdr; +size_t shstrndx, next; +GElf_Nhdr nhdr; +size_t name_off, desc_off, offset; +int ret =0 ; + +if (gelf_getehdr (elf, &ehdr) ==NULL ) { + ret = -EBADF ; + goto out_ret; + } +if (elf_getshdrstrndx (elf, &shstrndx) !=0 ) { + ret = -EBADF ; + goto out_ret; + } + +/* Look for the required section */ + scn =elf_section_by_name (elf, &ehdr, &shdr,SDT_NOTE_SCN ,NULL ); +if (!scn) { + ret = -ENOENT ; + goto out_ret; + } + +if ((shdr.sh_type !=SHT_NOTE ) || (shdr.sh_flags &SHF_ALLOC )) { + ret = -ENOENT ; + goto out_ret; + } + + data =elf_getdata (scn,NULL ); + +/* Get the SDT notes */ +for (offset =0 ; (next =gelf_getnote (data, offset, &nhdr, &name_off, + &desc_off)) >0 ; offset = next) { +if (nhdr.n_namesz ==sizeof (SDT_NOTE_NAME ) && + !memcmp (data->d_buf + name_off,SDT_NOTE_NAME , +sizeof (SDT_NOTE_NAME ))) { +/* Check the type of the note */ +if (nhdr.n_type !=SDT_NOTE_TYPE ) + goto out_ret; + + ret =populate_sdt_note (&elf, ((data->d_buf) + desc_off), + nhdr.n_descsz, sdt_notes); +if (ret <0 ) + goto out_ret; + } + } +if (list_empty (sdt_notes)) + ret = -ENOENT ; + +out_ret: +return ret; +} + +/** +* get_sdt_note_list : Wrapper to construct a list of sdt notes +* @head : empty list_head +* @target : file to find SDT notes from +* +* This opens the file, initializes +* the ELF and then calls construct_sdt_notes_list. +*/ +int get_sdt_note_list (struct list_head *head,const char *target) +{ +Elf *elf; +int fd, ret; + + fd =open (target,O_RDONLY ); +if (fd <0 ) +return -EBADF ; + + elf =elf_begin (fd,PERF_ELF_C_READ_MMAP ,NULL ); +if (!elf) { + ret = -EBADF ; + goto out_close; + } + ret =construct_sdt_notes_list (elf, head); +elf_end (elf); +out_close: +close (fd); +return ret; +} + +/** +* cleanup_sdt_note_list : free the sdt notes' list +* @sdt_notes: sdt notes' list +* +* Free up the SDT notes in @sdt_notes. +* Returns the number of SDT notes free'd. +*/ +int cleanup_sdt_note_list (struct list_head *sdt_notes) +{ +struct sdt_note *tmp, *pos; +int nr_free =0 ; + +list_for_each_entry_safe (pos, tmp, sdt_notes, note_list) { +list_del (&pos->note_list); +free (pos->name); +free (pos->provider); +free (pos); + nr_free++; + } +return nr_free; +} + +/** +* sdt_notes__get_count: Counts the number of sdt events +* @start: list_head to sdt_notes list +* +* Returns the number of SDT notes in a list +*/ +int sdt_notes__get_count (struct list_head *start) +{ +struct sdt_note *sdt_ptr; +int count =0 ; + +list_for_each_entry (sdt_ptr, start, note_list) + count++; +return count; +} +void symbol__elf_init (void ) {elf_version (EV_CURRENT );
tools/perf/util/symbol.h +22 -0
@@ -311,4 +311,26 @@ void arch__elf_sym_adjust(GElf_Sym *sym);int arch__choose_best_symbol (struct symbol *syma,struct symbol *symb); +/* structure containing an SDT note's info */ +struct sdt_note { +char *name;/* name of the note*/ +char *provider;/* provider name */ +bool bit32;/* whether the location is 32 bits? */ +union {/* location, base and semaphore addrs */ +Elf64_Addr a64[3 ]; +Elf32_Addr a32[3 ]; + } addr; +struct list_head note_list;/* SDT notes' list */ +}; + +int get_sdt_note_list (struct list_head *head,const char *target); +int cleanup_sdt_note_list (struct list_head *sdt_notes); +int sdt_notes__get_count (struct list_head *start); + +#define SDT_BASE_SCN ".stapsdt.base" +#define SDT_NOTE_SCN ".note.stapsdt" +#define SDT_NOTE_TYPE 3 +#define SDT_NOTE_NAME "stapsdt" +#define NR_ADDR 3 +#endif /* __PERF_SYMBOL */
RFC PATCH v2 14/16 perf probe: Add group name support
In reply to Masami HiramatsuAllow user to set group name for adding new event. Note that this can easily shot yourself in the foot. E.g. Existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can break something when loading/unloading modules.
--- tools/perf/util/probe-event.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)
tools/perf/util/probe-event.c +14 -9
@@ -1141,10 +1141,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)bool file_spec = false;/* * <Syntax> -* perf probe [EVENT=]SRC[:LN|;PTN] -* perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] -* -* TODO:Group name support +* perf probe [GRP:][EVENT=]SRC[:LN|;PTN] +* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] */ if (!arg)return -EINVAL ;
@@ -1153,11 +1151,19 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)if (ptr && *ptr =='=' ) {/* Event name */ *ptr ='\0' ; tmp = ptr +1 ; -if (strchr (arg,':' )) { -semantic_error ("Group name is not supported yet.\n" ); -return -ENOTSUP ; - } + ptr =strchr (arg,':' ); +if (ptr) { + *ptr ='\0' ; +if (!is_c_func_name (arg)) + goto not_fname; + pev->group =strdup (arg); +if (!pev->group) +return -ENOMEM ; + arg = ptr +1 ; + }else + pev->group =NULL ;if (!is_c_func_name (arg)) { +not_fname:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , arg);return -EINVAL ;
@@ -1165,7 +1171,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) pev->event =strdup (arg);if (pev->event ==NULL )return -ENOMEM ; - pev->group =NULL ; arg = tmp; }
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 14/16] perf probe: Add group name support
Quoted 6 lines · Masami Hiramatsu
Allow user to set group name for adding new event. Note that this can easily shot yourself in the foot. E.g. Existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can break something when loading/unloading modules.
Yes, I agree that this can be dangerous. How about enforcing [ku]probes to make the directory of dynamic events safely? I think it'd be better putting all dynamic events in a single directory - e.g. $tracefs/events/probe/. Any events lack group name are created in the directory. Any events have group name create subdirectories as group name under the directory. The perf tools (and others too) should be changed to lookup the directory after the usual location.
What do you think?
Quoted 11 lines
Signed-off-by Masami Hiramatsu <[email protected]>--- tools/perf/util/probe-event.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)tools/perf/util/probe-event.c +0
-0
tools/perf/util/probe-event.c static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) · line 1144
Quoted 8 lines
tools/perf/util/probe-event.c +1
-4@@ -1141,10 +1141,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)bool file_spec = false;/* * <Syntax> -* perf probe [EVENT=]SRC[:LN|;PTN] -* perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] -* -* TODO:Group name support +* perf probe [GRP:][EVENT=]SRC[:LN|;PTN]
Shouldn't it be
[[GRP:]EVENT=]
?
tools/perf/util/probe-event.c static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) · line 1145
Quoted 1 line
tools/perf/util/probe-event.c +1
-0+* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
Ditto.
Thanks,
Namhyung
Quoted 37 lines
tools/perf/util/probe-event.c +12
-5*/ if (!arg)return -EINVAL ;@@ -1153,11 +1151,19 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)if (ptr && *ptr =='=' ) {/* Event name */ *ptr ='\0' ; tmp = ptr +1 ; -if (strchr (arg,':' )) { -semantic_error ("Group name is not supported yet.\n" ); -return -ENOTSUP ; - } + ptr =strchr (arg,':' ); +if (ptr) { + *ptr ='\0' ; +if (!is_c_func_name (arg)) + goto not_fname; + pev->group =strdup (arg); +if (!pev->group) +return -ENOMEM ; + arg = ptr +1 ; + }else + pev->group =NULL ;if (!is_c_func_name (arg)) { +not_fname:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , arg);return -EINVAL ;@@ -1165,7 +1171,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) pev->event =strdup (arg);if (pev->event ==NULL )return -ENOMEM ; - pev->group =NULL ; arg = tmp; }
Re: [RFC PATCH perf/core v2 14/16] perf probe: Add group name support
Quoted 10 lines · Namhyung Kim
Quoted 6 lines · Masami Hiramatsu
Allow user to set group name for adding new event. Note that this can easily shot yourself in the foot. E.g. Existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can break something when loading/unloading modules.
Yes, I agree that this can be dangerous. How about enforcing [ku]probes to make the directory of dynamic events safely?
What the safety issue would you afraid?
Quoted 6 lines
I think
it'd be better putting all dynamic events in a single directory - e.g. $tracefs/events/probe/. Any events lack group name are created in the directory. Any events have group name create subdirectories as group name under the directory. The perf tools (and others too) should be changed to lookup the directory after the usual location.
That will be possible, but includes a big change on event namespace, e.g. how we'll show the events by perf-list? Even if we can avoid namespace conflict on tracefs, perf-list event namespace is still fragile.
Quoted 1 line
What do you think?
I think there are 2 purposes of probe-event, one is just additional debug points, another is an extensible event-set. The former will not any namespace problem, we just add it into new namespace. But latter requires to be treated as a part of existing (in-kernel) events. And (userspace)SDT is clearly the latter one.
However, avoiding the conflict of namespace is also important, how about simply using sdt_<PROVIDER>:<NAME> ?
- Give just a name on a userspace binary
perf probe -x <BIN> --add <NAME>=<PROBEDEF>
-> probe_<BIN>:<NAME>
- Give a pair of group and name on a userspace binary perf probe -x <BIN> --add <GRP>:<NAME>=<PROBEDEF> -> probe_<GRP>:<NAME>
- Set an sdt event on a userspace binary
perf probe -x <BIN> --add %<PROV>:<NAME> # or %sdt_<PROV> ?
-> sdt_<PROV>:<NAME>
- Set an cached event on a userspace binary
perf probe -x <BIN> --add %<GRP>:<NAME> # or %probe_<GRP> ?
-> probe_<GRP>:<NAME>
Thank you,
Quoted 72 lines
Quoted 12 lines
Signed-off-by Masami Hiramatsu <[email protected]>--- tools/perf/util/probe-event.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-)tools/perf/util/probe-event.c +0
-0tools/perf/util/probe-event.c static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) · line 1144
Quoted 8 lines
tools/perf/util/probe-event.c +1
-4@@ -1141,10 +1141,8 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)bool file_spec = false;/* * <Syntax> -* perf probe [EVENT=]SRC[:LN|;PTN] -* perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] -* -* TODO:Group name support +* perf probe [GRP:][EVENT=]SRC[:LN|;PTN] Shouldn't it be
[[GRP:]EVENT=]?
tools/perf/util/probe-event.c static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) · line 1145
Quoted 1 line
tools/perf/util/probe-event.c +1
-0+* perf probe [GRP:][EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] Ditto.
Thanks,
NamhyungQuoted 37 lines
tools/perf/util/probe-event.c +12
-5*/ if (!arg)return -EINVAL ;@@ -1153,11 +1151,19 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)if (ptr && *ptr =='=' ) {/* Event name */ *ptr ='\0' ; tmp = ptr +1 ; -if (strchr (arg,':' )) { -semantic_error ("Group name is not supported yet.\n" ); -return -ENOTSUP ; - } + ptr =strchr (arg,':' ); +if (ptr) { + *ptr ='\0' ; +if (!is_c_func_name (arg)) + goto not_fname; + pev->group =strdup (arg); +if (!pev->group) +return -ENOMEM ; + arg = ptr +1 ; + }else + pev->group =NULL ;if (!is_c_func_name (arg)) { +not_fname:semantic_error ("%s is bad for event name -it must " "follow C symbol-naming rule.\n" , arg);return -EINVAL ;@@ -1165,7 +1171,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) pev->event =strdup (arg);if (pev->event ==NULL )return -ENOMEM ; - pev->group =NULL ; arg = tmp; }
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 14/16] perf probe: Add group name support
Quoted 9 lines · Masami Hiramatsu
Quoted 8 lines · Namhyung Kim
Quoted 6 lines · Masami Hiramatsu
Allow user to set group name for adding new event. Note that this can easily shot yourself in the foot. E.g. Existing group name can conflict with other events. Especially, using the group name reserved for kernel modules can break something when loading/unloading modules.
Quoted 4 lines
Quoted 2 lines
Yes, I agree that this can be dangerous. How about enforcing [ku]probes to make the directory of dynamic events safely?
What the safety issue would you afraid?
As you said, I worried that an arbitrary group/event names can clash with another module's group/event names.
Quoted 8 lines
Quoted 7 lines
I think
it'd be better putting all dynamic events in a single directory - e.g. $tracefs/events/probe/. Any events lack group name are created in the directory. Any events have group name create subdirectories as group name under the directory. The perf tools (and others too) should be changed to lookup the directory after the usual location.
Quoted 4 lines
That will be possible, but includes a big change on event namespace, e.g. how we'll show the events by perf-list? Even if we can avoid namespace conflict on tracefs, perf-list event namespace is still fragile.
Yes, it's a big change. And I think we can easily fix perf-list to handle the new event namespace. But other tools/scripts will break.
Quoted 12 lines
Quoted 2 lines
What do you think?
I think there are 2 purposes of probe-event, one is just additional debug points, another is an extensible event-set. The former will not any namespace problem, we just add it into new namespace. But latter requires to be treated as a part of existing (in-kernel) events. And (userspace)SDT is clearly the latter one.
However, avoiding the conflict of namespace is also important, how about simply using sdt_<PROVIDER>:<NAME> ?
Quoted 12 lines
- Give just a name on a userspace binary
perf probe -x <BIN> --add <NAME>=<PROBEDEF>
-> probe_<BIN>:<NAME>
- Give a pair of group and name on a userspace binary perf probe -x <BIN> --add <GRP>:<NAME>=<PROBEDEF> -> probe_<GRP>:<NAME>
- Set an sdt event on a userspace binary
perf probe -x <BIN> --add %<PROV>:<NAME> # or %sdt_<PROV> ?
-> sdt_<PROV>:<NAME>
- Set an cached event on a userspace binary
perf probe -x <BIN> --add %<GRP>:<NAME> # or %probe_<GRP> ?
-> probe_<GRP>:<NAME>
I think this is good for perf. It seems same problem still exists when users access tracefs directly though.
Thanks,
Namhyung
RFC PATCH v2 15/16 perf buildid-cache: Scan and import user SDT events to probe cache
In reply to Masami Hiramatsuperf buildid-cache --add <binary> scans given binary and add the SDT events to probe cache. It is possible to use the cached SDT events as other cached events (perf probe <provider>:<event>=<event>).
e.g.
----
# perf buildid-cache --add /lib/libc-2.17.so
# perf probe --cache --list | head -n 5
/usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392):
libc:setjmp=setjmp
libc:longjmp=longjmp
libc:longjmp_target=longjmp_target
libc:memory_heap_new=memory_heap_new
# perf probe -x /usr/lib/libc-2.17.so \
-a libc:memory_heap_new=memory_heap_new
Added new event:
libc:memory_heap_new (on memory_heap_new
in /usr/lib/libc-2.17.so)You can now use it in all perf tools, such as:
perf record -e libc:memory_heap_new -aR sleep 1
# perf probe -l
libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so)
----Note that SDT event entries in probe-cache file is somewhat different from normal cached events. Normal one starts with "#", but SDTs are starting with "%".
--- tools/perf/util/build-id.c | 27 ++++++++++++++++-- tools/perf/util/probe-file.c | 64 ++++++++++++++++++++++++++++++++++++++++-- tools/perf/util/probe-file.h | 2 + 3 files changed, 87 insertions(+), 6 deletions(-)
tools/perf/util/build-id.c +24 -3
@@ -17,6 +17,7 @@#include "tool.h" #include "header.h" #include "vdso.h" +#include "probe-file.h" static bool no_buildid_cache;
@@ -432,6 +433,23 @@ int build_id_cache__list_build_ids(const char *pathname,return ret; } +#ifdef CONFIG_LIBELF +static void build_id_cache__add_sdt_cache (const char *sbuild_id, +const char *realname) +{ +struct probe_cache *cache; + + cache =probe_cache__new (sbuild_id); +if (!cache) +return ; +if (probe_cache__scan_sdt (cache, realname) >=0 ) +probe_cache__commit (cache); +probe_cache__delete (cache); +} +#else +#define build_id_cache__add_sdt_cache (sbuild_id, realname) do { } while (0) +#endif +int build_id_cache__add_s (const char *sbuild_id,const char *name,bool is_kallsyms,bool is_vdso) {
@@ -470,20 +488,23 @@ int build_id_cache__add_s(const char *sbuild_id, const char *name, goto out_free; } +/* Make a symbolic link */ if (!build_id_cache__linkname (sbuild_id, linkname, size)) goto out_free; + tmp =strrchr (linkname,'/' ); *tmp ='\0' ; -if (access (linkname,X_OK ) &&mkdir_p (linkname,0755 )) goto out_free; - *tmp ='/' ; tmp = dir_name +strlen (buildid_dir) -5 ;memcpy (tmp,"../.." ,5 ); -if (symlink (tmp, linkname) ==0 ) err =0 ; + +/* Update SDT cache */ +build_id_cache__add_sdt_cache (sbuild_id, realname); + out_free:if (!is_kallsyms)free (realname);
tools/perf/util/probe-file.c +61 -3
84 lines not on this page · raw message
tools/perf/util/probe-file.h +2 -0
@@ -18,6 +18,7 @@ int probe_file__del_events(int fd, struct strfilter *filter);/* Cache of probe definitions */ struct probe_cache_entry {struct list_head list; +bool sdt;struct perf_probe_event pev;char *spev;struct strlist *tevlist;
@@ -32,6 +33,7 @@ struct probe_cache *probe_cache__new(const char *target);int probe_cache__add_entry (struct probe_cache *pcache,struct perf_probe_event *pev,struct probe_trace_event *tevs,int ntevs); +int probe_cache__scan_sdt (struct probe_cache *pcache,const char *pathname);int probe_cache__commit (struct probe_cache *pcache);void probe_cache__delete (struct probe_cache *pcache); int probe_cache__remove_entries(struct probe_cache *pcache,
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 15/16] perf buildid-cache: Scan and import user SDT events to probe cache
Quoted 3 lines · Masami Hiramatsu
perf buildid-cache --add <binary> scans given binary and add the SDT events to probe cache. It is possible to use the cached SDT events as other cached events (perf probe <provider>:<event>=<event>).
That means lookup the cached SDT events only using event name, right? What if same event names are used by more than one providers?
Quoted 10 lines
e.g.
----# perf buildid-cache --add /lib/libc-2.17.so # perf probe --cache --list | head -n 5 /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new
I expected something like this instead..
libc:memory_heap_new=new_heap+183
Thanks,
Namhyung
Quoted 19 lines
# perf probe -x /usr/lib/libc-2.17.so \ -a libc:memory_heap_new=memory_heap_new Added new event: libc:memory_heap_new (on memory_heap_new in /usr/lib/libc-2.17.so)You can now use it in all perf tools, such as:
perf record -e libc:memory_heap_new -aR sleep 1
# perf probe -l libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so) ----Note that SDT event entries in probe-cache file is somewhat different from normal cached events. Normal one starts with "#", but SDTs are starting with "%".
Signed-off-by Masami Hiramatsu <[email protected]>
Re: [RFC PATCH perf/core v2 15/16] perf buildid-cache: Scan and import user SDT events to probe cache
Quoted 6 lines · Namhyung Kim
Quoted 3 lines · Masami Hiramatsu
perf buildid-cache --add <binary> scans given binary and add the SDT events to probe cache. It is possible to use the cached SDT events as other cached events (perf probe <provider>:<event>=<event>).
That means lookup the cached SDT events only using event name, right?
Right,
Quoted 1 line
What if same event names are used by more than one providers?
That's a good discussion point :)
What I'm thinking is that the real SDT is always prior to other cached events. (currently not implemented yet)
- if someone gives a same event name, it overwrites previous one.
- if someone gives an event name same as existing SDT, it is not cached (or rejected)
- if SDT scanned after cached same name events, SDT always overwrites the entry.
So, the all SDT events will be treated as fixed events.
Note that this will be happen if we agree SDT and probe share the same namespace :)
Quoted 11 lines
Quoted 10 lines
e.g.
----# perf buildid-cache --add /lib/libc-2.17.so # perf probe --cache --list | head -n 5 /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new
Quoted 3 lines
I expected something like this instead..
libc:memory_heap_new=new_heap+183
OK, that's much better :)
Quoted 26 lines
Thanks,
NamhyungQuoted 19 lines
# perf probe -x /usr/lib/libc-2.17.so \ -a libc:memory_heap_new=memory_heap_new Added new event: libc:memory_heap_new (on memory_heap_new in /usr/lib/libc-2.17.so)You can now use it in all perf tools, such as:
perf record -e libc:memory_heap_new -aR sleep 1
# perf probe -l libc:memory_heap_new (on new_heap+183 in /usr/lib/libc-2.17.so) ----Note that SDT event entries in probe-cache file is somewhat different from normal cached events. Normal one starts with "#", but SDTs are starting with "%".
Signed-off-by Masami Hiramatsu <[email protected]>
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 15/16] perf buildid-cache: Scan and import user SDT events to probe cache
Quoted 14 lines · Masami Hiramatsu
Quoted 6 lines · Namhyung Kim
Quoted 3 lines · Masami Hiramatsu
perf buildid-cache --add <binary> scans given binary and add the SDT events to probe cache. It is possible to use the cached SDT events as other cached events (perf probe <provider>:<event>=<event>).
That means lookup the cached SDT events only using event name, right?
Right,
Quoted 1 line
What if same event names are used by more than one providers?
That's a good discussion point :)
Quoted 7 lines
What I'm thinking is that the real SDT is always prior to other cached events. (currently not implemented yet)
- if someone gives a same event name, it overwrites previous one.
- if someone gives an event name same as existing SDT, it is not cached (or rejected)
- if SDT scanned after cached same name events, SDT always overwrites the entry.
I'm thinking about allowing same name for different events. IMHO it's possible to have same SDT names for some reason - i.e. having multiple versions of same program, similar (but different) binaries have same event names, or even in a single bianry it might have same event names but different provider names.
In that case, I think perf probe (or record) simply can do the job for every matching events.
Quoted 5 lines
So, the all SDT events will be treated as fixed events.
Note that this will be happen if we agree SDT and probe share the same namespace :)
Right.
Thanks,
Namhyung
Re: [RFC PATCH perf/core v2 15/16] perf buildid-cache: Scan and import user SDT events to probe cache
Quoted 23 lines · Namhyung Kim
Quoted 14 lines · Masami Hiramatsu
Quoted 6 lines · Namhyung Kim
Quoted 3 lines · Masami Hiramatsu
perf buildid-cache --add <binary> scans given binary and add the SDT events to probe cache. It is possible to use the cached SDT events as other cached events (perf probe <provider>:<event>=<event>).
That means lookup the cached SDT events only using event name, right?
Right,
Quoted 1 line
What if same event names are used by more than one providers?
That's a good discussion point :)
Quoted 7 lines
What I'm thinking is that the real SDT is always prior to other cached events. (currently not implemented yet)
- if someone gives a same event name, it overwrites previous one.
- if someone gives an event name same as existing SDT, it is not cached (or rejected)
- if SDT scanned after cached same name events, SDT always overwrites the entry.
Quoted 8 lines
I'm thinking about allowing same name for different events. IMHO it's possible to have same SDT names for some reason - i.e. having multiple versions of same program, similar (but different) binaries have same event names, or even in a single bianry it might have same event names but different provider names.
In that case, I think perf probe (or record) simply can do the job for every matching events.
Hmm, right. If we support the 3-level event name as you said, that can make things much simpler. We can use "probe_<12chars-buildid>" for the toplevel dirname, and "provider/name" for lower 2 levels.
Or, if we can use <provider>.<buildid>/ for the group name (this requres kernel change) it is more easier to support SDTs.
Thank you,
Quoted 13 lines
Quoted 6 lines
So, the all SDT events will be treated as fixed events.
Note that this will be happen if we agree SDT and probe share the same namespace :)
Right.
Thanks,
Namhyung
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
RFC PATCH v2 16/16 perf probe: Accept %sdt and %cached event name
In reply to Masami HiramatsuTo 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:
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 libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more
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 | 3 + tools/perf/util/probe-event.c | 78 ++++++++++++++++++++++--------- tools/perf/util/probe-event.h | 1 tools/perf/util/probe-file.c | 9 ++++ 4 files changed, 69 insertions(+), 22 deletions(-)
tools/perf/Documentation/perf-probe.txt +3 -0
@@ -151,11 +151,14 @@ Probe points are defined by following syntax. 3) Define event based on source file with lazy pattern [EVENT=]SRC;PTN [ARG ...] + 4) Pre-defined SDT events + %[PROVIDER:]SDTEVENT 'EVENT' specifies the name of new event, if omitted, it will be set the name of the probed function. Currently, event group name is set as 'probe'. '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. PROBE ARGUMENT --------------
tools/perf/util/probe-event.c +56 -22
114 lines not on this page · raw message
tools/perf/util/probe-event.h +1 -0
@@ -84,6 +84,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
@@ -504,6 +504,15 @@ probe_cache__find(struct probe_cache *pcache, struct perf_probe_event *pev)return NULL ;list_for_each_entry (entry, &pcache->list, list) { +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) &&
Namhyung Kim
maintainerRe: [RFC PATCH perf/core v2 16/16] perf probe: Accept %sdt and %cached event name
Quoted 2 lines · Masami Hiramatsu
To improbe usability, support %[PROVIDER:]SDTEVENT format to add new probes on SDT and cached events.
Ah, you meant we can skip the provider if the event name is unique..
Quoted 4 lines
e.g.
----# perf probe -x /lib/libc-2.17.so %lll_lock_wait_private
Maybe we can also skip the target path (-x) too in this case.
Thanks,
Namhyung
Quoted 26 lines
Added new event:
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 libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more libc:lll_lock_wait_private (on __lll_lock_wait_private+21 in /usr/lib/libc-2.17.so) ----Note that this is not only for SDT events, but also normal events with event-name.
e.g. define "myevent" on cache (-n doesn't add the real probe)
----# perf probe -x ./perf --cache -n --add 'myevent=dso__load $params' ---- Reuse the "myevent" from cache as below. ---- # perf probe -x ./perf %myevent ----Signed-off-by Masami Hiramatsu <[email protected]>
Re: Re: [RFC PATCH perf/core v2 16/16] perf probe: Accept %sdt and %cached event name
Quoted 5 lines · Namhyung Kim
Quoted 2 lines · Masami Hiramatsu
To improbe usability, support %[PROVIDER:]SDTEVENT format to add new probes on SDT and cached events.
Ah, you meant we can skip the provider if the event name is unique..
Right, that's easier for users.
Quoted 6 lines
Quoted 4 lines
e.g.
----# perf probe -x /lib/libc-2.17.so %lll_lock_wait_privateMaybe we can also skip the target path (-x) too in this case.
Agreed. For that feature, we need to improve buildid-cache to get all valid buildid caches (this means that it has to verify all the cached binaries' buildid). Anyway, the same feature is required for showing available cached probe-events on perf-list.
Thank you,
Quoted 37 lines
Thanks,
NamhyungQuoted 18 lines
Added new event:
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 libc:lll_lock_wait_private -aR sleep 1
# perf probe -l | more 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)
----Quoted 8 lines
# perf probe -x ./perf --cache -n --add 'myevent=dso__load $params' ---- Reuse the "myevent" from cache as below. ---- # perf probe -x ./perf %myevent ----Signed-off-by Masami Hiramatsu <[email protected]>--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Hi Masami,
Quoted 4 lines · Masami Hiramatsu
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Thanks for adding the SDT support.
Quoted 60 lines
The perf-probe is useful for debugging, but it strongly depends on the debuginfo. Without debuginfo, it is just a frontend of ftrace's dynamic events. This can usually happen in server farms or on cloud system, since no one wants to distribute big debuginfo packages.
To solve this issue, I had tried to make a pre-analyzed probes ( https://lkml.org/lkml/2014/10/31/207 ) but it has a problm that we can't ensure the probed binary is same as what we analyzed. Arnaldo gave me an idea to reuse build-id cache for that perpose and this series is the first prototype of that.
At the same time, Hemant has started to support SDT probes which also use the cache file of SDT info. So I decided to merge this into the same build-id cache.
In this version, SDT support is still very limited, it works as a part of probe-cache.In this version, perf probe supports --cache option which means that perf probe manipulate probe caches, for example,
# perf probe --cache --add "probe-desc"does not only add probe events but also add "probe-desc" and it's result on the cache. (Note that the cached entry is always referred even without --cache)
The --list and --del commands also support --cache. Note that both are only manipulate caches, not real events.To use SDT, we have to scan the target binary at first by using perf-buildid-cache, e.g.
# perf buildid-cache --add /lib/libc-2.17.soAnd perf probe --cache --list shows what SDTs are scanned.
# perf probe --cache --list /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new libc:memory_sbrk_less=memory_sbrk_less libc:memory_arena_reuse_free_list=memory_arena_reuse_free_list libc:memory_arena_reuse=memory_arena_reuse ...To use the SDT events, perf probe -x BIN %SDTEVENT allows you to add a probe on SDTEVENT@BIN.
# perf probe -x /lib/libc-2.17.so %memory_heap_newIf you define a cached probe with event name, you can also reuse it as same as SDT events.
# perf probe -x ./perf --cache -n 'myevent=dso__load $params'(Note that "-n" option only updates caches)
To use the above "myevent", you just have to add "%myevent".
Quoted 6 lines
# perf probe -x ./perf %myeventTODOs:
- Show available cached/SDT events by perf-list
- Allow perf-record to use cached/SDT events directly
As I was already working on SDT events' recording
https://lkml.org/lkml/2014/11/2/73,
I can re-spin the patches on top of your patchset and make the required changes to implement the above TODOs.
What would you suggest?
Quoted 48 lines
Thank you,
---
Hemant Kumar (1):
perf/sdt: ELF support for SDTMasami Hiramatsu (15):
perf probe: Simplify__add_probe_trace_eventscode
perf probe: Move ftrace probe-event operations toprobe-file.cperf probe: Use strbuf for making strings inprobe-event.c
perf-buildid-cache: Use path/to/bin/buildid/elf instead of path/to/bin/buildid perf buildid: UseSBUILD_ID_SIZEmacro
perf buildid: Introduce sysfs/filename__sprintf_build_id
perf: Add lsdir to read a directory
perf-buildid-cache: Use lsdir for looking up buildid caches
perf probe: Add --cache option to cache the probe definitions perf probe: Use cache entry if possible
perf probe: Show all cached probes
perf probe: Remove caches when --cache is given
perf probe: Add group name support
perf buildid-cache: Scan and import user SDT events to probe cache perf probe: Accept %sdt and %cached event nametools/perf/Documentation/perf-probe.txt | 14 tools/perf/builtin-buildid-cache.c | 22 - tools/perf/builtin-buildid-list.c | 28 - tools/perf/builtin-probe.c | 3 tools/perf/util/Build | 1 tools/perf/util/build-id.c | 230 ++++++-- tools/perf/util/build-id.h | 11 tools/perf/util/dso.h | 5 tools/perf/util/probe-event.c | 918 ++++++++++++++----------------- tools/perf/util/probe-event.h | 16 - tools/perf/util/probe-file.c | 763 ++++++++++++++++++++++++++ tools/perf/util/probe-file.h | 46 ++ tools/perf/util/probe-finder.c | 10 tools/perf/util/symbol-elf.c | 252 +++++++++ tools/perf/util/symbol.c | 2 tools/perf/util/symbol.h | 22 + tools/perf/util/util.c | 34 + tools/perf/util/util.h | 4 18 files changed, 1781 insertions(+), 600 deletions(-)create mode 100644
tools/perf/util/probe-file.c
create mode 100644tools/perf/util/probe-file.h
Signature · 2 lines
Thanks, Hemant Kumar
Hi Hemant,
Quoted 73 lines · Hemant Kumar
Hi Masami,
Quoted 4 lines · Masami Hiramatsu
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Thanks for adding the SDT support.
Quoted 63 lines
The perf-probe is useful for debugging, but it strongly depends on the debuginfo. Without debuginfo, it is just a frontend of ftrace's dynamic events. This can usually happen in server farms or on cloud system, since no one wants to distribute big debuginfo packages.
To solve this issue, I had tried to make a pre-analyzed probes ( https://lkml.org/lkml/2014/10/31/207 ) but it has a problm that we can't ensure the probed binary is same as what we analyzed. Arnaldo gave me an idea to reuse build-id cache for that perpose and this series is the first prototype of that.
At the same time, Hemant has started to support SDT probes which also use the cache file of SDT info. So I decided to merge this into the same build-id cache.
In this version, SDT support is still very limited, it works as a part of probe-cache.In this version, perf probe supports --cache option which means that perf probe manipulate probe caches, for example,
# perf probe --cache --add "probe-desc"does not only add probe events but also add "probe-desc" and it's result on the cache. (Note that the cached entry is always referred even without --cache)
The --list and --del commands also support --cache. Note that both are only manipulate caches, not real events.To use SDT, we have to scan the target binary at first by using perf-buildid-cache, e.g.
# perf buildid-cache --add /lib/libc-2.17.soAnd perf probe --cache --list shows what SDTs are scanned.
# perf probe --cache --list /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new libc:memory_sbrk_less=memory_sbrk_less libc:memory_arena_reuse_free_list=memory_arena_reuse_free_list libc:memory_arena_reuse=memory_arena_reuse ...To use the SDT events, perf probe -x BIN %SDTEVENT allows you to add a probe on SDTEVENT@BIN.
# perf probe -x /lib/libc-2.17.so %memory_heap_newIf you define a cached probe with event name, you can also reuse it as same as SDT events.
# perf probe -x ./perf --cache -n 'myevent=dso__load $params'(Note that "-n" option only updates caches)
To use the above "myevent", you just have to add "%myevent".# perf probe -x ./perf %myevent
Quoted 8 lines
Quoted 3 lines
TODOs:
- Show available cached/SDT events by perf-list
- Allow perf-record to use cached/SDT events directlyAs I was already working on SDT events' recording
https://lkml.org/lkml/2014/11/2/73,
I can re-spin the patches on top of your patchset and make the required changes to implement the above TODOs.
Sounds great! :)
Note that you'll need to re-implement almost from scratch, since now the SDT is implemented on buildid-cache. Maybe I have to work on the buildid-cache one more to filter out binaries which are gone or different version from current running one (e.g. old vmlinux). It could help you to get available SDTs when showing it via perf-list.
Quoted 1 line
What would you suggest?
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
In this series I've introduced %event syntax only to recall cached event setting explicitly, because perf-probe is a lower layer tool to set up new event. IMO, perf-list and perf-record should be higher tools which handle abstract events.
Thanks!
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Namhyung Kim
maintainerHi Masami,
Quoted 7 lines · Masami Hiramatsu
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
I don't remember how the SDT events should be shown to users. Sorry if I'm missing something here.
AFAIK an SDT event consists of a provider and an event name. So it can be simply 'provider:event' like tracepoints or 'binary:provider_event' like uprobes.
I like the former because it's simpler but it needs to guarantee that it doesn't clash with existing tracepoints/[ku]probes. So IIUC we chose the '%' sign to distinguish them. But after setting a probe at it, the group name should be the binary name. So the whole event name might be changed, and this is not good.
So we should use the latter form. But in this case, I think we need a way to distinguish provider and event names. Since the provider name also can include '_' characters in it. And maybe it still needs to distinguish an SDT event and its probe for some reason. In that case, we might use 'sdt:provider_event' form or something like that.
Thanks,
Namhyung
Quoted 5 lines
In this series I've introduced %event syntax only to recall cached event setting explicitly, because perf-probe is a lower layer tool to set up new event. IMO, perf-list and perf-record should be higher tools which handle abstract events.
G'Day Masami-san, Namhyung,
I'm really looking forward to this feature -- very useful, thanks!...
Quoted 18 lines · Namhyung Kim
Hi Masami,
Quoted 7 lines · Masami Hiramatsu
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
I don't remember how the SDT events should be shown to users. Sorry if I'm missing something here.
AFAIK an SDT event consists of a provider and an event name. So it can be simply 'provider:event' like tracepoints or 'binary:provider_event' like uprobes.
Quoted 5 lines
I like the former because it's simpler but it needs to guarantee that it doesn't clash with existing tracepoints/[ku]probes. So IIUC we chose the '%' sign to distinguish them. But after setting a probe at it, the group name should be the binary name. So the whole event name might be changed, and this is not good.
I don't think we should worry about the clash, as the provider name should differentiate. So I think "libfoo:bar" with perf record is better. After adding them to the cache (via % if needed), I'd think they would be best looking like tracepoints. Eg, listing them together they can be differentiated, something like:
# perf list [...] block:block_rq_abort [Tracepoint event] block:block_rq_requeue [Tracepoint event] block:block_rq_complete [Tracepoint event] [...] libc:memory_heap_new [User tracepoint event] libc:memory_heap_free [User tracepoint event] libc:memory_heap_more [User tracepoint event] [...]
Then used the same.
Brendan
Namhyung Kim
maintainerHi Brendan,
Quoted 23 lines · Brendan Gregg
G'Day Masami-san, Namhyung,
I'm really looking forward to this feature -- very useful, thanks!...
Quoted 18 lines · Namhyung Kim
Hi Masami,
Quoted 7 lines · Masami Hiramatsu
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
I don't remember how the SDT events should be shown to users. Sorry if I'm missing something here.
AFAIK an SDT event consists of a provider and an event name. So it can be simply 'provider:event' like tracepoints or 'binary:provider_event' like uprobes.
Quoted 8 lines
Quoted 5 lines
I like the former because it's simpler but it needs to guarantee that it doesn't clash with existing tracepoints/[ku]probes. So IIUC we chose the '%' sign to distinguish them. But after setting a probe at it, the group name should be the binary name. So the whole event name might be changed, and this is not good.
I don't think we should worry about the clash, as the provider name should differentiate.
But there's no guarantee. Maybe an userspace tool which deals with a kernel module has SDT names as same as the kernel module's tracepoint names. It might or might not be a problem if we can handle those duplicate names somehow.
Quoted 16 lines
So I think "libfoo:bar" with perf record is
better. After adding them to the cache (via % if needed), I'd think they would be best looking like tracepoints. Eg, listing them together they can be differentiated, something like:# perf list [...] block:block_rq_abort [Tracepoint event] block:block_rq_requeue [Tracepoint event] block:block_rq_complete [Tracepoint event] [...] libc:memory_heap_new [User tracepoint event] libc:memory_heap_free [User tracepoint event] libc:memory_heap_more [User tracepoint event] [...]
Quoted 1 line
Then used the same.
Yes, as I said I also prefer this simpler form. Maybe we can choose to use another names for low-level plumbing inside the perf tools, but I still think that users should be able to use simple names like above.
Thanks,
Namhyung
Quoted 32 lines · Namhyung Kim
Hi Brendan,
Quoted 29 lines · Brendan Gregg
G'Day Masami-san, Namhyung,
I'm really looking forward to this feature -- very useful, thanks!...
Quoted 23 lines · Namhyung Kim
Hi Masami,
Quoted 7 lines · Masami Hiramatsu
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
I don't remember how the SDT events should be shown to users. Sorry if I'm missing something here.
AFAIK an SDT event consists of a provider and an event name. So it can be simply 'provider:event' like tracepoints or 'binary:provider_event' like uprobes.
I like the former because it's simpler but it needs to guarantee that it doesn't clash with existing tracepoints/[ku]probes. So IIUC we chose the '%' sign to distinguish them. But after setting a probe at it, the group name should be the binary name. So the whole event name might be changed, and this is not good.
Quoted 7 lines
Quoted 2 lines
I don't think we should worry about the clash, as the provider name should differentiate.
But there's no guarantee. Maybe an userspace tool which deals with a kernel module has SDT names as same as the kernel module's tracepoint names. It might or might not be a problem if we can handle those duplicate names somehow.
I'd like to suggest to choose the behavior on scanning SDT. Since the perf-probe just relays on what the event names are stored on the cache file, we can choose "sdt_" prefix or not when scanning the SDT.
If the name is already used by the kernel tracepoint, we can add sdt_ prefix or some sort of suffix.
Thank you,
Quoted 21 lines
Quoted 16 lines
So I think "libfoo:bar" with perf record is
better. After adding them to the cache (via % if needed), I'd think they would be best looking like tracepoints. Eg, listing them together they can be differentiated, something like:# perf list [...] block:block_rq_abort [Tracepoint event] block:block_rq_requeue [Tracepoint event] block:block_rq_complete [Tracepoint event] [...] libc:memory_heap_new [User tracepoint event] libc:memory_heap_free [User tracepoint event] libc:memory_heap_more [User tracepoint event] [...]Quoted 1 line
Then used the same.
Yes, as I said I also prefer this simpler form. Maybe we can choose to use another names for low-level plumbing inside the perf tools, but I still think that users should be able to use simple names like above.
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Hi Masami,
Apologies for the delayed response.
Quoted 82 lines · Masami Hiramatsu
Hi Hemant,
Quoted 72 lines · Hemant Kumar
Hi Masami,
Quoted 4 lines · Masami Hiramatsu
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Thanks for adding the SDT support.
Quoted 63 lines
The perf-probe is useful for debugging, but it strongly depends on the debuginfo. Without debuginfo, it is just a frontend of ftrace's dynamic events. This can usually happen in server farms or on cloud system, since no one wants to distribute big debuginfo packages.
To solve this issue, I had tried to make a pre-analyzed probes ( https://lkml.org/lkml/2014/10/31/207 ) but it has a problm that we can't ensure the probed binary is same as what we analyzed. Arnaldo gave me an idea to reuse build-id cache for that perpose and this series is the first prototype of that.
At the same time, Hemant has started to support SDT probes which also use the cache file of SDT info. So I decided to merge this into the same build-id cache.
In this version, SDT support is still very limited, it works as a part of probe-cache.In this version, perf probe supports --cache option which means that perf probe manipulate probe caches, for example,
# perf probe --cache --add "probe-desc"does not only add probe events but also add "probe-desc" and it's result on the cache. (Note that the cached entry is always referred even without --cache)
The --list and --del commands also support --cache. Note that both are only manipulate caches, not real events.To use SDT, we have to scan the target binary at first by using perf-buildid-cache, e.g.
# perf buildid-cache --add /lib/libc-2.17.soAnd perf probe --cache --list shows what SDTs are scanned.
# perf probe --cache --list /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new libc:memory_sbrk_less=memory_sbrk_less libc:memory_arena_reuse_free_list=memory_arena_reuse_free_list libc:memory_arena_reuse=memory_arena_reuse ...To use the SDT events, perf probe -x BIN %SDTEVENT allows you to add a probe on SDTEVENT@BIN.
# perf probe -x /lib/libc-2.17.so %memory_heap_newIf you define a cached probe with event name, you can also reuse it as same as SDT events.
# perf probe -x ./perf --cache -n 'myevent=dso__load $params'(Note that "-n" option only updates caches)
To use the above "myevent", you just have to add "%myevent".# perf probe -x ./perf %myeventQuoted 7 lines
Quoted 3 lines
TODOs:
- Show available cached/SDT events by perf-list
- Allow perf-record to use cached/SDT events directlyAs I was already working on SDT events' recording
https://lkml.org/lkml/2014/11/2/73,
I can re-spin the patches on top of your patchset and make the required changes to implement the above TODOs.
Quoted 6 lines
Sounds great! :)
Note that you'll need to re-implement almost from scratch, since now the SDT is implemented on buildid-cache. Maybe I have to work on the buildid-cache one more to filter out binaries which are gone or different version from current running one (e.g. old vmlinux). It could help you to get available SDTs when showing it via perf-list.
Sure. That would be great.
Quoted 8 lines
Quoted 1 line
What would you suggest?
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
Although I agree to have "perf record" as a higher level tool and not bother this tool to distinguish between its events, but that way we end up looking into kprobe_events, uprobe_events, kernel tracepoints and then the entire cache for any event (which may or may not be an SDT event or even a valid event) lookup. Right?
The idea behind '%' was to identify the SDT events and take a different path to lookup through the cache, put a probe, record and then delete the probe. Or, do you want "perf record" to record any event this way (not just an sdt event).
Please correct me if I missed something.
Quoted 8 lines
In this series I've introduced %event syntax only to recall cached event setting explicitly, because perf-probe is a lower layer tool to set up new event. IMO, perf-list and perf-record should be higher tools which handle abstract events.
Thanks!
Signature · 2 lines
Thanks, Hemant Kumar
Quoted 105 lines · Hemant Kumar
Hi Masami,
Apologies for the delayed response.
Quoted 82 lines · Masami Hiramatsu
Hi Hemant,
Quoted 72 lines · Hemant Kumar
Hi Masami,
Quoted 4 lines · Masami Hiramatsu
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Thanks for adding the SDT support.
Quoted 63 lines
The perf-probe is useful for debugging, but it strongly depends on the debuginfo. Without debuginfo, it is just a frontend of ftrace's dynamic events. This can usually happen in server farms or on cloud system, since no one wants to distribute big debuginfo packages.
To solve this issue, I had tried to make a pre-analyzed probes ( https://lkml.org/lkml/2014/10/31/207 ) but it has a problm that we can't ensure the probed binary is same as what we analyzed. Arnaldo gave me an idea to reuse build-id cache for that perpose and this series is the first prototype of that.
At the same time, Hemant has started to support SDT probes which also use the cache file of SDT info. So I decided to merge this into the same build-id cache.
In this version, SDT support is still very limited, it works as a part of probe-cache.In this version, perf probe supports --cache option which means that perf probe manipulate probe caches, for example,
# perf probe --cache --add "probe-desc"does not only add probe events but also add "probe-desc" and it's result on the cache. (Note that the cached entry is always referred even without --cache)
The --list and --del commands also support --cache. Note that both are only manipulate caches, not real events.To use SDT, we have to scan the target binary at first by using perf-buildid-cache, e.g.
# perf buildid-cache --add /lib/libc-2.17.soAnd perf probe --cache --list shows what SDTs are scanned.
# perf probe --cache --list /usr/lib/libc-2.17.so (a6fb821bdf53660eb2c29f778757aef294d3d392): libc:setjmp=setjmp libc:longjmp=longjmp libc:longjmp_target=longjmp_target libc:memory_heap_new=memory_heap_new libc:memory_sbrk_less=memory_sbrk_less libc:memory_arena_reuse_free_list=memory_arena_reuse_free_list libc:memory_arena_reuse=memory_arena_reuse ...To use the SDT events, perf probe -x BIN %SDTEVENT allows you to add a probe on SDTEVENT@BIN.
# perf probe -x /lib/libc-2.17.so %memory_heap_newIf you define a cached probe with event name, you can also reuse it as same as SDT events.
# perf probe -x ./perf --cache -n 'myevent=dso__load $params'(Note that "-n" option only updates caches)
To use the above "myevent", you just have to add "%myevent".# perf probe -x ./perf %myeventQuoted 7 lines
Quoted 3 lines
TODOs:
- Show available cached/SDT events by perf-list
- Allow perf-record to use cached/SDT events directlyAs I was already working on SDT events' recording
https://lkml.org/lkml/2014/11/2/73,
I can re-spin the patches on top of your patchset and make the required changes to implement the above TODOs.Quoted 6 lines
Sounds great! :)
Note that you'll need to re-implement almost from scratch, since now the SDT is implemented on buildid-cache. Maybe I have to work on the buildid-cache one more to filter out binaries which are gone or different version from current running one (e.g. old vmlinux). It could help you to get available SDTs when showing it via perf-list.Sure. That would be great.
Quoted 8 lines
Quoted 1 line
What would you suggest?
Now I'm thinking that we should avoid using %event syntax for perf-list and perf-record to avoid confusion. For example, suppose that we have "libfoo:bar" SDT event, when we just scanned the libfoo binary and use it via perf-record, we'll run perf record -e "%libfoo:bar". However, after we set the probe via perf-probe, we have to run perf record -e "libfoo:bar". That difference looks no good. So, I think in both case it should accept -e "libfoo:bar" syntax.
Quoted 5 lines
Although I agree to have "perf record" as a higher level tool and not bother this tool to distinguish between its events, but that way we end up looking into
kprobe_events,uprobe_events, kernel tracepoints and then the entire cache for any event (which may or may not be an SDT event or even a valid event) lookup. Right?
Yeah, right.
Quoted 5 lines
The idea behind '%' was to identify the SDT events and take a different path to lookup through the cache, put a probe, record and then delete the probe. Or, do you want "perf record" to record any event this way (not just an sdt event).
I see, but I think that is not good by following reasons,
- when we record event with "-e %provider:event", it will be shown as "provider:event"
- if perf-list shows the SDT(cached) events as "%provider:event", that will not match the recorded result.
- it is somewhat fragile that we temporary add the SDT event and remove it after record, because the event will not hide from ftrace users (this means that we'll fail removing the event by -EBUSY if someone use it via ftrace)
- if we set SDT events perf-probe, it will be shown as "provider:event" name because "%" will be rejected by ftrace. In that case, what the perf-list show those events, both of %provider:event and provider:event ?
thus I pushed the "%" as a "special remembering mark" only for looking up the event from cache by perf-probe.
So I'd like to suggest that the following behavior
1) perf-list shows the cached-with-name and SDT events as Tracepoint events even if it is not yet probed.
# perf list
List of pre-defined events (to be used in -e):
...
libc:memory_heap_new [Tracepoint event]
...
probes:myevent [Tracepoint event]
...
2) perf-record -e with no-probed event should try to set up the given probe by using perf-probe. It is possible to remove that the probe after recording, but also ignore if it fails by -EBUSY. (anyway, there is no difference for users)
This rule will solve the contradiction between the event name on recorded data and listed events. However, as we discussed there are other clashes.
A) clash among binaries: Since the binary builders can freely use the provider name, it is possible to clash to other binaries' SDTs.
B) clash among different versions: Of course the different versions of binaries can be co-exist on the system. Those usually have the same SDTs and same basename, just different build-ids.
These issues are not solved by using "%" because it happens among SDTs. So we need to find another way to distinguish the SDTs.
Thank you,
Quoted 12 lines
Please correct me if I missed something.
Quoted 8 lines
In this series I've introduced %event syntax only to recall cached event setting explicitly, because perf-probe is a lower layer tool to set up new event. IMO, perf-list and perf-record should be higher tools which handle abstract events.
Thanks!
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Arnaldo Carvalho de Melo
maintainerEm Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
Quoted 10 lines · Hemant Kumar
Quoted 6 lines · Masami Hiramatsu
Quoted 1 line · Hemant Kumar
The idea behind '%' was to identify the SDT events and take a different path to lookup through the cache, put a probe, record and then delete the probe. Or, do you want "perf record" to record any event this way (not just an sdt event).
I see, but I think that is not good by following reasons,
Quoted 8 lines
- when we record event with "-e %provider:event", it will be shown as "provider:event"
- if perf-list shows the SDT(cached) events as "%provider:event", that will not match the recorded result.
- it is somewhat fragile that we temporary add the SDT event and remove it after record, because the event will not hide from ftrace users (this means that we'll fail removing the event by-EBUSYif someone use it via ftrace)
We should avoid that, if we say record event "foo:bar", then we should consistently show "foo:bar" everywhere this is referenced.
Quoted 11 lines
- if we set SDT events perf-probe, it will be shown as "provider:event" name because "%" will be rejected by ftrace. In that case, what the perf-list show those events, both of %provider:event and provider:event ?
thus I pushed the "%" as a "special remembering mark" only for looking up the event from cache by perf-probe.
So I'd like to suggest that the following behavior
1) perf-list shows the cached-with-name and SDT events as Tracepoint events even if it is not yet probed.
I can agree with 'perf list' showing what can be used as events, and SDTs, AFAIK, match that definition, i.e. we have somewhere (in the DSOs, right?) information about where to ask for an event to be enabled.
If there are details on how that needs to be obtained, then passed to the kernel somehow to then become really, really accessible, then these details are completely internal.
Quoted 5 lines
# perf listList of pre-defined events (to be used in -e):
...
libc:memory_heap_new [Tracepoint event]
Is it like this or is it like [ku]probes where we already have a namespace qualifier, i.e.:
[root@zoo ~]# perf probe icmp_rcv
Added new event:
probe:icmp_rcv (on icmp_rcv)
You can now use it in all perf tools, such as:
perf record -e probe:icmp_rcv -aR sleep 1
[root@zoo ~]#
[root@zoo ~]# perf probe /lib64/libc-2.20.so malloc Added new events:
probe_libc:malloc (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_1 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_2 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_3 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_4 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_5 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_6 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_7 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_8 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_9 (on malloc in /lib64/libc-2.20.so)
probe_libc:malloc_10 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_11 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_12 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_13 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_14 (on malloc in /lib64/libc-2.20.so)
You can now use it in all perf tools, such as:
perf record -e probe_libc:malloc_14 -aR sleep 1
[root@zoo ~]#
"probe" for kernel events, "probe_%s" % DSO basename for userspace events.
Why not continue with that and have SDTs use the probe_%s: namespace? Sorry if this was already discussed here...
If there is some ambiguity, that can be resolved by explicitely setting a new name, 'perf probe' has provision for that, right? I.e.:
[root@zoo ~]# perf probe /lib64/libc-2.20.so another_name=malloc Added new events:
<SNIP>
probe_libc:another_name_14 (on malloc in /lib64/libc-2.20.so)
You can now use it in all perf tools, such as:
perf record -e probe_libc:another_name_14 -aR sleep 1
[root@zoo ~]#
Quoted 8 lines
...
probes:myevent [Tracepoint event]
...2) perf-record -e with no-probed event should try to set up the given probe by using perf-probe. It is possible to remove that the probe after recording, but also ignore if it fails by
-EBUSY. (anyway, there is no difference for users)
Right, being able to add new probes _without_ calling 'perf probe', but instead functions used by 'perf probe' is something the eBPF does (I'm almost getting there... :) ) and that I want to do in other tools, like 'trace' as well...
There are permission problems about how to add new probes and how to _enable_ them, i.e. I think it is ok to allow users to ask for probe:foo, if they are monitoring just their workloads...
[root@zoo ~]# perf probe 'vfs_getname=getname_flags:72 pathname=filename:string' Added new event:
probe:vfs_getname (on getname_flags:72 with pathname=filename:string)
You can now use it in all perf tools, such as:
perf record -e probe:vfs_getname -aR sleep 1
[root@zoo ~]#
Then, as !root:
[acme@zoo linux]$ trace cat /etc/passwd
Error: No permissions to read /sys/kernel/debug/tracing/events/raw_syscalls/sys_(enter|exit)
Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug'
By default, !root users can't see debugfs, so, no dice in trying to use the raw_syscalls tracepoints, bummer, then:
[acme@zoo linux]$ sudo mount -o remount,mode=755 /sys/kernel/debug [sudo] password for acme:
[acme@zoo linux]$ trace cat /etc/passwd
Error: No permissions to read /sys/kernel/debug/tracing/events/raw_syscalls/sys_(enter|exit)
Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing'
Ouch, now this tracefs thing inside debugfs, at least sudo doesn't asks me for the password this time!
But then, since 'perf trace' knows there is a probe:vfs_getname syscall in place, it will try to use it, to monitor a workload it is about to start, but:
[acme@zoo linux]$ sudo mount -o remount,mode=755 /sys/kernel/debug/tracing [acme@zoo linux]$ trace cat /etc/passwd
Error: Operation not permitted.
Hint: Check /proc/sys/kernel/perf_event_paranoid setting.
Hint: For system wide tracing it needs to be set to -1.
Hint: Try: 'sudo sh -c "echo -1 > /proc/sys/kernel/perf_event_paranoid"'
Hint: The current value is 1.
[acme@zoo linux]$
This needs refining, i.e. I should just warn that albeit "probe:vfs_getname" is available, it can't be used, unless we open the doors wide.
Sorry for the digression, but these permission issues will hit us with SDT as well, no?
Quoted 5 lines
This rule will solve the contradiction between the event name on recorded data and listed events. However, as we discussed there are other clashes.
A) clash among binaries: Since the binary builders can freely use the provider name, it is possible to clash to other binaries' SDTs.
Yes, one way to disambiguate is to use the buildid, i.e. content based, when/if the need arises. We should _always_ store the build-id, together with any probe used, so that we can bail out when trying to run those with a non matching DSO (kernel, module, library, whatever).
When specifying some SDT that is ambiguous, we should bail out and ask for further namespacing, like:
[acme@zoo linux]$ git show --oneline 25b6
error: short SHA1 25b6 is ambiguous.
error: short SHA1 25b6 is ambiguous.
fatal: ambiguous argument '25b6': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
[acme@zoo linux]$ git show --oneline 25b67
error: short SHA1 25b67 is ambiguous.
error: short SHA1 25b67 is ambiguous.
fatal: ambiguous argument '25b67': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
It can be via build-id or by asking for the full pathname to the DSO, etc.
Quoted 3 lines
B) clash among different versions: Of course the different versions of binaries can be co-exist on the system. Those usually have the same SDTs and same basename, just different build-ids.
Right, in that case the build-id or the full pathname needs to be specified somehow
Quoted 4 lines
These issues are not solved by using "%" because it happens among SDTs. So we need to find another way to distinguish the SDTs.
From what I've read so far (not much): agreed.
- Arnaldo
Quoted 30 lines · Arnaldo Carvalho de Melo
Em Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
Quoted 10 lines · Hemant Kumar
Quoted 6 lines · Masami Hiramatsu
Quoted 1 line · Hemant Kumar
The idea behind '%' was to identify the SDT events and take a different path to lookup through the cache, put a probe, record and then delete the probe. Or, do you want "perf record" to record any event this way (not just an sdt event).
I see, but I think that is not good by following reasons,
Quoted 8 lines
- when we record event with "-e %provider:event", it will be shown as "provider:event"
- if perf-list shows the SDT(cached) events as "%provider:event", that will not match the recorded result.
- it is somewhat fragile that we temporary add the SDT event and remove it after record, because the event will not hide from ftrace users (this means that we'll fail removing the event by-EBUSYif someone use it via ftrace)We should avoid that, if we say record event "foo:bar", then we should consistently show "foo:bar" everywhere this is referenced.
Quoted 6 lines
- if we set SDT events perf-probe, it will be shown as "provider:event" name because "%" will be rejected by ftrace. In that case, what the perf-list show those events, both of %provider:event and provider:event ?
thus I pushed the "%" as a "special remembering mark" only for looking up the event from cache by perf-probe.
Quoted 8 lines
Quoted 4 lines
So I'd like to suggest that the following behavior
1) perf-list shows the cached-with-name and SDT events as Tracepoint events even if it is not yet probed.
I can agree with 'perf list' showing what can be used as events, and SDTs, AFAIK, match that definition, i.e. we have somewhere (in the DSOs, right?) information about where to ask for an event to be enabled.
SDTs are described in .note section, and is extracted by perf-buildid-cache and stored into perf-probe's cache file (under buildid-cache). Perf-list shows only the extracted one.
Quoted 3 lines
If there are details on how that needs to be obtained, then passed to the kernel somehow to then become really, really accessible, then these details are completely internal.
agreed.
Quoted 42 lines
Quoted 6 lines
# perf listList of pre-defined events (to be used in -e):
...
libc:memory_heap_new [Tracepoint event]Is it like this or is it like [ku]probes where we already have a namespace qualifier, i.e.:
[root@zoo ~]# perf probe
icmp_rcv
Added new event:
probe:icmp_rcv (onicmp_rcv)You can now use it in all perf tools, such as:
perf record -e probe:icmp_rcv -aR sleep 1
[root@zoo ~]#
[root@zoo ~]# perf probe
/lib64/libc-2.20.somalloc Added new events:probe_libc:malloc (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_1 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_2 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_3 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_4 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_5 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_6 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_7 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_8 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_9 (on malloc in /lib64/libc-2.20.so)probe_libc:malloc_10 (on malloc in
/lib64/libc-2.20.so) probe_libc:malloc_11 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_12 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_13 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_14 (on malloc in/lib64/libc-2.20.so)You can now use it in all perf tools, such as:
perf record -e probe_libc:malloc_14 -aR sleep 1
Quoted 7 lines
[root@zoo ~]#
"probe" for kernel events, "probe_%s" % DSO basename for userspace events.
Why not continue with that and have SDTs use the probe_%s: namespace? Sorry if this was already discussed here...
:) We are discussing about that in another thread, anyway, probe_%s can solve a little part of the clash of names.
Quoted 3 lines
If there is some ambiguity, that can be resolved by explicitely setting a new name, 'perf probe' has provision for that, right? I.e.:
Yes, but that means we'll have to give new names before using that.
Actually, SDT has "provider-name", "event-name" and "probe location" (also have arguments, but not supported). And provider name is not always same as the binary name. (actually, the application developers can use any name for it...)
So adding something special prefix or detect clash before using will be the option.
The following patterns we've discussed.
- <provider>:<name>
simple, but could easily clash with others.
- probe_<provider>:<name>
- sdt_<provider>:<name>
also simple and similar to current solution. but fragile against clash among SDTs.
- probe_<binary>:<provider>_<name>
also simple, but if provider or/and name has '_', it is hard to split the provider and name. and fragile against clash among SDTs too.
- <provider>_<buildid>/<name>
possible, but ugly since buildid is a random long xdigits(maybe cut up to 8 or 12 bytes).
Quoted 20 lines
[root@zoo ~]# perf probe
/lib64/libc-2.20.soanother_name=malloc Added new events:
<SNIP>
probe_libc:another_name_14 (on malloc in/lib64/libc-2.20.so)You can now use it in all perf tools, such as:
perf record -e probe_libc:another_name_14 -aR sleep 1
[root@zoo ~]#
Quoted 8 lines
...
probes:myevent [Tracepoint event]
...2) perf-record -e with no-probed event should try to set up the given probe by using perf-probe. It is possible to remove that the probe after recording, but also ignore if it fails by
-EBUSY. (anyway, there is no difference for users)
Quoted 4 lines
Right, being able to add new probes _without_ calling 'perf probe', but instead functions used by 'perf probe' is something the eBPF does (I'm almost getting there... :) ) and that I want to do in other tools, like 'trace' as well...
Yes, it should be done internally. (of course, users also can use perf-probe for activating SDT.)
Quoted 3 lines
There are permission problems about how to add new probes and how to _enable_ them, i.e. I think it is ok to allow users to ask for probe:foo, if they are monitoring just their workloads...
I see... But that's another issue I think, since the issue is already there for using uprobes. We'd better fork thread for that issue.
[...]
Quoted 4 lines
This needs refining, i.e. I should just warn that albeit "probe:vfs_getname" is available, it can't be used, unless we open the doors wide.
Sorry for the digression, but these permission issues will hit us with SDT as well, no?
Yes, and we have another way to avoid this issue, by using setuid as systemtap does.
Quoted 10 lines
Quoted 5 lines
This rule will solve the contradiction between the event name on recorded data and listed events. However, as we discussed there are other clashes.
A) clash among binaries: Since the binary builders can freely use the provider name, it is possible to clash to other binaries' SDTs.
Yes, one way to disambiguate is to use the buildid, i.e. content based, when/if the need arises. We should _always_ store the build-id, together with any probe used, so that we can bail out when trying to run those with a non matching DSO (kernel, module, library, whatever).
Store the build-id with what? SDTs and cached probes are already stored under build-id directory(same location of buildid-cache). Would you mean perf.data?
And managing all probe events strictly by perftools is hard since someone can set new probes via tracefs(debugfs) directly.
Quoted 17 lines
When specifying some SDT that is ambiguous, we should bail out and ask for further namespacing, like:
[acme@zoo linux]$ git show --oneline 25b6
error: short SHA1 25b6 is ambiguous.
error: short SHA1 25b6 is ambiguous.
fatal: ambiguous argument '25b6': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
[acme@zoo linux]$ git show --oneline 25b67
error: short SHA1 25b67 is ambiguous.
error: short SHA1 25b67 is ambiguous.
fatal: ambiguous argument '25b67': unknown revision or path not in the working tree. Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
Quoted 12 lines
It can be via build-id or by asking for the full pathname to the DSO, etc.
Quoted 3 lines
B) clash among different versions: Of course the different versions of binaries can be co-exist on the system. Those usually have the same SDTs and same basename, just different build-ids.
Right, in that case the build-id or the full pathname needs to be specified somehow
Quoted 4 lines
These issues are not solved by using "%" because it happens among SDTs. So we need to find another way to distinguish the SDTs.
From what I've read so far (not much): agreed.
Thank you,
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Arnaldo Carvalho de Melo
maintainerEm Fri, Jul 24, 2015 at 01:24:53AM +0900, Masami Hiramatsu escreveu:
Quoted 7 lines · Arnaldo Carvalho de Melo
Quoted 4 lines
This needs refining, i.e. I should just warn that albeit "probe:vfs_getname" is available, it can't be used, unless we open the doors wide.
Sorry for the digression, but these permission issues will hit us with SDT as well, no?
Yes, and we have another way to avoid this issue, by using setuid as systemtap does.
Will react to the other parts later, but 'setuid'?, can we do better? That look like some big hammer :-/
- Arnaldo
Namhyung Kim
maintainerHi Masami and Arnaldo,
Quoted 79 lines · Masami Hiramatsu
Quoted 42 lines · Arnaldo Carvalho de Melo
Em Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
Quoted 5 lines
# perf listList of pre-defined events (to be used in -e):
...
libc:memory_heap_new [Tracepoint event]Is it like this or is it like [ku]probes where we already have a namespace qualifier, i.e.:
[root@zoo ~]# perf probe
icmp_rcv
Added new event:
probe:icmp_rcv (onicmp_rcv)You can now use it in all perf tools, such as:
perf record -e probe:icmp_rcv -aR sleep 1
[root@zoo ~]#
[root@zoo ~]# perf probe
/lib64/libc-2.20.somalloc Added new events:probe_libc:malloc (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_1 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_2 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_3 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_4 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_5 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_6 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_7 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_8 (on malloc in /lib64/libc-2.20.so) probe_libc:malloc_9 (on malloc in /lib64/libc-2.20.so)probe_libc:malloc_10 (on malloc in
/lib64/libc-2.20.so) probe_libc:malloc_11 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_12 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_13 (on malloc in/lib64/libc-2.20.so) probe_libc:malloc_14 (on malloc in/lib64/libc-2.20.so)You can now use it in all perf tools, such as:
perf record -e probe_libc:malloc_14 -aR sleep 1
Quoted 7 lines
[root@zoo ~]#
"probe" for kernel events, "probe_%s" % DSO basename for userspace events.
Why not continue with that and have SDTs use the probe_%s: namespace? Sorry if this was already discussed here...
:) We are discussing about that in another thread, anyway, probe_%s can solve a little part of the clash of names.
Quoted 3 lines
If there is some ambiguity, that can be resolved by explicitely setting a new name, 'perf probe' has provision for that, right? I.e.:
Yes, but that means we'll have to give new names before using that.
Actually, SDT has "provider-name", "event-name" and "probe location" (also have arguments, but not supported). And provider name is not always same as the binary name. (actually, the application developers can use any name for it...)
So adding something special prefix or detect clash before using will be the option.The following patterns we've discussed.
- <provider>:<name>
simple, but could easily clash with others.
- probe_<provider>:<name>
- sdt_<provider>:<name>
also simple and similar to current solution. but fragile against clash among SDTs.
- probe_<binary>:<provider>_<name>
also simple, but if provider or/and name has '_', it is hard to split the provider and name. and fragile against clash among SDTs too.
- <provider>_<buildid>/<name>
Quoted 2 lines
possible, but ugly since buildid is a random long xdigits(maybe cut up to 8 or 12 bytes).
As I said, we might allow name clashes as they're rare. I don't want to make it complex just for an uncommon case. I think such a duplicate name is fine as long as 'perf list' indicates it and 'perf record' enable them all.
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Maybe something like below. Suppose we have 3 SDT events with a same name:
/some/where/dir1/libfoo1.so (build-id: 0x1234...) --> foo:bar /some/where/dir2/libfoo1.so (build-id: 0x5678...) --> foo:bar /some/where/dir2/libfoo2.so (build-id: 0xabcd...) --> foo:bar
So perf list shows the single name, but also says it has 3 events.
$ perf list sdt_foo:bar
sdt_foo:bar (total 3 events) [User SDT event]
$ perf list -v sdt_foo:bar
sdt_foo:bar:libfoo1.so:0x1234... [User SDT event] sdt_foo:bar:libfoo1.so:0x5678... [User SDT event] sdt_foo:bar:libfoo2.so:0xabcd... [User SDT event]
Now perf record can accept any of these forms..
# record all 3 events $ perf record -e 'sdt_foo:bar'
# record 2 events from libfoo1.so $ perf record -e 'sdt_foo:bar:libfoo1.so'
# record only 1 event $ perf record -e 'sdt_foo:bar:libfoo1.so:0x1234...'
What do you think?
Thanks,
Namhyung
Arnaldo Carvalho de Melo
maintainerEm Fri, Jul 24, 2015 at 04:55:19PM +0900, Namhyung Kim escreveu:
Quoted 19 lines · Masami Hiramatsu
Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 1 line
Em Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
The following patterns we've discussed.
- <provider>:<name>
simple, but could easily clash with others.
- probe_<provider>:<name>
- sdt_<provider>:<name>
also simple and similar to current solution. but fragile against clash among SDTs.
- probe_<binary>:<provider>_<name>
also simple, but if provider or/and name has '_', it is hard to split the provider and name. and fragile against clash among SDTs too.
- <provider>_<buildid>/<name>Quoted 2 lines
possible, but ugly since buildid is a random long xdigits(maybe cut up to 8 or 12 bytes).
Quoted 4 lines
As I said, we might allow name clashes as they're rare. I don't want to make it complex just for an uncommon case. I think such a duplicate name is fine as long as 'perf list' indicates it and 'perf record' enable them all.
I made some comments about enabling it all by default, look below.
Quoted 2 lines
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Reading this again after writing what is below: my suggestion is to use @, see rationale below.
Quoted 7 lines
Maybe something like below. Suppose we have 3 SDT events with a same name:
/some/where/dir1/libfoo1.so (build-id: 0x1234...) --> foo:bar /some/where/dir2/libfoo1.so (build-id: 0x5678...) --> foo:bar /some/where/dir2/libfoo2.so (build-id: 0xabcd...) --> foo:bar
Quoted 5 lines
So perf list shows the single name, but also says it has 3 events.
$ perf list sdt_foo:barsdt_foo:bar (total 3 events) [User SDT event]
I would show what desambiguates them in non verbose mode, i.e., the above would be:
$ perf list sdt_foo:bar
sdt_foo:bar:dir1/libfoo1.so [User SDT event] sdt_foo:bar:dir2/libfoo1.so [User SDT event] sdt_foo:bar:libfoo2.so [User SDT event]
The -v one would should both the full path and the buildid, but this
is just polishing up the default output a bit to make it more informative.
Now what should be the default when one does:
perf record -e sdt_foo:bar
Will it enable all events or bail out and state that multiple
events with that name matches, requiring a '--all-matches' to really apply it to all events with the same name?
Humm, this probably will not be that common, so perhaps just
use all matches by default while telling the user that all those places were used and if the user wants just one of them, be more precise, adding somehow a disambiguator.
That would be something like this:
perf record -e sdt_foo:bar:0x1234
Or perhaps:
perf record -e sdt_foo:bar@0x1234
Because in this case the 'at' meaning of '@' makes sense, i.e.use the std_foo:bar event at the DSO with a 0x1234 buildid?
Additionally, for people that don't want to mess with buildids
because its environment is deemed well controlled and this works and is unambiguous, looking at the LD_LIBRARY_PATH or equivalent:
perf record -e sdt_foo:bar@libfoo2
Full paths could be used as well.
Quoted 13 lines
$ perf list -v sdt_foo:barsdt_foo:bar:libfoo1.so:0x1234... [User SDT event] sdt_foo:bar:libfoo1.so:0x5678... [User SDT event] sdt_foo:bar:libfoo2.so:0xabcd... [User SDT event]Now perf record can accept any of these forms..
# record all 3 events $ perf record -e 'sdt_foo:bar'
Quoted 8 lines
# record 2 events from libfoo1.so $ perf record -e 'sdt_foo:bar:libfoo1.so'# record only 1 event $ perf record -e 'sdt_foo:bar:libfoo1.so:0x1234...'What do you think?
If nothing prevents using @ with the meaning of "event at LOCATION" where LOCATION is a buildid (noticed because it starts with 0x) or a library name or pathname, then that looks more natural.
- Arnaldo
Quoted 51 lines · Arnaldo Carvalho de Melo
Em Fri, Jul 24, 2015 at 04:55:19PM +0900, Namhyung Kim escreveu:
Quoted 19 lines · Masami Hiramatsu
Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 1 line
Em Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
The following patterns we've discussed.
- <provider>:<name>
simple, but could easily clash with others.
- probe_<provider>:<name>
- sdt_<provider>:<name>
also simple and similar to current solution. but fragile against clash among SDTs.
- probe_<binary>:<provider>_<name>
also simple, but if provider or/and name has '_', it is hard to split the provider and name. and fragile against clash among SDTs too.
- <provider>_<buildid>/<name>Quoted 2 lines
possible, but ugly since buildid is a random long xdigits(maybe cut up to 8 or 12 bytes).Quoted 4 lines
As I said, we might allow name clashes as they're rare. I don't want to make it complex just for an uncommon case. I think such a duplicate name is fine as long as 'perf list' indicates it and 'perf record' enable them all.
I made some comments about enabling it all by default, look below.
Quoted 2 lines
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Reading this again after writing what is below: my suggestion is to use @, see rationale below.
Quoted 7 lines
Maybe something like below. Suppose we have 3 SDT events with a same name:
/some/where/dir1/libfoo1.so (build-id: 0x1234...) --> foo:bar /some/where/dir2/libfoo1.so (build-id: 0x5678...) --> foo:bar /some/where/dir2/libfoo2.so (build-id: 0xabcd...) --> foo:barQuoted 5 lines
So perf list shows the single name, but also says it has 3 events.
$ perf list sdt_foo:barsdt_foo:bar (total 3 events) [User SDT event]
I would show what desambiguates them in non verbose mode, i.e., the above would be:
$ perf list sdt_foo:bar
Quoted 7 lines
sdt_foo:bar:dir1/libfoo1.so [User SDT event] sdt_foo:bar:dir2/libfoo1.so [User SDT event] sdt_foo:bar:libfoo2.so [User SDT event]The -v one would should both the full path and the buildid, but this
is just polishing up the default output a bit to make it more informative.
I agree that the short path is useful, but we know only full path how to make it short? (only show the differences?)
Quoted 8 lines
Now what should be the default when one does:
perf record -e sdt_foo:bar
Will it enable all events or bail out and state that multiple
events with that name matches, requiring a '--all-matches' to really apply it to all events with the same name?
OK, but the problem is that the k/uprobe_event doesn't support multiple probe on one event yet. This means that if we set those 3 events, it will be translated to "sdt_foo:bar", "sdt_foo:bar_1", and "sdt_foo:bar_2". So we need to enhance k/uprobe_event too. Note that, if the event-name clash happens among events with different type of arguments, we can not bail it out... It is better to warn user if that happened.
Quoted 14 lines
Humm, this probably will not be that common, so perhaps just
use all matches by default while telling the user that all those places were used and if the user wants just one of them, be more precise, adding somehow a disambiguator.That would be something like this: perf record -e sdt_foo:bar:0x1234 Or perhaps: perf record -e sdt_foo:bar@0x1234 Because in this case the 'at' meaning of '@' makes sense, i.e.
Quoted 1 line
use the std_foo:bar event at the DSO with a
0x1234buildid?
Ah, that's nice :) I like '@'.
Quoted 27 lines
Additionally, for people that don't want to mess with buildids
because its environment is deemed well controlled and this works and is unambiguous, looking at theLD_LIBRARY_PATHor equivalent:perf record -e sdt_foo:bar@libfoo2
Full paths could be used as well.
Quoted 20 lines
$ perf list -v sdt_foo:barsdt_foo:bar:libfoo1.so:0x1234... [User SDT event] sdt_foo:bar:libfoo1.so:0x5678... [User SDT event] sdt_foo:bar:libfoo2.so:0xabcd... [User SDT event]Now perf record can accept any of these forms..
# record all 3 events $ perf record -e 'sdt_foo:bar'# record 2 events from libfoo1.so $ perf record -e 'sdt_foo:bar:libfoo1.so'# record only 1 event $ perf record -e 'sdt_foo:bar:libfoo1.so:0x1234...'
Quoted 5 lines
Quoted 1 line
What do you think?
If nothing prevents using @ with the meaning of "event at LOCATION" where LOCATION is a buildid (noticed because it starts with 0x) or a library name or pathname, then that looks more natural.
BTW, will we show it as "[User SDT event]" instead of "[Tracepoint]"? In that case, after setting the event, same name event will appear under tracefs/events/. I guess it conflicts with above SDT event. e.g.
$ perf list sdt_foo:bar
sdt_foo:bar@dir1/libfoo1.so [User SDT event] sdt_foo:bar@dir2/libfoo1.so [User SDT event] sdt_foo:[email protected] [User SDT event]
And enables on libfoo2.so
$ perf record -e sdt_foo:[email protected]
What the perf list shows
$ perf list sdt_foo:bar
sdt_foo:[email protected] [Tracepoint] sdt_foo:bar@dir1/libfoo1.so [User SDT event] sdt_foo:bar@dir2/libfoo1.so [User SDT event]
Is this OK? Or, we'll need to distinguish sdt_* from other events.
Thank you,
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Namhyung Kim
maintainerHi Arnaldo,
Quoted 20 lines · Arnaldo Carvalho de Melo
Em Fri, Jul 24, 2015 at 04:55:19PM +0900, Namhyung Kim escreveu:
Quoted 18 lines · Masami Hiramatsu
Quoted 17 lines · Arnaldo Carvalho de Melo
Quoted 1 line
Em Thu, Jul 23, 2015 at 10:13:22PM +0900, Masami Hiramatsu escreveu:
The following patterns we've discussed.
- <provider>:<name>
simple, but could easily clash with others.
- probe_<provider>:<name>
- sdt_<provider>:<name>
also simple and similar to current solution. but fragile against clash among SDTs.
- probe_<binary>:<provider>_<name>
also simple, but if provider or/and name has '_', it is hard to split the provider and name. and fragile against clash among SDTs too.
- <provider>_<buildid>/<name>possible, but ugly since buildid is a random long xdigits(maybe cut up to 8 or 12 bytes).
Quoted 6 lines
Quoted 4 lines
As I said, we might allow name clashes as they're rare. I don't want to make it complex just for an uncommon case. I think such a duplicate name is fine as long as 'perf list' indicates it and 'perf record' enable them all.
I made some comments about enabling it all by default, look below.
OK.
Quoted 6 lines
Quoted 3 lines
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Reading this again after writing what is below: my suggestion is to use @, see rationale below.
I'm fine with using @.
Quoted 14 lines
Quoted 8 lines
Maybe something like below. Suppose we have 3 SDT events with a same name:
/some/where/dir1/libfoo1.so (build-id: 0x1234...) --> foo:bar /some/where/dir2/libfoo1.so (build-id: 0x5678...) --> foo:bar /some/where/dir2/libfoo2.so (build-id: 0xabcd...) --> foo:barQuoted 5 lines
So perf list shows the single name, but also says it has 3 events.
$ perf list sdt_foo:barsdt_foo:bar (total 3 events) [User SDT event]
Quoted 8 lines
I would show what desambiguates them in non verbose mode, i.e., the above would be:
$ perf list sdt_foo:barsdt_foo:bar:dir1/libfoo1.so [User SDT event] sdt_foo:bar:dir2/libfoo1.so [User SDT event] sdt_foo:bar:libfoo2.so [User SDT event]
Then it should use @ here too.
Quoted 4 lines
The -v one would should both the full path and the buildid, but this
is just polishing up the default output a bit to make it more informative.
Fair enough.
Quoted 5 lines
Now what should be the default when one does:
perf record -e sdt_foo:bar
Quoted 8 lines
Will it enable all events or bail out and state that multiple
events with that name matches, requiring a '--all-matches' to really apply it to all events with the same name?Humm, this probably will not be that common, so perhaps just
use all matches by default while telling the user that all those places were used and if the user wants just one of them, be more precise, adding somehow a disambiguator.
Either is fine to me. Mayb we can add a config option to select the default bahavior.. :)
Quoted 11 lines
That would be something like this: perf record -e sdt_foo:bar:0x1234 Or perhaps: perf record -e sdt_foo:bar@0x1234 Because in this case the 'at' meaning of '@' makes sense, i.e.use the std_foo:bar event at the DSO with a
0x1234buildid?
IMHO @ looks perfect for pathnames but I don't know about build-id as it can be thought as some address. Anyway I still think @ is a good choice though. ;-)
Quoted 4 lines
Additionally, for people that don't want to mess with buildids
because its environment is deemed well controlled and this works and is unambiguous, looking at theLD_LIBRARY_PATHor equivalent:
Ah, good idea.
Quoted 24 lines
perf record -e sdt_foo:bar@libfoo2
Full paths could be used as well.
Quoted 20 lines
$ perf list -v sdt_foo:barsdt_foo:bar:libfoo1.so:0x1234... [User SDT event] sdt_foo:bar:libfoo1.so:0x5678... [User SDT event] sdt_foo:bar:libfoo2.so:0xabcd... [User SDT event]Now perf record can accept any of these forms..
# record all 3 events $ perf record -e 'sdt_foo:bar'# record 2 events from libfoo1.so $ perf record -e 'sdt_foo:bar:libfoo1.so'# record only 1 event $ perf record -e 'sdt_foo:bar:libfoo1.so:0x1234...'
Quoted 5 lines
Quoted 1 line
What do you think?
If nothing prevents using @ with the meaning of "event at LOCATION" where LOCATION is a buildid (noticed because it starts with 0x) or a library name or pathname, then that looks more natural.
Agreed.
Thanks,
Namhyung
Arnaldo Carvalho de Melo
maintainerEm Mon, Jul 27, 2015 at 11:03:20PM +0900, Namhyung Kim escreveu:
Quoted 12 lines · Arnaldo Carvalho de Melo
Quoted 5 lines
Quoted 2 lines
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Reading this again after writing what is below: my suggestion is to use @, see rationale below.
I'm fine with using @.
Quoted 3 lines
I would show what desambiguates them in non verbose mode, i.e., the above would be:
Quoted 7 lines
Quoted 5 lines
$ perf list sdt_foo:barsdt_foo:bar:dir1/libfoo1.so [User SDT event] sdt_foo:bar:dir2/libfoo1.so [User SDT event] sdt_foo:bar:libfoo2.so [User SDT event]Then it should use @ here too.
Right.
<SNIP>
Quoted 10 lines
Quoted 6 lines
That would be something like this:
perf record -e sdt_foo:bar@0x1234
Because in this case the 'at' meaning of '@' makes sense, i.e.
use the std_foo:bar event at the DSO with a0x1234buildid?IMHO @ looks perfect for pathnames but I don't know about build-id as it can be thought as some address. Anyway I still think @ is a good choice though. ;-)
Yeah, perhaps we need further clarification? I.e. something like:
sdt_foo:bar:libfoo1.so@buildid(0x1234)
Or something else, perhaps shorter, that clarifies that it is a buildid?
- Arnaldo
Quoted 36 lines · Arnaldo Carvalho de Melo
Em Mon, Jul 27, 2015 at 11:03:20PM +0900, Namhyung Kim escreveu:
Quoted 12 lines · Arnaldo Carvalho de Melo
Quoted 5 lines
Quoted 2 lines
If we agreed to extend the event format, I'd like to keep it simple and to make it optional to add more info (separated by colon?).
Reading this again after writing what is below: my suggestion is to use @, see rationale below.
I'm fine with using @.
Quoted 3 lines
I would show what desambiguates them in non verbose mode, i.e., the above would be:
Quoted 7 lines
Quoted 5 lines
$ perf list sdt_foo:barsdt_foo:bar:dir1/libfoo1.so [User SDT event] sdt_foo:bar:dir2/libfoo1.so [User SDT event] sdt_foo:bar:libfoo2.so [User SDT event]Then it should use @ here too.
Right.
<SNIP>
Quoted 10 lines
Quoted 6 lines
That would be something like this:
perf record -e sdt_foo:bar@0x1234
Because in this case the 'at' meaning of '@' makes sense, i.e.
use the std_foo:bar event at the DSO with a0x1234buildid?IMHO @ looks perfect for pathnames but I don't know about build-id as it can be thought as some address. Anyway I still think @ is a good choice though. ;-)
Quoted 5 lines
Yeah, perhaps we need further clarification? I.e. something like:
sdt_foo:bar:libfoo1.so@buildid(0x1234)Or something else, perhaps shorter, that clarifies that it is a buildid?
Hmm, Do we really need such additional buildid? Even though, I think the build id should have different delimiter, like '%', as below.
sdt_foo:[email protected]%buildid
Thank you,
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]
Arnaldo Carvalho de Melo
maintainerEm Tue, Jul 28, 2015 at 09:42:59AM +0900, Masami Hiramatsu escreveu:
Quoted 6 lines · Arnaldo Carvalho de Melo
Quoted 4 lines
Em Mon, Jul 27, 2015 at 11:03:20PM +0900, Namhyung Kim escreveu:
Quoted 3 lines
IMHO @ looks perfect for pathnames but I don't know about build-id as it can be thought as some address. Anyway I still think @ is a good choice though. ;-)
Quoted 7 lines
Quoted 5 lines
Yeah, perhaps we need further clarification? I.e. something like:
sdt_foo:bar:libfoo1.so@buildid(0x1234)Or something else, perhaps shorter, that clarifies that it is a buildid?
Hmm, Do we really need such additional buildid? Even though, I think
"or something else, perhaps shorter" :-)
Quoted 3 lines
the build id should have different delimiter, like '%', as below.
sdt_foo:[email protected]%buildid
How about:
sdt_foo:[email protected](0x1234)
Which is clear, to humans: "hey, I want the SDT event 'bar' at the 'libfoo1' library, but make sure it is the one which contents have build id '0x1234'".
But even the name of the library is not strictly needed, would be just a nicety for humans, as the way buildids are looked up are by means of:
[acme@zoo tuna]$ ls -la /usr/lib/debug/.build-id/ | tail -5
drwxr-xr-x. 2 root root 4096 Jul 23 09:26 fb/ drwxr-xr-x. 2 root root 4096 Jun 22 19:35 fc/ drwxr-xr-x. 2 root root 4096 Jun 22 19:35 fd/ drwxr-xr-x. 2 root root 4096 Jun 22 19:35 fe/ drwxr-xr-x. 2 root root 4096 Jun 26 16:57 ff/
[acme@zoo tuna]$
So, having:
sdt_foo:bar@0x1234
Should be unambiguous and shorter.
- ARnaldo
Arnaldo Carvalho de Melo
maintainerEm Wed, Jul 15, 2015 at 06:13:53PM +0900, Masami Hiramatsu escreveu:
Quoted 4 lines
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Applied the first three patches, after fixing up a trivial clash with work I did in perf/core.
- Arnaldo
Arnaldo Carvalho de Melo
maintainerEm Mon, Jul 20, 2015 at 03:36:40PM -0300, Arnaldo Carvalho de Melo escreveu:
Quoted 7 lines
Em Wed, Jul 15, 2015 at 06:13:53PM +0900, Masami Hiramatsu escreveu:
Quoted 4 lines
Hi,
Here is the 2nd version of the patchset for probe-cache and initial SDT support which are going to be perf-cache finally.
Applied the first three patches, after fixing up a trivial clash with
The first two patches were applied, sorry.
Quoted 3 lines
work I did in perf/core.
- Arnaldo