aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-11-23 13:39:10 -0500
committerIngo Molnar <mingo@elte.hu>2009-11-23 13:51:48 -0500
commitcc612d8199089413719397c9d92e5823da578eac (patch)
treeaec84294a839bc82b738326ed5f338e6ebc47a30
parent1b290d670ffa883b7e062177463a8efd00eaa2c1 (diff)
perf symbols: Look for vmlinux in more places
Now that we can check the buildid to see if it really matches, this can be done safely: vmlinux /boot/vmlinux /boot/vmlinux-<uts.release> /lib/modules/<uts.release>/build/vmlinux /usr/lib/debug/lib/modules/%s/vmlinux More can be added - if you know about distros that put the vmlinux somewhere else please let us know. Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> LKML-Reference: <1259001550-8194-1-git-send-email-acme@infradead.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/builtin-annotate.c3
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-report.c6
-rw-r--r--tools/perf/builtin-sched.c3
-rw-r--r--tools/perf/builtin-top.c3
-rw-r--r--tools/perf/builtin-trace.c3
-rw-r--r--tools/perf/util/data_map.c4
-rw-r--r--tools/perf/util/data_map.h2
-rw-r--r--tools/perf/util/header.c2
-rw-r--r--tools/perf/util/symbol.c113
-rw-r--r--tools/perf/util/symbol.h4
11 files changed, 122 insertions, 23 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 203152729a68..6b13a1ecf1e7 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -37,6 +37,7 @@ static bool use_modules;
37 37
38static unsigned long page_size; 38static unsigned long page_size;
39static unsigned long mmap_window = 32; 39static unsigned long mmap_window = 32;
40const char *vmlinux_name;
40 41
41struct sym_hist { 42struct sym_hist {
42 u64 sum; 43 u64 sum;
@@ -637,7 +638,7 @@ static int __cmd_annotate(void)
637 exit(0); 638 exit(0);
638 } 639 }
639 640
640 if (kernel_maps__init(use_modules) < 0) { 641 if (kernel_maps__init(vmlinux_name, true, use_modules) < 0) {
641 pr_err("failed to create kernel maps for symbol resolution\b"); 642 pr_err("failed to create kernel maps for symbol resolution\b");
642 return -1; 643 return -1;
643 } 644 }
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 4145049e7bf5..5d8aeae50004 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -291,7 +291,7 @@ static int read_events(void)
291 register_idle_thread(); 291 register_idle_thread();
292 register_perf_file_handler(&file_handler); 292 register_perf_file_handler(&file_handler);
293 293
294 return mmap_dispatch_perf_file(&header, input_name, 0, 0, 294 return mmap_dispatch_perf_file(&header, input_name, NULL, false, 0, 0,
295 &cwdlen, &cwd); 295 &cwdlen, &cwd);
296} 296}
297 297
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 7e690f73b516..fe474b7f8ad0 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -52,6 +52,7 @@ static char *pretty_printing_style = default_pretty_printing_style;
52static int exclude_other = 1; 52static int exclude_other = 1;
53 53
54static char callchain_default_opt[] = "fractal,0.5"; 54static char callchain_default_opt[] = "fractal,0.5";
55const char *vmlinux_name;
55 56
56static char *cwd; 57static char *cwd;
57static int cwdlen; 58static int cwdlen;
@@ -925,8 +926,9 @@ static int __cmd_report(void)
925 926
926 register_perf_file_handler(&file_handler); 927 register_perf_file_handler(&file_handler);
927 928
928 ret = mmap_dispatch_perf_file(&header, input_name, force, full_paths, 929 ret = mmap_dispatch_perf_file(&header, input_name, vmlinux_name,
929 &cwdlen, &cwd); 930 !vmlinux_name, force,
931 full_paths, &cwdlen, &cwd);
930 if (ret) 932 if (ret)
931 return ret; 933 return ret;
932 934
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index df44b756cecc..260f57a72ee0 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1718,7 +1718,8 @@ static int read_events(void)
1718 register_idle_thread(); 1718 register_idle_thread();
1719 register_perf_file_handler(&file_handler); 1719 register_perf_file_handler(&file_handler);
1720 1720
1721 return mmap_dispatch_perf_file(&header, input_name, 0, 0, &cwdlen, &cwd); 1721 return mmap_dispatch_perf_file(&header, input_name, NULL, false, 0, 0,
1722 &cwdlen, &cwd);
1722} 1723}
1723 1724
1724static void print_bad_events(void) 1725static void print_bad_events(void)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ea49c2e9dda3..eef9caab6eee 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -79,6 +79,7 @@ static int dump_symtab = 0;
79static bool hide_kernel_symbols = false; 79static bool hide_kernel_symbols = false;
80static bool hide_user_symbols = false; 80static bool hide_user_symbols = false;
81static struct winsize winsize; 81static struct winsize winsize;
82const char *vmlinux_name;
82static const char *graph_line = 83static const char *graph_line =
83 "_____________________________________________________________________" 84 "_____________________________________________________________________"
84 "_____________________________________________________________________"; 85 "_____________________________________________________________________";
@@ -1341,7 +1342,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1341 if (delay_secs < 1) 1342 if (delay_secs < 1)
1342 delay_secs = 1; 1343 delay_secs = 1;
1343 1344
1344 err = kernel_maps__init(true); 1345 err = kernel_maps__init(vmlinux_name, !vmlinux_name, true);
1345 if (err < 0) 1346 if (err < 0)
1346 return err; 1347 return err;
1347 parse_source(sym_filter_entry); 1348 parse_source(sym_filter_entry);
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index d042d656c561..b71198e5dc14 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -131,7 +131,8 @@ static int __cmd_trace(void)
131 register_idle_thread(); 131 register_idle_thread();
132 register_perf_file_handler(&file_handler); 132 register_perf_file_handler(&file_handler);
133 133
134 return mmap_dispatch_perf_file(&header, input_name, 0, 0, &cwdlen, &cwd); 134 return mmap_dispatch_perf_file(&header, input_name, NULL, false,
135 0, 0, &cwdlen, &cwd);
135} 136}
136 137
137static const char * const annotate_usage[] = { 138static const char * const annotate_usage[] = {
diff --git a/tools/perf/util/data_map.c b/tools/perf/util/data_map.c
index e7b6c2bea3de..f318d19b2562 100644
--- a/tools/perf/util/data_map.c
+++ b/tools/perf/util/data_map.c
@@ -101,6 +101,8 @@ out:
101 101
102int mmap_dispatch_perf_file(struct perf_header **pheader, 102int mmap_dispatch_perf_file(struct perf_header **pheader,
103 const char *input_name, 103 const char *input_name,
104 const char *vmlinux_name,
105 bool try_vmlinux_path,
104 int force, 106 int force,
105 int full_paths, 107 int full_paths,
106 int *cwdlen, 108 int *cwdlen,
@@ -171,7 +173,7 @@ int mmap_dispatch_perf_file(struct perf_header **pheader,
171 goto out_delete; 173 goto out_delete;
172 174
173 err = -ENOMEM; 175 err = -ENOMEM;
174 if (kernel_maps__init(true) < 0) { 176 if (kernel_maps__init(vmlinux_name, try_vmlinux_path, true) < 0) {
175 pr_err("failed to setup the kernel maps to resolve symbols\n"); 177 pr_err("failed to setup the kernel maps to resolve symbols\n");
176 goto out_delete; 178 goto out_delete;
177 } 179 }
diff --git a/tools/perf/util/data_map.h b/tools/perf/util/data_map.h
index ae036ecd7625..3f0d21b3819e 100644
--- a/tools/perf/util/data_map.h
+++ b/tools/perf/util/data_map.h
@@ -23,6 +23,8 @@ struct perf_file_handler {
23void register_perf_file_handler(struct perf_file_handler *handler); 23void register_perf_file_handler(struct perf_file_handler *handler);
24int mmap_dispatch_perf_file(struct perf_header **pheader, 24int mmap_dispatch_perf_file(struct perf_header **pheader,
25 const char *input_name, 25 const char *input_name,
26 const char *vmlinux_name,
27 bool try_vmlinux_path,
26 int force, 28 int force,
27 int full_paths, 29 int full_paths,
28 int *cwdlen, 30 int *cwdlen,
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index ac3410b8e9e3..1332f8ec04aa 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -257,7 +257,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
257 * Read the kernel buildid nad the list of loaded modules with 257 * Read the kernel buildid nad the list of loaded modules with
258 * its build_ids: 258 * its build_ids:
259 */ 259 */
260 kernel_maps__init(true); 260 kernel_maps__init(NULL, false, true);
261 261
262 /* Write build-ids */ 262 /* Write build-ids */
263 buildid_sec->offset = lseek(fd, 0, SEEK_CUR); 263 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 74b5b8a16951..44d81d5ae8cf 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -34,6 +34,8 @@ static void kernel_maps__insert(struct map *map);
34static int dso__load_kernel_sym(struct dso *self, struct map *map, 34static int dso__load_kernel_sym(struct dso *self, struct map *map,
35 symbol_filter_t filter); 35 symbol_filter_t filter);
36unsigned int symbol__priv_size; 36unsigned int symbol__priv_size;
37static int vmlinux_path__nr_entries;
38static char **vmlinux_path;
37 39
38static struct rb_root kernel_maps; 40static struct rb_root kernel_maps;
39 41
@@ -1386,15 +1388,43 @@ static int dso__load_vmlinux(struct dso *self, struct map *map,
1386static int dso__load_kernel_sym(struct dso *self, struct map *map, 1388static int dso__load_kernel_sym(struct dso *self, struct map *map,
1387 symbol_filter_t filter) 1389 symbol_filter_t filter)
1388{ 1390{
1389 int err = dso__load_vmlinux(self, map, self->name, filter); 1391 int err;
1392 bool is_kallsyms;
1393
1394 if (vmlinux_path != NULL) {
1395 int i;
1396 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1397 vmlinux_path__nr_entries);
1398 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1399 err = dso__load_vmlinux(self, map, vmlinux_path[i],
1400 filter);
1401 if (err > 0) {
1402 pr_debug("Using %s for symbols\n",
1403 vmlinux_path[i]);
1404 dso__set_long_name(self,
1405 strdup(vmlinux_path[i]));
1406 goto out_fixup;
1407 }
1408 }
1409 }
1410
1411 is_kallsyms = self->long_name[0] == '[';
1412 if (is_kallsyms)
1413 goto do_kallsyms;
1390 1414
1415 err = dso__load_vmlinux(self, map, self->long_name, filter);
1391 if (err <= 0) { 1416 if (err <= 0) {
1417 pr_info("The file %s cannot be used, "
1418 "trying to use /proc/kallsyms...", self->long_name);
1419 sleep(2);
1420do_kallsyms:
1392 err = kernel_maps__load_kallsyms(filter); 1421 err = kernel_maps__load_kallsyms(filter);
1393 if (err > 0) 1422 if (err > 0 && !is_kallsyms)
1394 dso__set_long_name(self, strdup("[kernel.kallsyms]")); 1423 dso__set_long_name(self, strdup("[kernel.kallsyms]"));
1395 } 1424 }
1396 1425
1397 if (err > 0) { 1426 if (err > 0) {
1427out_fixup:
1398 map__fixup_start(map); 1428 map__fixup_start(map);
1399 map__fixup_end(map); 1429 map__fixup_end(map);
1400 } 1430 }
@@ -1403,9 +1433,7 @@ static int dso__load_kernel_sym(struct dso *self, struct map *map,
1403} 1433}
1404 1434
1405LIST_HEAD(dsos); 1435LIST_HEAD(dsos);
1406struct dso *vdso; 1436struct dso *vdso;
1407
1408const char *vmlinux_name = "vmlinux";
1409 1437
1410static void dsos__add(struct dso *dso) 1438static void dsos__add(struct dso *dso)
1411{ 1439{
@@ -1457,9 +1485,9 @@ size_t dsos__fprintf_buildid(FILE *fp)
1457 return ret; 1485 return ret;
1458} 1486}
1459 1487
1460static int kernel_maps__create_kernel_map(void) 1488static int kernel_maps__create_kernel_map(const char *vmlinux_name)
1461{ 1489{
1462 struct dso *kernel = dso__new(vmlinux_name); 1490 struct dso *kernel = dso__new(vmlinux_name ?: "[kernel.kallsyms]");
1463 1491
1464 if (kernel == NULL) 1492 if (kernel == NULL)
1465 return -1; 1493 return -1;
@@ -1468,10 +1496,10 @@ static int kernel_maps__create_kernel_map(void)
1468 if (kernel_map == NULL) 1496 if (kernel_map == NULL)
1469 goto out_delete_kernel_dso; 1497 goto out_delete_kernel_dso;
1470 1498
1471 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip; 1499 kernel_map->map_ip = kernel_map->unmap_ip = identity__map_ip;
1500 kernel->short_name = "[kernel]";
1501 kernel->kernel = 1;
1472 1502
1473 kernel->short_name = "[kernel]";
1474 kernel->kernel = 1;
1475 vdso = dso__new("[vdso]"); 1503 vdso = dso__new("[vdso]");
1476 if (vdso == NULL) 1504 if (vdso == NULL)
1477 goto out_delete_kernel_map; 1505 goto out_delete_kernel_map;
@@ -1494,11 +1522,72 @@ out_delete_kernel_dso:
1494 return -1; 1522 return -1;
1495} 1523}
1496 1524
1497int kernel_maps__init(bool use_modules) 1525static void vmlinux_path__exit(void)
1526{
1527 while (--vmlinux_path__nr_entries >= 0) {
1528 free(vmlinux_path[vmlinux_path__nr_entries]);
1529 vmlinux_path[vmlinux_path__nr_entries] = NULL;
1530 }
1531
1532 free(vmlinux_path);
1533 vmlinux_path = NULL;
1534}
1535
1536static int vmlinux_path__init(void)
1537{
1538 struct utsname uts;
1539 char bf[PATH_MAX];
1540
1541 if (uname(&uts) < 0)
1542 return -1;
1543
1544 vmlinux_path = malloc(sizeof(char *) * 5);
1545 if (vmlinux_path == NULL)
1546 return -1;
1547
1548 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
1549 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1550 goto out_fail;
1551 ++vmlinux_path__nr_entries;
1552 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
1553 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1554 goto out_fail;
1555 ++vmlinux_path__nr_entries;
1556 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
1557 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1558 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1559 goto out_fail;
1560 ++vmlinux_path__nr_entries;
1561 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
1562 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1563 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1564 goto out_fail;
1565 ++vmlinux_path__nr_entries;
1566 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
1567 uts.release);
1568 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
1569 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
1570 goto out_fail;
1571 ++vmlinux_path__nr_entries;
1572
1573 return 0;
1574
1575out_fail:
1576 vmlinux_path__exit();
1577 return -1;
1578}
1579
1580int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path,
1581 bool use_modules)
1498{ 1582{
1499 if (kernel_maps__create_kernel_map() < 0) 1583 if (try_vmlinux_path && vmlinux_path__init() < 0)
1500 return -1; 1584 return -1;
1501 1585
1586 if (kernel_maps__create_kernel_map(vmlinux_name) < 0) {
1587 vmlinux_path__exit();
1588 return -1;
1589 }
1590
1502 if (use_modules && kernel_maps__create_module_maps() < 0) 1591 if (use_modules && kernel_maps__create_module_maps() < 0)
1503 pr_debug("Failed to load list of modules in use, " 1592 pr_debug("Failed to load list of modules in use, "
1504 "continuing...\n"); 1593 "continuing...\n");
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 7a129047c47d..8c4d026e067a 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -93,7 +93,8 @@ int sysfs__read_build_id(const char *filename, void *bf, size_t size);
93bool dsos__read_build_ids(void); 93bool dsos__read_build_ids(void);
94int build_id__sprintf(u8 *self, int len, char *bf); 94int build_id__sprintf(u8 *self, int len, char *bf);
95 95
96int kernel_maps__init(bool use_modules); 96int kernel_maps__init(const char *vmlinux_name, bool try_vmlinux_path,
97 bool use_modules);
97size_t kernel_maps__fprintf(FILE *fp); 98size_t kernel_maps__fprintf(FILE *fp);
98 99
99void symbol__init(unsigned int priv_size); 100void symbol__init(unsigned int priv_size);
@@ -101,5 +102,4 @@ void symbol__init(unsigned int priv_size);
101extern struct list_head dsos; 102extern struct list_head dsos;
102extern struct map *kernel_map; 103extern struct map *kernel_map;
103extern struct dso *vdso; 104extern struct dso *vdso;
104extern const char *vmlinux_name;
105#endif /* __PERF_SYMBOL */ 105#endif /* __PERF_SYMBOL */