aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/hist.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r--tools/perf/util/hist.c42
1 files changed, 33 insertions, 9 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 9a71c94f057a..cbf7eae2ce09 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1,4 +1,5 @@
1#include "util.h" 1#include "util.h"
2#include "build-id.h"
2#include "hist.h" 3#include "hist.h"
3#include "session.h" 4#include "session.h"
4#include "sort.h" 5#include "sort.h"
@@ -988,22 +989,42 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
988 struct symbol *sym = self->ms.sym; 989 struct symbol *sym = self->ms.sym;
989 struct map *map = self->ms.map; 990 struct map *map = self->ms.map;
990 struct dso *dso = map->dso; 991 struct dso *dso = map->dso;
991 const char *filename = dso->long_name; 992 char *filename = dso__build_id_filename(dso, NULL, 0);
993 bool free_filename = true;
992 char command[PATH_MAX * 2]; 994 char command[PATH_MAX * 2];
993 FILE *file; 995 FILE *file;
996 int err = 0;
994 u64 len; 997 u64 len;
995 998
996 if (!filename) 999 if (filename == NULL) {
997 return -1; 1000 if (dso->has_build_id) {
1001 pr_err("Can't annotate %s: not enough memory\n",
1002 sym->name);
1003 return -ENOMEM;
1004 }
1005 goto fallback;
1006 } else if (readlink(filename, command, sizeof(command)) < 0 ||
1007 strstr(command, "[kernel.kallsyms]") ||
1008 access(filename, R_OK)) {
1009 free(filename);
1010fallback:
1011 /*
1012 * If we don't have build-ids or the build-id file isn't in the
1013 * cache, or is just a kallsyms file, well, lets hope that this
1014 * DSO is the same as when 'perf record' ran.
1015 */
1016 filename = dso->long_name;
1017 free_filename = false;
1018 }
998 1019
999 if (dso->origin == DSO__ORIG_KERNEL) { 1020 if (dso->origin == DSO__ORIG_KERNEL) {
1000 if (dso->annotate_warned) 1021 if (dso->annotate_warned)
1001 return 0; 1022 goto out_free_filename;
1023 err = -ENOENT;
1002 dso->annotate_warned = 1; 1024 dso->annotate_warned = 1;
1003 pr_err("Can't annotate %s: No vmlinux file was found in the " 1025 pr_err("Can't annotate %s: No vmlinux file was found in the "
1004 "path:\n", sym->name); 1026 "path\n", sym->name);
1005 vmlinux_path__fprintf(stderr); 1027 goto out_free_filename;
1006 return -1;
1007 } 1028 }
1008 1029
1009 pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__, 1030 pr_debug("%s: filename=%s, sym=%s, start=%#Lx, end=%#Lx\n", __func__,
@@ -1025,14 +1046,17 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
1025 1046
1026 file = popen(command, "r"); 1047 file = popen(command, "r");
1027 if (!file) 1048 if (!file)
1028 return -1; 1049 goto out_free_filename;
1029 1050
1030 while (!feof(file)) 1051 while (!feof(file))
1031 if (hist_entry__parse_objdump_line(self, file, head) < 0) 1052 if (hist_entry__parse_objdump_line(self, file, head) < 0)
1032 break; 1053 break;
1033 1054
1034 pclose(file); 1055 pclose(file);
1035 return 0; 1056out_free_filename:
1057 if (free_filename)
1058 free(filename);
1059 return err;
1036} 1060}
1037 1061
1038void hists__inc_nr_events(struct hists *self, u32 type) 1062void hists__inc_nr_events(struct hists *self, u32 type)