diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 15:23:47 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-27 15:23:47 -0700 |
commit | c5617b200ac52e35f7e8cf05a17b0a2d50f6b3e9 (patch) | |
tree | 40d5e99660c77c5791392d349a93113c044dbf14 /tools/perf/util/hist.c | |
parent | cad719d86e9dbd06634eaba6401e022c8101d6b2 (diff) | |
parent | 49c177461bfbedeccbab22bf3905db2f9da7f1c3 (diff) |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (61 commits)
tracing: Add __used annotation to event variable
perf, trace: Fix !x86 build bug
perf report: Support multiple events on the TUI
perf annotate: Fix up usage of the build id cache
x86/mmiotrace: Remove redundant instruction prefix checks
perf annotate: Add TUI interface
perf tui: Remove annotate from popup menu after failure
perf report: Don't start the TUI if -D is used
perf: Fix getline undeclared
perf: Optimize perf_tp_event_match()
perf: Remove more code from the fastpath
perf: Optimize the !vmalloc backed buffer
perf: Optimize perf_output_copy()
perf: Fix wakeup storm for RO mmap()s
perf-record: Share per-cpu buffers
perf-record: Remove -M
perf: Ensure that IOC_OUTPUT isn't used to create multi-writer buffers
perf, trace: Optimize tracepoints by using per-tracepoint-per-cpu hlist to track events
perf, trace: Optimize tracepoints by removing IRQ-disable from perf/tracepoint interaction
perf tui: Allow disabling the TUI on a per command basis in ~/.perfconfig
...
Diffstat (limited to 'tools/perf/util/hist.c')
-rw-r--r-- | tools/perf/util/hist.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 9a71c94f057..cbf7eae2ce0 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -1,4 +1,5 @@ #include "util.h" +#include "build-id.h" #include "hist.h" #include "session.h" #include "sort.h" @@ -988,22 +989,42 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head) struct symbol *sym = self->ms.sym; struct map *map = self->ms.map; struct dso *dso = map->dso; - const char *filename = dso->long_name; + char *filename = dso__build_id_filename(dso, NULL, 0); + bool free_filename = true; char command[PATH_MAX * 2]; FILE *file; + int err = 0; u64 len; - if (!filename) - return -1; + if (filename == NULL) { + if (dso->has_build_id) { + pr_err("Can't annotate %s: not enough memory\n", + sym->name); + return -ENOMEM; + } + goto fallback; + } else if (readlink(filename, command, sizeof(command)) < 0 || + strstr(command, "[kernel.kallsyms]") || + access(filename, R_OK)) { + free(filename); +fallback: + /* + * If we don't have build-ids or the build-id file isn't in the + * cache, or is just a kallsyms file, well, lets hope that this + * DSO is the same as when 'perf record' ran. + */ + filename = dso->long_name; + free_filename = false; + } if (dso->origin == DSO__ORIG_KERNEL) { if (dso->annotate_warned) - return 0; + goto out_free_filename; + err = -ENOENT; dso->annotate_warned = 1; pr_err("Can't annotate %s: No vmlinux file was found in the " - "path:\n", sym->name); - vmlinux_path__fprintf(stderr); - return -1; + "path\n", sym->name); + goto out_free_filename; } 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) file = popen(command, "r"); if (!file) - return -1; + goto out_free_filename; while (!feof(file)) if (hist_entry__parse_objdump_line(self, file, head) < 0) break; pclose(file); - return 0; +out_free_filename: + if (free_filename) + free(filename); + return err; } void hists__inc_nr_events(struct hists *self, u32 type) |