|
@@ -42,6 +42,7 @@
|
|
#include "util/debug.h"
|
|
#include "util/debug.h"
|
|
|
|
|
|
#include <assert.h>
|
|
#include <assert.h>
|
|
|
|
+#include <elf.h>
|
|
#include <fcntl.h>
|
|
#include <fcntl.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdio.h>
|
|
@@ -59,6 +60,7 @@
|
|
#include <sys/prctl.h>
|
|
#include <sys/prctl.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/uio.h>
|
|
#include <sys/uio.h>
|
|
|
|
+#include <sys/utsname.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/mman.h>
|
|
|
|
|
|
#include <linux/unistd.h>
|
|
#include <linux/unistd.h>
|
|
@@ -162,12 +164,40 @@ static void __zero_source_counters(struct hist_entry *he)
|
|
symbol__annotate_zero_histograms(sym);
|
|
symbol__annotate_zero_histograms(sym);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static void ui__warn_map_erange(struct map *map, struct symbol *sym, u64 ip)
|
|
|
|
+{
|
|
|
|
+ struct utsname uts;
|
|
|
|
+ int err = uname(&uts);
|
|
|
|
+
|
|
|
|
+ ui__warning("Out of bounds address found:\n\n"
|
|
|
|
+ "Addr: %" PRIx64 "\n"
|
|
|
|
+ "DSO: %s %c\n"
|
|
|
|
+ "Map: %" PRIx64 "-%" PRIx64 "\n"
|
|
|
|
+ "Symbol: %" PRIx64 "-%" PRIx64 " %c %s\n"
|
|
|
|
+ "Arch: %s\n"
|
|
|
|
+ "Kernel: %s\n"
|
|
|
|
+ "Tools: %s\n\n"
|
|
|
|
+ "Not all samples will be on the annotation output.\n\n"
|
|
|
|
+ "Please report to linux-kernel@vger.kernel.org\n",
|
|
|
|
+ ip, map->dso->long_name, dso__symtab_origin(map->dso),
|
|
|
|
+ map->start, map->end, sym->start, sym->end,
|
|
|
|
+ sym->binding == STB_GLOBAL ? 'g' :
|
|
|
|
+ sym->binding == STB_LOCAL ? 'l' : 'w', sym->name,
|
|
|
|
+ err ? "[unknown]" : uts.machine,
|
|
|
|
+ err ? "[unknown]" : uts.release, perf_version_string);
|
|
|
|
+ if (use_browser <= 0)
|
|
|
|
+ sleep(5);
|
|
|
|
+
|
|
|
|
+ map->erange_warned = true;
|
|
|
|
+}
|
|
|
|
+
|
|
static void perf_top__record_precise_ip(struct perf_top *top,
|
|
static void perf_top__record_precise_ip(struct perf_top *top,
|
|
struct hist_entry *he,
|
|
struct hist_entry *he,
|
|
int counter, u64 ip)
|
|
int counter, u64 ip)
|
|
{
|
|
{
|
|
struct annotation *notes;
|
|
struct annotation *notes;
|
|
struct symbol *sym;
|
|
struct symbol *sym;
|
|
|
|
+ int err;
|
|
|
|
|
|
if (he == NULL || he->ms.sym == NULL ||
|
|
if (he == NULL || he->ms.sym == NULL ||
|
|
((top->sym_filter_entry == NULL ||
|
|
((top->sym_filter_entry == NULL ||
|
|
@@ -189,9 +219,12 @@ static void perf_top__record_precise_ip(struct perf_top *top,
|
|
}
|
|
}
|
|
|
|
|
|
ip = he->ms.map->map_ip(he->ms.map, ip);
|
|
ip = he->ms.map->map_ip(he->ms.map, ip);
|
|
- symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
|
|
|
|
|
|
+ err = symbol__inc_addr_samples(sym, he->ms.map, counter, ip);
|
|
|
|
|
|
pthread_mutex_unlock(¬es->lock);
|
|
pthread_mutex_unlock(¬es->lock);
|
|
|
|
+
|
|
|
|
+ if (err == -ERANGE && !he->ms.map->erange_warned)
|
|
|
|
+ ui__warn_map_erange(he->ms.map, sym, ip);
|
|
}
|
|
}
|
|
|
|
|
|
static void perf_top__show_details(struct perf_top *top)
|
|
static void perf_top__show_details(struct perf_top *top)
|
|
@@ -615,6 +648,7 @@ process_hotkey:
|
|
|
|
|
|
/* Tag samples to be skipped. */
|
|
/* Tag samples to be skipped. */
|
|
static const char *skip_symbols[] = {
|
|
static const char *skip_symbols[] = {
|
|
|
|
+ "intel_idle",
|
|
"default_idle",
|
|
"default_idle",
|
|
"native_safe_halt",
|
|
"native_safe_halt",
|
|
"cpu_idle",
|
|
"cpu_idle",
|