aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-top.c35
-rw-r--r--tools/perf/util/annotate.c4
-rw-r--r--tools/perf/util/map.c1
-rw-r--r--tools/perf/util/map.h1
4 files changed, 38 insertions, 3 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index fab0a1c7e872..8ef59f8262bb 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -42,6 +42,7 @@
42#include "util/debug.h" 42#include "util/debug.h"
43 43
44#include <assert.h> 44#include <assert.h>
45#include <elf.h>
45#include <fcntl.h> 46#include <fcntl.h>
46 47
47#include <stdio.h> 48#include <stdio.h>
@@ -59,6 +60,7 @@
59#include <sys/prctl.h> 60#include <sys/prctl.h>
60#include <sys/wait.h> 61#include <sys/wait.h>
61#include <sys/uio.h> 62#include <sys/uio.h>
63#include <sys/utsname.h>
62#include <sys/mman.h> 64#include <sys/mman.h>
63 65
64#include <linux/unistd.h> 66#include <linux/unistd.h>
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
162 symbol__annotate_zero_histograms(sym); 164 symbol__annotate_zero_histograms(sym);
163} 165}
164 166
167static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
168{
169 struct utsname uts;
170 int err = uname(&uts);
171
172 ui__warning("Out of bounds address found:\n\n"
173 "Addr: %" PRIx64 "\n"
174 "DSO: %s %c\n"
175 "Map: %" PRIx64 "-%" PRIx64 "\n"
176 "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
177 "Arch: %s\n"
178 "Kernel: %s\n"
179 "Tools: %s\n\n"
180 "Not all samples will be on the annotation output.\n\n"
181 "Please report to linux-kernel@vger.kernel.org\n",
182 ip, map->dso->long_name, dso__symtab_origin(map->dso),
183 map->start, map->end, sym->start, sym->end,
184 sym->binding == STB_GLOBAL ? 'g' :
185 sym->binding == STB_LOCAL ? 'l' : 'w', sym->name,
186 err ? "[unknown]" : uts.machine,
187 err ? "[unknown]" : uts.release, perf_version_string);
188 if (use_browser <= 0)
189 sleep(5);
190
191 map->erange_warned = true;
192}
193
165static void perf_top__record_precise_ip(struct perf_top *top, 194static void perf_top__record_precise_ip(struct perf_top *top,
166 struct hist_entry *he, 195 struct hist_entry *he,
167 int counter, u64 ip) 196 int counter, u64 ip)
168{ 197{
169 struct annotation *notes; 198 struct annotation *notes;
170 struct symbol *sym; 199 struct symbol *sym;
200 int err;
171 201
172 if (he == NULL || he->ms.sym == NULL || 202 if (he == NULL || he->ms.sym == NULL ||
173 ((top->sym_filter_entry == NULL || 203 ((top->sym_filter_entry == NULL ||
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
189 } 219 }
190 220
191 ip = he->ms.map->map_ip(he->ms.map, ip); 221 ip = he->ms.map->map_ip(he->ms.map, ip);
192 symbol__inc_addr_samples(sym, he->ms.map, counter, ip); 222 err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
193 223
194 pthread_mutex_unlock(&notes->lock); 224 pthread_mutex_unlock(&notes->lock);
225
226 if (err == -ERANGE && !he->ms.map->erange_warned)
227 ui__warn_map_erange(he->ms.map, sym, ip);
195} 228}
196 229
197static void perf_top__show_details(struct perf_top *top) 230static void perf_top__show_details(struct perf_top *top)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 70f5a4dc17e9..08c6d138a655 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -64,8 +64,8 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,
64 64
65 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr)); 65 pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));
66 66
67 if (addr > sym->end) 67 if (addr < sym->start || addr > sym->end)
68 return 0; 68 return -ERANGE;
69 69
70 offset = addr - sym->start; 70 offset = addr - sym->start;
71 h = annotation__histogram(notes, evidx); 71 h = annotation__histogram(notes, evidx);
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index dea6d1c1a954..35ae56864e4f 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -38,6 +38,7 @@ void map__init(struct map *self, enum map_type type,
38 RB_CLEAR_NODE(&self->rb_node); 38 RB_CLEAR_NODE(&self->rb_node);
39 self->groups = NULL; 39 self->groups = NULL;
40 self->referenced = false; 40 self->referenced = false;
41 self->erange_warned = false;
41} 42}
42 43
43struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, 44struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index b100c20b7f94..81371bad4ef0 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -33,6 +33,7 @@ struct map {
33 u64 end; 33 u64 end;
34 u8 /* enum map_type */ type; 34 u8 /* enum map_type */ type;
35 bool referenced; 35 bool referenced;
36 bool erange_warned;
36 u32 priv; 37 u32 priv;
37 u64 pgoff; 38 u64 pgoff;
38 39