lkml.org 
[lkml]   [2016]   [Jun]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH perf/core v11 20/20] perf probe: Support @BUILDID or @FILE suffix for SDT events
    Date
    Support @BUILDID or @FILE suffix for SDT events. This allows
    perf to add probes on SDTs/pre-cached events on given FILE
    or the file which has given BUILDID (also, this complements
    BUILDID.)
    For example, both gcc and libstdc++ has same SDTs as below.
    If you would like to add a probe on sdt_libstdcxx:catch on gcc,
    you can do as below.

    ----
    # perf list sdt | tail -n 6
    sdt_libstdcxx:catch@/usr/bin/gcc(0cc207fc4b27) [SDT event]
    sdt_libstdcxx:catch@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:rethrow@/usr/bin/gcc(0cc207fc4b27) [SDT event]
    sdt_libstdcxx:rethrow@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    sdt_libstdcxx:throw@/usr/bin/gcc(0cc207fc4b27) [SDT event]
    sdt_libstdcxx:throw@/usr/lib64/libstdc++.so.6.0.20(91c7a88fdf49)
    # perf probe -a %sdt_libstdcxx:catch@0cc
    Added new event:
    sdt_libstdcxx:catch (on %catch in /usr/bin/gcc)

    You can now use it in all perf tools, such as:

    perf record -e sdt_libstdcxx:catch -aR sleep 1
    ----

    Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
    ---
    tools/perf/util/build-id.c | 43 +++++++++++++++++++++++++++++++++++++++++
    tools/perf/util/build-id.h | 1 +
    tools/perf/util/probe-event.c | 17 ++++++++++++++--
    3 files changed, 59 insertions(+), 2 deletions(-)

    diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
    index a28ef39..7b78a33 100644
    --- a/tools/perf/util/build-id.c
    +++ b/tools/perf/util/build-id.c
    @@ -523,6 +523,49 @@ err_out:
    goto out_free;
    }

    +static bool str_is_build_id(const char *maybe_sbuild_id, size_t len)
    +{
    + size_t i;
    +
    + for (i = 0; i < len; i++) {
    + if (!isxdigit(maybe_sbuild_id[i]))
    + return false;
    + }
    + return true;
    +}
    +
    +/* Return the valid complete build-id */
    +char *build_id_cache__complement(const char *incomplete_sbuild_id)
    +{
    + struct strlist *bidlist;
    + struct str_node *nd, *cand = NULL;
    + char *sbuild_id = NULL;
    + size_t len = strlen(incomplete_sbuild_id);
    +
    + if (len >= SBUILD_ID_SIZE ||
    + !str_is_build_id(incomplete_sbuild_id, len))
    + return NULL;
    +
    + bidlist = build_id_cache__list_all(true);
    + if (!bidlist)
    + return NULL;
    +
    + strlist__for_each(nd, bidlist) {
    + if (strncmp(nd->s, incomplete_sbuild_id, len) != 0)
    + continue;
    + if (cand) { /* Error: There are more than 2 candidates. */
    + cand = NULL;
    + break;
    + }
    + cand = nd;
    + }
    + if (cand)
    + sbuild_id = strdup(cand->s);
    + strlist__delete(bidlist);
    +
    + return sbuild_id;
    +}
    +
    char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
    bool is_kallsyms, bool is_vdso)
    {
    diff --git a/tools/perf/util/build-id.h b/tools/perf/util/build-id.h
    index 64e740f..d279906 100644
    --- a/tools/perf/util/build-id.h
    +++ b/tools/perf/util/build-id.h
    @@ -35,6 +35,7 @@ char *build_id_cache__linkname(const char *sbuild_id, char *bf, size_t size);
    char *build_id_cache__cachedir(const char *sbuild_id, const char *name,
    bool is_kallsyms, bool is_vdso);
    struct strlist *build_id_cache__list_all(bool validonly);
    +char *build_id_cache__complement(const char *incomplete_sbuild_id);
    int build_id_cache__list_build_ids(const char *pathname,
    struct strlist **result);
    bool build_id_cache__cached(const char *sbuild_id);
    diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
    index 81e22f1..fa3cbb3 100644
    --- a/tools/perf/util/probe-event.c
    +++ b/tools/perf/util/probe-event.c
    @@ -1253,8 +1253,21 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
    ptr = strpbrk(arg, ";=@+%");
    if (pev->sdt) {
    if (ptr) {
    - semantic_error("%s must contain only an SDT event name.\n", arg);
    - return -EINVAL;
    + if (*ptr != '@') {
    + semantic_error("%s must be an SDT name.\n",
    + arg);
    + return -EINVAL;
    + }
    + /* This must be a target file name or build id */
    + tmp = build_id_cache__complement(ptr + 1);
    + if (tmp) {
    + pev->target = build_id_cache__origname(tmp);
    + free(tmp);
    + } else
    + pev->target = strdup(ptr + 1);
    + if (!pev->target)
    + return -ENOMEM;
    + *ptr = '\0';
    }
    ret = parse_perf_probe_event_name(&arg, pev);
    if (ret == 0) {
    \
     
     \ /
      Last update: 2016-06-15 06:01    [W:4.105 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site