linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] perf tools: Add rootfs option for off-box analysis using specified tree
@ 2010-11-21 16:19 David Ahern
  0 siblings, 0 replies; 5+ messages in thread
From: David Ahern @ 2010-11-21 16:19 UTC (permalink / raw)
  To: linux-perf-users; +Cc: David Ahern

The rootfs argument allows analysis of perf.data file using a locally
accessible filesystem tree with debug symbols - e.g.,  loop mounted
KVM disk images, NFS, USB keys, initrds, etc. Anything with an OS tree
can be analyzed from anywhere without the need to populate a local
data store with build-ids.

Signed-off-by: David Ahern <daahern@cisco.com>
---
 tools/perf/builtin-annotate.c  |   16 +++++--
 tools/perf/builtin-diff.c      |    2 +
 tools/perf/builtin-report.c    |    2 +
 tools/perf/builtin-timechart.c |    2 +
 tools/perf/util/hist.c         |   14 +++++-
 tools/perf/util/symbol.c       |   82 +++++++++++++++++++++++++---------------
 tools/perf/util/symbol.h       |    1 +
 7 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6d5604d8d..0ad6876 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -280,7 +280,8 @@ static int hist_entry__tty_annotate(struct hist_entry *he)
 	struct map *map = he->ms.map;
 	struct dso *dso = map->dso;
 	struct symbol *sym = he->ms.sym;
-	const char *filename = dso->long_name, *d_filename;
+	const char *filename = dso->long_name;
+	char d_filename[PATH_MAX];
 	u64 len;
 	LIST_HEAD(head);
 	struct objdump_line *pos, *n;
@@ -288,10 +289,13 @@ static int hist_entry__tty_annotate(struct hist_entry *he)
 	if (hist_entry__annotate(he, &head, 0) < 0)
 		return -1;
 
-	if (full_paths)
-		d_filename = filename;
-	else
-		d_filename = basename(filename);
+	if (full_paths) {
+		snprintf(d_filename, sizeof(d_filename), "%s%s",
+			 symbol_conf.rootfs, filename);
+	} else {
+		snprintf(d_filename, sizeof(d_filename), "%s/%s",
+			 symbol_conf.rootfs, basename(filename));
+	}
 
 	len = sym->end - sym->start;
 
@@ -437,6 +441,8 @@ static const struct option options[] = {
 		    "print matching source lines (may be slow)"),
 	OPT_BOOLEAN('P', "full-paths", &full_paths,
 		    "Don't shorten the displayed pathnames"),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index fca1d44..92754fa 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -191,6 +191,8 @@ static const struct option options[] = {
 	OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
 		   "separator for columns, no spaces will be added between "
 		   "columns '.' is reserved."),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5de405d..dd07dda 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -478,6 +478,8 @@ static const struct option options[] = {
 		   "columns '.' is reserved."),
 	OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
 		    "Only display entries resolved to a symbol"),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 9bcc38f..9745cd0 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1018,6 +1018,8 @@ static const struct option options[] = {
 	OPT_CALLBACK('p', "process", NULL, "process",
 		      "process selector. Pass a pid or process name.",
 		       parse_process),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 2022e87..f4de675 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1092,6 +1092,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 	FILE *file;
 	int err = 0;
 	u64 len;
+	char rootfs_filename[PATH_MAX];
+
+	if (filename) {
+		snprintf(rootfs_filename, sizeof(rootfs_filename), "%s%s",
+		 symbol_conf.rootfs, filename);
+	}
 
 	if (filename == NULL) {
 		if (dso->has_build_id) {
@@ -1100,9 +1106,9 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 			return -ENOMEM;
 		}
 		goto fallback;
-	} else if (readlink(filename, command, sizeof(command)) < 0 ||
+	} else if (readlink(rootfs_filename, command, sizeof(command)) < 0 ||
 		   strstr(command, "[kernel.kallsyms]") ||
-		   access(filename, R_OK)) {
+		   access(rootfs_filename, R_OK)) {
 		free(filename);
 fallback:
 		/*
@@ -1111,6 +1117,8 @@ fallback:
 		 * DSO is the same as when 'perf record' ran.
 		 */
 		filename = dso->long_name;
+		snprintf(rootfs_filename, sizeof(rootfs_filename), "%s%s",
+		 symbol_conf.rootfs, filename);
 		free_filename = false;
 	}
 
@@ -1137,7 +1145,7 @@ fallback:
 		 "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
 		 map__rip_2objdump(map, sym->start),
 		 map__rip_2objdump(map, sym->end),
-		 filename, filename);
+		 rootfs_filename, filename);
 
 	pr_debug("Executing: %s\n", command);
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 861be8b..6fdbcaa 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -41,6 +41,7 @@ struct symbol_conf symbol_conf = {
 	.exclude_other	  = true,
 	.use_modules	  = true,
 	.try_vmlinux_path = true,
+	.rootfs           = "",
 };
 
 int dso__name_len(const struct dso *self)
@@ -831,8 +832,11 @@ static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
 	char sympltname[1024];
 	Elf *elf;
 	int nr = 0, symidx, fd, err = 0;
+	char name[PATH_MAX];
 
-	fd = open(self->long_name, O_RDONLY);
+	snprintf(name, sizeof(name), "%s%s",
+		 symbol_conf.rootfs, self->long_name);
+	fd = open(name, O_RDONLY);
 	if (fd < 0)
 		goto out;
 
@@ -1444,16 +1448,19 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 	     self->origin++) {
 		switch (self->origin) {
 		case DSO__ORIG_BUILD_ID_CACHE:
-			if (dso__build_id_filename(self, name, size) == NULL)
+			/* skip the locally configured cache if a rootfs is given */
+			if ((strlen(symbol_conf.rootfs) != 0) ||
+			    (dso__build_id_filename(self, name, size) == NULL)) {
 				continue;
+			}
 			break;
 		case DSO__ORIG_FEDORA:
-			snprintf(name, size, "/usr/lib/debug%s.debug",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s.debug",
+				 symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_UBUNTU:
-			snprintf(name, size, "/usr/lib/debug%s",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s",
+				 symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_BUILDID: {
 			char build_id_hex[BUILD_ID_SIZE * 2 + 1];
@@ -1465,12 +1472,13 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 					  sizeof(self->build_id),
 					  build_id_hex);
 			snprintf(name, size,
-				 "/usr/lib/debug/.build-id/%.2s/%s.debug",
-				 build_id_hex, build_id_hex + 2);
+				 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+				 symbol_conf.rootfs, build_id_hex, build_id_hex + 2);
 			}
 			break;
 		case DSO__ORIG_DSO:
-			snprintf(name, size, "%s", self->long_name);
+			snprintf(name, size, "%s%s",
+			     symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_GUEST_KMODULE:
 			if (!map->groups || !map->groups->machine)
@@ -1776,17 +1784,20 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
 			     const char *vmlinux, symbol_filter_t filter)
 {
 	int err = -1, fd;
+	char rootfs_vmlinux[PATH_MAX];
 
-	fd = open(vmlinux, O_RDONLY);
+	snprintf(rootfs_vmlinux, sizeof(rootfs_vmlinux), "%s/%s",
+		 symbol_conf.rootfs, vmlinux);
+	fd = open(rootfs_vmlinux, O_RDONLY);
 	if (fd < 0)
 		return -1;
 
 	dso__set_loaded(self, map->type);
-	err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
+	err = dso__load_sym(self, map, rootfs_vmlinux, fd, filter, 0, 0);
 	close(fd);
 
 	if (err > 0)
-		pr_debug("Using %s for symbols\n", vmlinux);
+		pr_debug("Using %s for symbols\n", rootfs_vmlinux);
 
 	return err;
 }
@@ -1859,6 +1870,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
 			goto out_fixup;
 	}
 
+	/* do not try local files if a rootfs was given */
+	if (strlen(symbol_conf.rootfs) != 0)
+		return -1;
+
 	/*
 	 * Say the kernel DSO was created when processing the build-id header table,
 	 * we have a build-id, so check if it is the same as the running kernel,
@@ -2208,9 +2223,6 @@ static int vmlinux_path__init(void)
 	struct utsname uts;
 	char bf[PATH_MAX];
 
-	if (uname(&uts) < 0)
-		return -1;
-
 	vmlinux_path = malloc(sizeof(char *) * 5);
 	if (vmlinux_path == NULL)
 		return -1;
@@ -2223,22 +2235,30 @@ static int vmlinux_path__init(void)
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
 		goto out_fail;
 	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
-		 uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
+
+	/* if no rootfs has been given try running kernel version too */
+	if (strlen(symbol_conf.rootfs) == 0) {
+		if (uname(&uts) < 0)
+			return -1;
+
+		snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+		snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux",
+			 uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+		snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
+			 uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+	}
 
 	return 0;
 
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 038f220..a97b6d3 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -85,6 +85,7 @@ struct symbol_conf {
        struct strlist	*dso_list,
 			*comm_list,
 			*sym_list;
+	const char	*rootfs;
 };
 
 extern struct symbol_conf symbol_conf;
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread
* [PATCH] perf tools: Add rootfs option for off-box analysis using specified tree
@ 2010-11-21 16:17 y
  0 siblings, 0 replies; 5+ messages in thread
From: y @ 2010-11-21 16:17 UTC (permalink / raw)
  To: linux-perf-users; +Cc: David Ahern

From: David Ahern <daahern@cisco.com>

The rootfs argument allows analysis of perf.data file using a locally
accessible filesystem tree with debug symbols - e.g.,  loop mounted
KVM disk images, NFS, USB keys, initrds, etc. Anything with an OS tree
can be analyzed from anywhere without the need to populate a local
data store with build-ids.

Signed-off-by: David Ahern <daahern@cisco.com>
---
 tools/perf/builtin-annotate.c  |   16 +++++--
 tools/perf/builtin-diff.c      |    2 +
 tools/perf/builtin-report.c    |    2 +
 tools/perf/builtin-timechart.c |    2 +
 tools/perf/util/hist.c         |   14 +++++-
 tools/perf/util/symbol.c       |   82 +++++++++++++++++++++++++---------------
 tools/perf/util/symbol.h       |    1 +
 7 files changed, 80 insertions(+), 39 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 6d5604d8d..0ad6876 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -280,7 +280,8 @@ static int hist_entry__tty_annotate(struct hist_entry *he)
 	struct map *map = he->ms.map;
 	struct dso *dso = map->dso;
 	struct symbol *sym = he->ms.sym;
-	const char *filename = dso->long_name, *d_filename;
+	const char *filename = dso->long_name;
+	char d_filename[PATH_MAX];
 	u64 len;
 	LIST_HEAD(head);
 	struct objdump_line *pos, *n;
@@ -288,10 +289,13 @@ static int hist_entry__tty_annotate(struct hist_entry *he)
 	if (hist_entry__annotate(he, &head, 0) < 0)
 		return -1;
 
-	if (full_paths)
-		d_filename = filename;
-	else
-		d_filename = basename(filename);
+	if (full_paths) {
+		snprintf(d_filename, sizeof(d_filename), "%s%s",
+			 symbol_conf.rootfs, filename);
+	} else {
+		snprintf(d_filename, sizeof(d_filename), "%s/%s",
+			 symbol_conf.rootfs, basename(filename));
+	}
 
 	len = sym->end - sym->start;
 
@@ -437,6 +441,8 @@ static const struct option options[] = {
 		    "print matching source lines (may be slow)"),
 	OPT_BOOLEAN('P', "full-paths", &full_paths,
 		    "Don't shorten the displayed pathnames"),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index fca1d44..92754fa 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -191,6 +191,8 @@ static const struct option options[] = {
 	OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
 		   "separator for columns, no spaces will be added between "
 		   "columns '.' is reserved."),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 5de405d..dd07dda 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -478,6 +478,8 @@ static const struct option options[] = {
 		   "columns '.' is reserved."),
 	OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
 		    "Only display entries resolved to a symbol"),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 9bcc38f..9745cd0 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1018,6 +1018,8 @@ static const struct option options[] = {
 	OPT_CALLBACK('p', "process", NULL, "process",
 		      "process selector. Pass a pid or process name.",
 		       parse_process),
+	OPT_STRING(0, "rootfs", &symbol_conf.rootfs, "directory",
+		    "Look for symbol files relative to this root directory."),
 	OPT_END()
 };
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 2022e87..f4de675 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1092,6 +1092,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 	FILE *file;
 	int err = 0;
 	u64 len;
+	char rootfs_filename[PATH_MAX];
+
+	if (filename) {
+		snprintf(rootfs_filename, sizeof(rootfs_filename), "%s%s",
+		 symbol_conf.rootfs, filename);
+	}
 
 	if (filename == NULL) {
 		if (dso->has_build_id) {
@@ -1100,9 +1106,9 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head,
 			return -ENOMEM;
 		}
 		goto fallback;
-	} else if (readlink(filename, command, sizeof(command)) < 0 ||
+	} else if (readlink(rootfs_filename, command, sizeof(command)) < 0 ||
 		   strstr(command, "[kernel.kallsyms]") ||
-		   access(filename, R_OK)) {
+		   access(rootfs_filename, R_OK)) {
 		free(filename);
 fallback:
 		/*
@@ -1111,6 +1117,8 @@ fallback:
 		 * DSO is the same as when 'perf record' ran.
 		 */
 		filename = dso->long_name;
+		snprintf(rootfs_filename, sizeof(rootfs_filename), "%s%s",
+		 symbol_conf.rootfs, filename);
 		free_filename = false;
 	}
 
@@ -1137,7 +1145,7 @@ fallback:
 		 "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS -C %s|grep -v %s|expand",
 		 map__rip_2objdump(map, sym->start),
 		 map__rip_2objdump(map, sym->end),
-		 filename, filename);
+		 rootfs_filename, filename);
 
 	pr_debug("Executing: %s\n", command);
 
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 861be8b..6fdbcaa 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -41,6 +41,7 @@ struct symbol_conf symbol_conf = {
 	.exclude_other	  = true,
 	.use_modules	  = true,
 	.try_vmlinux_path = true,
+	.rootfs           = "",
 };
 
 int dso__name_len(const struct dso *self)
@@ -831,8 +832,11 @@ static int dso__synthesize_plt_symbols(struct  dso *self, struct map *map,
 	char sympltname[1024];
 	Elf *elf;
 	int nr = 0, symidx, fd, err = 0;
+	char name[PATH_MAX];
 
-	fd = open(self->long_name, O_RDONLY);
+	snprintf(name, sizeof(name), "%s%s",
+		 symbol_conf.rootfs, self->long_name);
+	fd = open(name, O_RDONLY);
 	if (fd < 0)
 		goto out;
 
@@ -1444,16 +1448,19 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 	     self->origin++) {
 		switch (self->origin) {
 		case DSO__ORIG_BUILD_ID_CACHE:
-			if (dso__build_id_filename(self, name, size) == NULL)
+			/* skip the locally configured cache if a rootfs is given */
+			if ((strlen(symbol_conf.rootfs) != 0) ||
+			    (dso__build_id_filename(self, name, size) == NULL)) {
 				continue;
+			}
 			break;
 		case DSO__ORIG_FEDORA:
-			snprintf(name, size, "/usr/lib/debug%s.debug",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s.debug",
+				 symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_UBUNTU:
-			snprintf(name, size, "/usr/lib/debug%s",
-				 self->long_name);
+			snprintf(name, size, "%s/usr/lib/debug%s",
+				 symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_BUILDID: {
 			char build_id_hex[BUILD_ID_SIZE * 2 + 1];
@@ -1465,12 +1472,13 @@ int dso__load(struct dso *self, struct map *map, symbol_filter_t filter)
 					  sizeof(self->build_id),
 					  build_id_hex);
 			snprintf(name, size,
-				 "/usr/lib/debug/.build-id/%.2s/%s.debug",
-				 build_id_hex, build_id_hex + 2);
+				 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
+				 symbol_conf.rootfs, build_id_hex, build_id_hex + 2);
 			}
 			break;
 		case DSO__ORIG_DSO:
-			snprintf(name, size, "%s", self->long_name);
+			snprintf(name, size, "%s%s",
+			     symbol_conf.rootfs, self->long_name);
 			break;
 		case DSO__ORIG_GUEST_KMODULE:
 			if (!map->groups || !map->groups->machine)
@@ -1776,17 +1784,20 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
 			     const char *vmlinux, symbol_filter_t filter)
 {
 	int err = -1, fd;
+	char rootfs_vmlinux[PATH_MAX];
 
-	fd = open(vmlinux, O_RDONLY);
+	snprintf(rootfs_vmlinux, sizeof(rootfs_vmlinux), "%s/%s",
+		 symbol_conf.rootfs, vmlinux);
+	fd = open(rootfs_vmlinux, O_RDONLY);
 	if (fd < 0)
 		return -1;
 
 	dso__set_loaded(self, map->type);
-	err = dso__load_sym(self, map, vmlinux, fd, filter, 0, 0);
+	err = dso__load_sym(self, map, rootfs_vmlinux, fd, filter, 0, 0);
 	close(fd);
 
 	if (err > 0)
-		pr_debug("Using %s for symbols\n", vmlinux);
+		pr_debug("Using %s for symbols\n", rootfs_vmlinux);
 
 	return err;
 }
@@ -1859,6 +1870,10 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
 			goto out_fixup;
 	}
 
+	/* do not try local files if a rootfs was given */
+	if (strlen(symbol_conf.rootfs) != 0)
+		return -1;
+
 	/*
 	 * Say the kernel DSO was created when processing the build-id header table,
 	 * we have a build-id, so check if it is the same as the running kernel,
@@ -2208,9 +2223,6 @@ static int vmlinux_path__init(void)
 	struct utsname uts;
 	char bf[PATH_MAX];
 
-	if (uname(&uts) < 0)
-		return -1;
-
 	vmlinux_path = malloc(sizeof(char *) * 5);
 	if (vmlinux_path == NULL)
 		return -1;
@@ -2223,22 +2235,30 @@ static int vmlinux_path__init(void)
 	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
 		goto out_fail;
 	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
-	snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
-		 uts.release);
-	vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
-	if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
-		goto out_fail;
-	++vmlinux_path__nr_entries;
+
+	/* if no rootfs has been given try running kernel version too */
+	if (strlen(symbol_conf.rootfs) == 0) {
+		if (uname(&uts) < 0)
+			return -1;
+
+		snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+		snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux",
+			 uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+		snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
+			 uts.release);
+		vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
+		if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
+			goto out_fail;
+		++vmlinux_path__nr_entries;
+	}
 
 	return 0;
 
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 038f220..a97b6d3 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -85,6 +85,7 @@ struct symbol_conf {
        struct strlist	*dso_list,
 			*comm_list,
 			*sym_list;
+	const char	*rootfs;
 };
 
 extern struct symbol_conf symbol_conf;
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-11-21 18:12 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1290356275-9969-1-git-send-email-y>
2010-11-21 16:34 ` [PATCH] perf tools: Add rootfs option for off-box analysis using specified tree Arnaldo Carvalho de Melo
2010-11-21 17:02   ` David S. Ahern
2010-11-21 18:12     ` Arnaldo Carvalho de Melo
2010-11-21 16:19 David Ahern
  -- strict thread matches above, loose matches on Subject: below --
2010-11-21 16:17 y

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).