[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150531151147.15103.44163.stgit@localhost.localdomain>
Date: Mon, 01 Jun 2015 00:11:47 +0900
From: Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>
To: Arnaldo Carvalho de Melo <acme@...nel.org>
Cc: Peter Zijlstra <a.p.zijlstra@...llo.nl>,
Adrian Hunter <adrian.hunter@...el.com>,
linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...hat.com>,
Paul Mackerras <paulus@...ba.org>,
Jiri Olsa <jolsa@...nel.org>,
Namhyung Kim <namhyung@...nel.org>,
Borislav Petkov <bp@...e.de>,
Hemant Kumar <hemant@...ux.vnet.ibm.com>
Subject: [RFC PATCH perf/core 12/13] perf probe: Show all cached probes
perf 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.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@...achi.com>
---
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 | 63 ++++++++++++++++++++++++++++++++-
tools/perf/util/probe-file.h | 1 +
6 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 97f4d07..1e09329 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -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 {
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index 169639e..63123c1 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -144,8 +144,7 @@ static int asnprintf(char **strp, size_t size, const char *fmt, ...)
return ret;
}
-static char *build_id_cache__linkname(const char *sbuild_id, char *bf,
- size_t size)
+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,
@@ -155,6 +154,29 @@ static char *build_id_cache__linkname(const char *sbuild_id, char *bf,
return bf;
}
+char *build_id_cache__origname(const char *sbuild_id)
+{
+ char *linkname;
+ char buf[PATH_MAX];
+ char *ret = NULL, *p;
+
+ linkname = build_id_cache__linkname(sbuild_id, NULL, 0);
+ if (!linkname)
+ return NULL;
+
+ if (readlink(linkname, buf, PATH_MAX) < 0)
+ goto out;
+ /* The link should be "../..<origpath>/<sbuild_id>" */
+ p = strrchr(buf, '/'); /* Cut off the "/<sbuild_id>" */
+ if (p) {
+ *p = '\0';
+ ret = strdup(buf + 5); /* Skip "../.." */
+ }
+out:
+ free(linkname);
+ return ret;
+}
+
static const char *build_id_cache__basename(bool is_kallsyms, bool is_vdso)
{
return is_kallsyms ? "kallsyms" : (is_vdso ? "vdso" : "elf");
@@ -313,6 +335,59 @@ void disable_buildid_cache(void)
no_buildid_cache = true;
}
+int build_id_cache__list_all(struct strlist **result)
+{
+ struct strlist *toplist, *list, *bidlist;
+ struct str_node *nd, *nd2;
+ char *topdir, *linkdir;
+ char sbuild_id[SBUILD_ID_SIZE];
+ int ret = 0;
+
+ /* Open the top-level directory */
+ if (asprintf(&topdir, "%s/.build-id/", buildid_dir) < 0)
+ return -errno;
+ toplist = lsdir(topdir, lsdir_no_dot_filter);
+ if (!toplist) {
+ pr_debug("Failed to opendir %s\n", topdir);
+ ret = -errno;
+ goto out;
+ }
+ bidlist = strlist__new(true, NULL);
+ strlist__for_each(nd, toplist) {
+ if (asprintf(&linkdir, "%s/%s", topdir, nd->s) < 0) {
+ ret = -errno;
+ goto out;
+ }
+ /* Open the lower-level directory */
+ list = lsdir(linkdir, lsdir_no_dot_filter);
+ if (!list) {
+ pr_debug("Failed to open %s: %d\n", linkdir, -errno);
+ goto next;
+ }
+ strlist__for_each(nd2, list) {
+ ret = snprintf(sbuild_id, SBUILD_ID_SIZE, "%s%s",
+ nd->s, nd2->s);
+ if (ret != SBUILD_ID_SIZE - 1) {
+ pr_debug("%s/%s is not buildid cache\n",
+ nd->s, nd2->s);
+ continue;
+ }
+ strlist__add(bidlist, sbuild_id);
+ }
+ strlist__delete(list);
+next:
+ free(linkdir);
+ }
+
+ *result = bidlist;
+out:
+ if (toplist)
+ strlist__delete(toplist);
+ free(topdir);
+
+ return ret;
+}
+
char *build_id_cache__dirname_from_path(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 a1f428d..2d5c61c 100644
--- a/tools/perf/util/build-id.h
+++ b/tools/perf/util/build-id.h
@@ -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);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 00fe6e7..e89675d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2144,6 +2144,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;
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 984f690..10dcec5 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -340,10 +340,17 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
{
char cpath[PATH_MAX];
char sbuildid[SBUILD_ID_SIZE];
- char *dir_name;
+ char *dir_name = NULL;
bool is_kallsyms = !target;
int ret, fd;
+ if (target && build_id_cache__cached(target)) {
+ /* This is a cached buildid */
+ strncpy(sbuildid, target, SBUILD_ID_SIZE);
+ dir_name = build_id_cache__linkname(sbuildid, NULL, 0);
+ goto found;
+ }
+
if (target)
ret = filename__sprintf_build_id(target, sbuildid);
else {
@@ -367,8 +374,11 @@ static int probe_cache__open(struct probe_cache *pcache, const char *target)
dir_name = build_id_cache__dirname_from_path(sbuildid, target,
is_kallsyms, false);
- if (!dir_name)
+found:
+ if (!dir_name) {
+ pr_debug("Failed to get cache from %s\n", target);
return -ENOMEM;
+ }
snprintf(cpath, PATH_MAX, "%s/probes", dir_name);
fd = open(cpath, O_CREAT | O_RDWR | O_APPEND, 0644);
@@ -616,3 +626,52 @@ int probe_cache__commit(struct probe_cache *pcache)
out:
return ret;
}
+
+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))
+ printf("%s\n", entry->spev);
+ }
+ return 0;
+}
+
+/* Show all cached probes */
+int probe_cache__show_all_caches(struct strfilter *filter)
+{
+ struct probe_cache *pcache;
+ struct strlist *bidlist;
+ struct str_node *nd;
+ char *buf;
+ int ret;
+
+ buf = strfilter__string(filter);
+ pr_debug("list cache with filter: %s\n", buf);
+ free(buf);
+
+ 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) {
+ pcache = probe_cache__new(nd->s);
+ if (!pcache)
+ continue;
+ buf = build_id_cache__origname(nd->s);
+ printf("%s (%s):\n", buf, nd->s);
+ free(buf);
+ probe_cache__show_entries(pcache, filter);
+ probe_cache__delete(pcache);
+ }
+ return 0;
+}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 833e061..26dc4f7 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -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
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists