* [PATCH] perf, tools: Support srccode output
@ 2018-12-04 0:18 Andi Kleen
2018-12-05 12:28 ` Jiri Olsa
0 siblings, 1 reply; 6+ messages in thread
From: Andi Kleen @ 2018-12-04 0:18 UTC (permalink / raw)
To: acme; +Cc: jolsa, linux-perf-users, linux-kernel, Andi Kleen
From: Andi Kleen <ak@linux.intel.com>
When looking at PT or brstackinsn traces with perf script
it can be very useful to see the source code. This adds a simple
facility to print them with perf script, if the information
is available through dwarf
% perf record ...
% perf script -F insn,ip,sym,srccode
...
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004c6 main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004cd main
5 for (i = 0; i < 10000000; i++)
4004b3 main
6 v++;
% perf record -b ...
% perf script -F insn,ip,sym,srccode,brstackinsn
...
main+22:
0000000000400543 insn: e8 ca ff ff ff # PRED
|18 f1();
f1:
0000000000400512 insn: 55
|10 {
0000000000400513 insn: 48 89 e5
0000000000400516 insn: b8 00 00 00 00
|11 f2();
000000000040051b insn: e8 d6 ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
0000000000400500 insn: 8b 0d 2a 0b 20 00
0000000000400506 insn: 99
0000000000400507 insn: f7 f9
0000000000400509 insn: 89 05 29 0b 20 00
000000000040050f insn: 90
|7 }
0000000000400510 insn: 5d
0000000000400511 insn: c3 # PRED
f1+14:
0000000000400520 insn: b8 00 00 00 00
|12 f2();
0000000000400525 insn: e8 cc ff ff ff # PRED
f2:
00000000004004f6 insn: 55
|5 {
00000000004004f7 insn: 48 89 e5
00000000004004fa insn: 8b 05 2c 0b 20 00
|6 c = a / b;
Not supported for callchains currently, would need some
layout changes there.
Signed-off-by: Andi Kleen <ak@linux.intel.com>
---
tools/perf/Documentation/perf-script.txt | 2 +-
tools/perf/builtin-script.c | 47 +++++-
tools/perf/util/Build | 1 +
tools/perf/util/evsel_fprintf.c | 1 +
tools/perf/util/map.c | 49 ++++++
tools/perf/util/map.h | 16 ++
tools/perf/util/srccode.c | 186 +++++++++++++++++++++++
tools/perf/util/srccode.h | 7 +
tools/perf/util/srcline.c | 28 ++++
tools/perf/util/srcline.h | 1 +
tools/perf/util/thread.c | 2 +
tools/perf/util/thread.h | 2 +
12 files changed, 339 insertions(+), 3 deletions(-)
create mode 100644 tools/perf/util/srccode.c
create mode 100644 tools/perf/util/srccode.h
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index a2b37ce48094..9e4def08d569 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -117,7 +117,7 @@ OPTIONS
Comma separated list of fields to print. Options are:
comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr, symoff,
srcline, period, iregs, uregs, brstack, brstacksym, flags, bpf-output, brstackinsn,
- brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc.
+ brstackoff, callindent, insn, insnlen, synth, phys_addr, metric, misc, srccode.
Field list can be prepended with the type, trace, sw or hw,
to indicate to which event type the field list applies.
e.g., -F sw:comm,tid,time,ip,sym and -F trace:time,cpu,trace
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 04913136bac9..fa6f86b98c76 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -96,6 +96,7 @@ enum perf_output_field {
PERF_OUTPUT_UREGS = 1U << 27,
PERF_OUTPUT_METRIC = 1U << 28,
PERF_OUTPUT_MISC = 1U << 29,
+ PERF_OUTPUT_SRCCODE = 1U << 30,
};
struct output_option {
@@ -132,6 +133,7 @@ struct output_option {
{.str = "phys_addr", .field = PERF_OUTPUT_PHYS_ADDR},
{.str = "metric", .field = PERF_OUTPUT_METRIC},
{.str = "misc", .field = PERF_OUTPUT_MISC},
+ {.str = "srccode", .field = PERF_OUTPUT_SRCCODE},
};
enum {
@@ -424,7 +426,7 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
pr_err("Display of DSO requested but no address to convert.\n");
return -EINVAL;
}
- if (PRINT_FIELD(SRCLINE) && !PRINT_FIELD(IP)) {
+ if ((PRINT_FIELD(SRCLINE) || PRINT_FIELD(SRCCODE)) && !PRINT_FIELD(IP)) {
pr_err("Display of source line number requested but sample IP is not\n"
"selected. Hence, no address to lookup the source line number.\n");
return -EINVAL;
@@ -907,6 +909,22 @@ static int grab_bb(u8 *buffer, u64 start, u64 end,
return len;
}
+static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
+{
+ struct addr_location al;
+ int ret = 0;
+
+ memset(&al, 0, sizeof(al));
+ thread__find_map(thread, cpumode, addr, &al);
+ if (!al.map)
+ return 0;
+ ret = map__fprintf_srccode(al.map, al.addr, stdout,
+ &thread->srccode_state);
+ if (ret)
+ ret += printf("\n");
+ return ret;
+}
+
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
struct perf_insn *x, u8 *inbuf, int len,
int insn, FILE *fp, int *total_cycles)
@@ -998,6 +1016,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
x.cpumode, x.cpu, &lastsym, attr, fp);
printed += ip__fprintf_jump(br->entries[nr - 1].from, &br->entries[nr - 1],
&x, buffer, len, 0, fp, &total_cycles);
+ if (PRINT_FIELD(SRCCODE))
+ printed += print_srccode(thread, x.cpumode, br->entries[nr - 1].from);
}
/* Print all blocks */
@@ -1027,12 +1047,16 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
if (ip == end) {
printed += ip__fprintf_jump(ip, &br->entries[i], &x, buffer + off, len - off, insn, fp,
&total_cycles);
+ if (PRINT_FIELD(SRCCODE))
+ printed += print_srccode(thread, x.cpumode, ip);
break;
} else {
printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", ip,
dump_insn(&x, ip, buffer + off, len - off, &ilen));
if (ilen == 0)
break;
+ if (PRINT_FIELD(SRCCODE))
+ print_srccode(thread, x.cpumode, ip);
insn++;
}
}
@@ -1063,6 +1087,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip,
dump_insn(&x, sample->ip, buffer, len, NULL));
+ if (PRINT_FIELD(SRCCODE))
+ print_srccode(thread, x.cpumode, sample->ip);
goto out;
}
for (off = 0; off <= end - start; off += ilen) {
@@ -1070,6 +1096,8 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
dump_insn(&x, start + off, buffer + off, len - off, &ilen));
if (ilen == 0)
break;
+ if (PRINT_FIELD(SRCCODE))
+ print_srccode(thread, x.cpumode, start + off);
}
out:
return printed;
@@ -1252,7 +1280,16 @@ static int perf_sample__fprintf_bts(struct perf_sample *sample,
printed += map__fprintf_srcline(al->map, al->addr, "\n ", fp);
printed += perf_sample__fprintf_insn(sample, attr, thread, machine, fp);
- return printed + fprintf(fp, "\n");
+ printed += fprintf(fp, "\n");
+ if (PRINT_FIELD(SRCCODE)) {
+ int ret = map__fprintf_srccode(al->map, al->addr, stdout,
+ &thread->srccode_state);
+ if (ret) {
+ printed += ret;
+ printed += printf("\n");
+ }
+ }
+ return printed;
}
static struct {
@@ -1792,6 +1829,12 @@ static void process_event(struct perf_script *script,
fprintf(fp, "%16" PRIx64, sample->phys_addr);
fprintf(fp, "\n");
+ if (PRINT_FIELD(SRCCODE)) {
+ if (map__fprintf_srccode(al->map, al->addr, stdout,
+ &thread->srccode_state))
+ printf("\n");
+ }
+
if (PRINT_FIELD(METRIC))
perf_sample__fprint_metric(script, thread, evsel, sample, fp);
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index b7bf201fe8a8..af72be7f5b3b 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -77,6 +77,7 @@ libperf-y += stat-shadow.o
libperf-y += stat-display.o
libperf-y += record.o
libperf-y += srcline.o
+libperf-y += srccode.o
libperf-y += data.o
libperf-y += tsc.o
libperf-y += cloexec.o
diff --git a/tools/perf/util/evsel_fprintf.c b/tools/perf/util/evsel_fprintf.c
index 0d0a4c6f368b..95ea147f9e18 100644
--- a/tools/perf/util/evsel_fprintf.c
+++ b/tools/perf/util/evsel_fprintf.c
@@ -173,6 +173,7 @@ int sample__fprintf_callchain(struct perf_sample *sample, int left_alignment,
if (!print_oneline)
printed += fprintf(fp, "\n");
+ /* Add srccode here too? */
if (symbol_conf.bt_stop_list &&
node->sym &&
strlist__has_entry(symbol_conf.bt_stop_list,
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 781eed8e3265..f8a0e85f2710 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -19,6 +19,7 @@
#include "srcline.h"
#include "namespaces.h"
#include "unwind.h"
+#include "srccode.h"
static void __maps__insert(struct maps *maps, struct map *map);
static void __maps__insert_name(struct maps *maps, struct map *map);
@@ -421,6 +422,54 @@ int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
return ret;
}
+int map__fprintf_srccode(struct map *map, u64 addr,
+ FILE *fp,
+ struct srccode_state *state)
+{
+ char *srcfile;
+ int ret = 0;
+ unsigned line;
+ int len;
+ char *srccode;
+
+ if (!map || !map->dso)
+ return 0;
+ srcfile = get_srcline_split(map->dso,
+ map__rip_2objdump(map, addr),
+ &line);
+ if (!srcfile)
+ return 0;
+
+ /* Avoid redundant printing */
+ if (state &&
+ state->srcfile &&
+ !strcmp(state->srcfile, srcfile) &&
+ state->line == line) {
+ free(srcfile);
+ return 0;
+ }
+
+ srccode = find_sourceline(srcfile, line, &len);
+ if (!srccode)
+ goto out_free_line;
+
+ ret = fprintf(fp, "|%-8d %.*s", line, len, srccode);
+ state->srcfile = srcfile;
+ state->line = line;
+ return ret;
+
+out_free_line:
+ free(srcfile);
+ return ret;
+}
+
+
+void srccode_state_free(struct srccode_state *state)
+{
+ zfree(&state->srcfile);
+ state->line = 0;
+}
+
/**
* map__rip_2objdump - convert symbol start address to objdump address.
* @map: memory map
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h
index 5c792c90fc4c..09282aa45c80 100644
--- a/tools/perf/util/map.h
+++ b/tools/perf/util/map.h
@@ -174,6 +174,22 @@ char *map__srcline(struct map *map, u64 addr, struct symbol *sym);
int map__fprintf_srcline(struct map *map, u64 addr, const char *prefix,
FILE *fp);
+struct srccode_state {
+ char *srcfile;
+ unsigned line;
+};
+
+static inline void srccode_state_init(struct srccode_state *state)
+{
+ state->srcfile = NULL;
+ state->line = 0;
+}
+
+void srccode_state_free(struct srccode_state *state);
+
+int map__fprintf_srccode(struct map *map, u64 addr,
+ FILE *fp, struct srccode_state *state);
+
int map__load(struct map *map);
struct symbol *map__find_symbol(struct map *map, u64 addr);
struct symbol *map__find_symbol_by_name(struct map *map, const char *name);
diff --git a/tools/perf/util/srccode.c b/tools/perf/util/srccode.c
new file mode 100644
index 000000000000..c22f6a3aa6ba
--- /dev/null
+++ b/tools/perf/util/srccode.c
@@ -0,0 +1,186 @@
+/*
+ * Manage printing of source lines
+ * Copyright (c) 2017, Intel Corporation.
+ * Author: Andi Kleen
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+#include "linux/list.h"
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <assert.h>
+#include <string.h>
+#include "srccode.h"
+#include "debug.h"
+#include "util.h"
+
+#define MAXSRCCACHE (32*1024*1024)
+#define MAXSRCFILES 64
+#define SRC_HTAB_SZ 64
+
+struct srcfile {
+ struct hlist_node hash_nd;
+ struct list_head nd;
+ char *fn;
+ char **lines;
+ char *map;
+ unsigned numlines;
+ size_t maplen;
+};
+
+static struct hlist_head srcfile_htab[SRC_HTAB_SZ];
+static LIST_HEAD(srcfile_list);
+static long map_total_sz;
+static int num_srcfiles;
+
+static unsigned shash(unsigned char *s)
+{
+ unsigned h = 0;
+ while (*s)
+ h = 65599 * h + *s++;
+ return h ^ (h >> 16);
+}
+
+static int countlines(char *map, int maplen)
+{
+ int numl;
+ char *end = map + maplen;
+ char *p = map;
+
+ if (maplen == 0)
+ return 0;
+ numl = 0;
+ while (p < end && (p = memchr(p, '\n', end - p)) != NULL) {
+ numl++;
+ p++;
+ }
+ if (p < end)
+ numl++;
+ return numl;
+}
+
+static void fill_lines(char **lines, int maxline, char *map, int maplen)
+{
+ int l;
+ char *end = map + maplen;
+ char *p = map;
+
+ if (maplen == 0 || maxline == 0)
+ return;
+ l = 0;
+ lines[l++] = map;
+ while (p < end && (p = memchr(p, '\n', end - p)) != NULL) {
+ if (l >= maxline)
+ return;
+ lines[l++] = ++p;
+ }
+ if (p < end)
+ lines[l] = p;
+}
+
+static void free_srcfile(struct srcfile *sf)
+{
+ list_del(&sf->nd);
+ hlist_del(&sf->hash_nd);
+ map_total_sz -= sf->maplen;
+ munmap(sf->map, sf->maplen);
+ free(sf->lines);
+ free(sf->fn);
+ free(sf);
+ num_srcfiles--;
+}
+
+static struct srcfile *find_srcfile(char *fn)
+{
+ struct stat st;
+ struct srcfile *h;
+ int fd;
+ unsigned long sz;
+ unsigned hval = shash((unsigned char *)fn) % SRC_HTAB_SZ;
+
+ hlist_for_each_entry (h, &srcfile_htab[hval], hash_nd) {
+ if (!strcmp(fn, h->fn)) {
+ /* Move to front */
+ list_del(&h->nd);
+ list_add(&h->nd, &srcfile_list);
+ return h;
+ }
+ }
+
+ /* Only prune if there is more than one entry */
+ while ((num_srcfiles > MAXSRCFILES || map_total_sz > MAXSRCCACHE) &&
+ srcfile_list.next != &srcfile_list) {
+ assert(!list_empty(&srcfile_list));
+ h = list_entry(srcfile_list.prev, struct srcfile, nd);
+ free_srcfile(h);
+ }
+
+ fd = open(fn, O_RDONLY);
+ if (fd < 0 || fstat(fd, &st) < 0) {
+ pr_debug("cannot open source file %s\n", fn);
+ return NULL;
+ }
+
+ h = malloc(sizeof(struct srcfile));
+ if (!h)
+ return NULL;
+
+ h->fn = strdup(fn);
+ if (!h->fn)
+ goto out_h;
+
+ h->maplen = st.st_size;
+ sz = (h->maplen + page_size - 1) & ~(page_size - 1);
+ h->map = mmap(NULL, sz, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+ if (h->map == (char *)-1) {
+ pr_debug("cannot mmap source file %s\n", fn);
+ goto out_fn;
+ }
+ h->numlines = countlines(h->map, h->maplen);
+ h->lines = calloc(h->numlines, sizeof(char *));
+ if (!h->lines)
+ goto out_map;
+ fill_lines(h->lines, h->numlines, h->map, h->maplen);
+ list_add(&h->nd, &srcfile_list);
+ hlist_add_head(&h->hash_nd, &srcfile_htab[hval]);
+ map_total_sz += h->maplen;
+ num_srcfiles++;
+ return h;
+
+out_map:
+ munmap(h->map, sz);
+out_fn:
+ free(h->fn);
+out_h:
+ free(h);
+ return NULL;
+}
+
+/* Result is not 0 terminated */
+char *find_sourceline(char *fn, unsigned line, int *lenp)
+{
+ char *l, *p;
+ struct srcfile *sf = find_srcfile(fn);
+ if (!sf)
+ return NULL;
+ line--;
+ if (line >= sf->numlines)
+ return NULL;
+ l = sf->lines[line];
+ if (!l)
+ return NULL;
+ p = memchr(l, '\n', sf->map + sf->maplen - l);
+ *lenp = p - l;
+ return l;
+}
diff --git a/tools/perf/util/srccode.h b/tools/perf/util/srccode.h
new file mode 100644
index 000000000000..e500a746d5f1
--- /dev/null
+++ b/tools/perf/util/srccode.h
@@ -0,0 +1,7 @@
+#ifndef SRCCODE_H
+#define SRCCODE_H 1
+
+/* Result is not 0 terminated */
+char *find_sourceline(char *fn, unsigned line, int *lenp);
+
+#endif
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index e767c4a9d4d2..dc86597d0cc4 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -548,6 +548,34 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
return srcline;
}
+/* Returns filename and fills in line number in line */
+char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line)
+{
+ char *file = NULL;
+ const char *dso_name;
+
+ if (!dso->has_srcline)
+ goto out;
+
+ dso_name = dso__name(dso);
+ if (dso_name == NULL)
+ goto out;
+
+ if (!addr2line(dso_name, addr, &file, line, dso, true, NULL, NULL))
+ goto out;
+
+ dso->a2l_fails = 0;
+ return file;
+
+out:
+ if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) {
+ dso->has_srcline = 0;
+ dso__free_a2l(dso);
+ }
+
+ return NULL;
+}
+
void free_srcline(char *srcline)
{
if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0)
diff --git a/tools/perf/util/srcline.h b/tools/perf/util/srcline.h
index b2bb5502fd62..5762212dc342 100644
--- a/tools/perf/util/srcline.h
+++ b/tools/perf/util/srcline.h
@@ -16,6 +16,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
bool show_sym, bool show_addr, bool unwind_inlines,
u64 ip);
void free_srcline(char *srcline);
+char *get_srcline_split(struct dso *dso, u64 addr, unsigned *line);
/* insert the srcline into the DSO, which will take ownership */
void srcline__tree_insert(struct rb_root *tree, u64 addr, char *srcline);
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 3d9ed7d0e281..c83372329f89 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -64,6 +64,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
RB_CLEAR_NODE(&thread->rb_node);
/* Thread holds first ref to nsdata. */
thread->nsinfo = nsinfo__new(pid);
+ srccode_state_init(&thread->srccode_state);
}
return thread;
@@ -103,6 +104,7 @@ void thread__delete(struct thread *thread)
unwind__finish_access(thread);
nsinfo__zput(thread->nsinfo);
+ srccode_state_free(&thread->srccode_state);
exit_rwsem(&thread->namespaces_lock);
exit_rwsem(&thread->comm_lock);
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 30e2b4c165fe..a4a56d5e98c7 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -8,6 +8,7 @@
#include <unistd.h>
#include <sys/types.h>
#include "symbol.h"
+#include "map.h"
#include <strlist.h>
#include <intlist.h>
#include "rwsem.h"
@@ -38,6 +39,7 @@ struct thread {
void *priv;
struct thread_stack *ts;
struct nsinfo *nsinfo;
+ struct srccode_state srccode_state;
#ifdef HAVE_LIBUNWIND_SUPPORT
void *addr_space;
struct unwind_libunwind_ops *unwind_libunwind_ops;
--
2.17.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] perf, tools: Support srccode output
2018-12-04 0:18 [PATCH] perf, tools: Support srccode output Andi Kleen
@ 2018-12-05 12:28 ` Jiri Olsa
2018-12-05 16:54 ` Arnaldo Carvalho de Melo
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Jiri Olsa @ 2018-12-05 12:28 UTC (permalink / raw)
To: Andi Kleen; +Cc: acme, jolsa, linux-perf-users, linux-kernel, Andi Kleen
On Mon, Dec 03, 2018 at 04:18:48PM -0800, Andi Kleen wrote:
> From: Andi Kleen <ak@linux.intel.com>
>
> When looking at PT or brstackinsn traces with perf script
> it can be very useful to see the source code. This adds a simple
> facility to print them with perf script, if the information
> is available through dwarf
>
> % perf record ...
> % perf script -F insn,ip,sym,srccode
> ...
>
> 4004c6 main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004c6 main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004cd main
> 5 for (i = 0; i < 10000000; i++)
> 4004b3 main
> 6 v++;
>
> % perf record -b ...
> % perf script -F insn,ip,sym,srccode,brstackinsn
>
> ...
> main+22:
> 0000000000400543 insn: e8 ca ff ff ff # PRED
> |18 f1();
> f1:
> 0000000000400512 insn: 55
> |10 {
> 0000000000400513 insn: 48 89 e5
> 0000000000400516 insn: b8 00 00 00 00
> |11 f2();
> 000000000040051b insn: e8 d6 ff ff ff # PRED
> f2:
> 00000000004004f6 insn: 55
> |5 {
> 00000000004004f7 insn: 48 89 e5
> 00000000004004fa insn: 8b 05 2c 0b 20 00
> |6 c = a / b;
> 0000000000400500 insn: 8b 0d 2a 0b 20 00
> 0000000000400506 insn: 99
> 0000000000400507 insn: f7 f9
> 0000000000400509 insn: 89 05 29 0b 20 00
> 000000000040050f insn: 90
> |7 }
> 0000000000400510 insn: 5d
> 0000000000400511 insn: c3 # PRED
> f1+14:
> 0000000000400520 insn: b8 00 00 00 00
> |12 f2();
> 0000000000400525 insn: e8 cc ff ff ff # PRED
> f2:
> 00000000004004f6 insn: 55
> |5 {
> 00000000004004f7 insn: 48 89 e5
> 00000000004004fa insn: 8b 05 2c 0b 20 00
> |6 c = a / b;
>
> Not supported for callchains currently, would need some
> layout changes there.
nice, works nicely, especialy with --xed
Acked-by: Jiri Olsa <jolsa@kernel.org>
I need to check, but is there a way to make this work with
perf-with-kcore script? looks like we endup with kcore and
won't allow vmlinux lookups for debug info
thanks,
jirka
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf, tools: Support srccode output
2018-12-05 12:28 ` Jiri Olsa
@ 2018-12-05 16:54 ` Arnaldo Carvalho de Melo
2018-12-05 17:05 ` Jiri Olsa
2018-12-05 17:33 ` Andi Kleen
2018-12-05 22:15 ` Arnaldo Carvalho de Melo
2 siblings, 1 reply; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-12-05 16:54 UTC (permalink / raw)
To: Jiri Olsa; +Cc: Andi Kleen, jolsa, linux-perf-users, linux-kernel, Andi Kleen
Em Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
> On Mon, Dec 03, 2018 at 04:18:48PM -0800, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > When looking at PT or brstackinsn traces with perf script
> > it can be very useful to see the source code. This adds a simple
> > facility to print them with perf script, if the information
> > is available through dwarf
> >
> > % perf record ...
> > % perf script -F insn,ip,sym,srccode
> > ...
> >
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004b3 main
> > 6 v++;
> >
> > % perf record -b ...
> > % perf script -F insn,ip,sym,srccode,brstackinsn
> >
> > ...
> > main+22:
> > 0000000000400543 insn: e8 ca ff ff ff # PRED
> > |18 f1();
> > f1:
> > 0000000000400512 insn: 55
> > |10 {
> > 0000000000400513 insn: 48 89 e5
> > 0000000000400516 insn: b8 00 00 00 00
> > |11 f2();
> > 000000000040051b insn: e8 d6 ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> > 0000000000400500 insn: 8b 0d 2a 0b 20 00
> > 0000000000400506 insn: 99
> > 0000000000400507 insn: f7 f9
> > 0000000000400509 insn: 89 05 29 0b 20 00
> > 000000000040050f insn: 90
> > |7 }
> > 0000000000400510 insn: 5d
> > 0000000000400511 insn: c3 # PRED
> > f1+14:
> > 0000000000400520 insn: b8 00 00 00 00
> > |12 f2();
> > 0000000000400525 insn: e8 cc ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> >
> > Not supported for callchains currently, would need some
> > layout changes there.
>
> nice, works nicely, especialy with --xed
The above seems to imply you actually tested it, was that the case? Can
you please provide me the exact 'perf record' line you used, that is
lacking in Andi's original commit log message?
- Arnaldo
> Acked-by: Jiri Olsa <jolsa@kernel.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf, tools: Support srccode output
2018-12-05 16:54 ` Arnaldo Carvalho de Melo
@ 2018-12-05 17:05 ` Jiri Olsa
0 siblings, 0 replies; 6+ messages in thread
From: Jiri Olsa @ 2018-12-05 17:05 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: Andi Kleen, jolsa, linux-perf-users, linux-kernel, Andi Kleen
On Wed, Dec 05, 2018 at 01:54:30PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
> > On Mon, Dec 03, 2018 at 04:18:48PM -0800, Andi Kleen wrote:
> > > From: Andi Kleen <ak@linux.intel.com>
> > >
> > > When looking at PT or brstackinsn traces with perf script
> > > it can be very useful to see the source code. This adds a simple
> > > facility to print them with perf script, if the information
> > > is available through dwarf
> > >
> > > % perf record ...
> > > % perf script -F insn,ip,sym,srccode
> > > ...
> > >
> > > 4004c6 main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004c6 main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004cd main
> > > 5 for (i = 0; i < 10000000; i++)
> > > 4004b3 main
> > > 6 v++;
> > >
> > > % perf record -b ...
> > > % perf script -F insn,ip,sym,srccode,brstackinsn
> > >
> > > ...
> > > main+22:
> > > 0000000000400543 insn: e8 ca ff ff ff # PRED
> > > |18 f1();
> > > f1:
> > > 0000000000400512 insn: 55
> > > |10 {
> > > 0000000000400513 insn: 48 89 e5
> > > 0000000000400516 insn: b8 00 00 00 00
> > > |11 f2();
> > > 000000000040051b insn: e8 d6 ff ff ff # PRED
> > > f2:
> > > 00000000004004f6 insn: 55
> > > |5 {
> > > 00000000004004f7 insn: 48 89 e5
> > > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > > |6 c = a / b;
> > > 0000000000400500 insn: 8b 0d 2a 0b 20 00
> > > 0000000000400506 insn: 99
> > > 0000000000400507 insn: f7 f9
> > > 0000000000400509 insn: 89 05 29 0b 20 00
> > > 000000000040050f insn: 90
> > > |7 }
> > > 0000000000400510 insn: 5d
> > > 0000000000400511 insn: c3 # PRED
> > > f1+14:
> > > 0000000000400520 insn: b8 00 00 00 00
> > > |12 f2();
> > > 0000000000400525 insn: e8 cc ff ff ff # PRED
> > > f2:
> > > 00000000004004f6 insn: 55
> > > |5 {
> > > 00000000004004f7 insn: 48 89 e5
> > > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > > |6 c = a / b;
> > >
> > > Not supported for callchains currently, would need some
> > > layout changes there.
> >
> > nice, works nicely, especialy with --xed
>
> The above seems to imply you actually tested it, was that the case? Can
> you please provide me the exact 'perf record' line you used, that is
> lacking in Andi's original commit log message?
yep..
# ./perf record -e intel_pt//u -- ./perf
jirka
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf, tools: Support srccode output
2018-12-05 12:28 ` Jiri Olsa
2018-12-05 16:54 ` Arnaldo Carvalho de Melo
@ 2018-12-05 17:33 ` Andi Kleen
2018-12-05 22:15 ` Arnaldo Carvalho de Melo
2 siblings, 0 replies; 6+ messages in thread
From: Andi Kleen @ 2018-12-05 17:33 UTC (permalink / raw)
To: Jiri Olsa; +Cc: Andi Kleen, acme, jolsa, linux-perf-users, linux-kernel
On Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa wrote:
> On Mon, Dec 03, 2018 at 04:18:48PM -0800, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > When looking at PT or brstackinsn traces with perf script
> > it can be very useful to see the source code. This adds a simple
> > facility to print them with perf script, if the information
> > is available through dwarf
> >
> > % perf record ...
> > % perf script -F insn,ip,sym,srccode
> > ...
> >
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004b3 main
> > 6 v++;
> >
> > % perf record -b ...
> > % perf script -F insn,ip,sym,srccode,brstackinsn
> >
> > ...
> > main+22:
> > 0000000000400543 insn: e8 ca ff ff ff # PRED
> > |18 f1();
> > f1:
> > 0000000000400512 insn: 55
> > |10 {
> > 0000000000400513 insn: 48 89 e5
> > 0000000000400516 insn: b8 00 00 00 00
> > |11 f2();
> > 000000000040051b insn: e8 d6 ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> > 0000000000400500 insn: 8b 0d 2a 0b 20 00
> > 0000000000400506 insn: 99
> > 0000000000400507 insn: f7 f9
> > 0000000000400509 insn: 89 05 29 0b 20 00
> > 000000000040050f insn: 90
> > |7 }
> > 0000000000400510 insn: 5d
> > 0000000000400511 insn: c3 # PRED
> > f1+14:
> > 0000000000400520 insn: b8 00 00 00 00
> > |12 f2();
> > 0000000000400525 insn: e8 cc ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> >
> > Not supported for callchains currently, would need some
> > layout changes there.
>
> nice, works nicely, especialy with --xed
>
> Acked-by: Jiri Olsa <jolsa@kernel.org>
>
> I need to check, but is there a way to make this work with
> perf-with-kcore script? looks like we endup with kcore and
> won't allow vmlinux lookups for debug info
Hmm, probably not currently. Would somehow need to point
to the debuginfo. Perhaps if /proc/kcore was fixed
to report the debugid, and then could find it this way.
Or we could add an option to perf report to add a vmlinux
only for debug info that is not used for reading the code.
-andi
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] perf, tools: Support srccode output
2018-12-05 12:28 ` Jiri Olsa
2018-12-05 16:54 ` Arnaldo Carvalho de Melo
2018-12-05 17:33 ` Andi Kleen
@ 2018-12-05 22:15 ` Arnaldo Carvalho de Melo
2 siblings, 0 replies; 6+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-12-05 22:15 UTC (permalink / raw)
To: Jiri Olsa; +Cc: Andi Kleen, jolsa, linux-perf-users, linux-kernel, Andi Kleen
Em Wed, Dec 05, 2018 at 01:28:38PM +0100, Jiri Olsa escreveu:
> On Mon, Dec 03, 2018 at 04:18:48PM -0800, Andi Kleen wrote:
> > From: Andi Kleen <ak@linux.intel.com>
> >
> > When looking at PT or brstackinsn traces with perf script
> > it can be very useful to see the source code. This adds a simple
> > facility to print them with perf script, if the information
> > is available through dwarf
> >
> > % perf record ...
> > % perf script -F insn,ip,sym,srccode
> > ...
> >
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004c6 main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004cd main
> > 5 for (i = 0; i < 10000000; i++)
> > 4004b3 main
> > 6 v++;
> >
> > % perf record -b ...
> > % perf script -F insn,ip,sym,srccode,brstackinsn
> >
> > ...
> > main+22:
> > 0000000000400543 insn: e8 ca ff ff ff # PRED
> > |18 f1();
> > f1:
> > 0000000000400512 insn: 55
> > |10 {
> > 0000000000400513 insn: 48 89 e5
> > 0000000000400516 insn: b8 00 00 00 00
> > |11 f2();
> > 000000000040051b insn: e8 d6 ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> > 0000000000400500 insn: 8b 0d 2a 0b 20 00
> > 0000000000400506 insn: 99
> > 0000000000400507 insn: f7 f9
> > 0000000000400509 insn: 89 05 29 0b 20 00
> > 000000000040050f insn: 90
> > |7 }
> > 0000000000400510 insn: 5d
> > 0000000000400511 insn: c3 # PRED
> > f1+14:
> > 0000000000400520 insn: b8 00 00 00 00
> > |12 f2();
> > 0000000000400525 insn: e8 cc ff ff ff # PRED
> > f2:
> > 00000000004004f6 insn: 55
> > |5 {
> > 00000000004004f7 insn: 48 89 e5
> > 00000000004004fa insn: 8b 05 2c 0b 20 00
> > |6 c = a / b;
> >
> > Not supported for callchains currently, would need some
> > layout changes there.
>
> nice, works nicely, especialy with --xed
>
> Acked-by: Jiri Olsa <jolsa@kernel.org>
Trying to fix this:
alpine:3.4
Downloading http://x.x.x.x/perf/perf-4.20.0-rc3.tar.xz...
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1426k 100 1426k 0 0 232M 0 --:--:-- --:--:-- --:--:-- 232M
8932875925270caf72895c32013a678e9c19aa0d
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-alpine-linux-musl/5.3.0/lto-wrapper
Target: x86_64-alpine-linux-musl
Configured with: /home/buildozer/aports/main/gcc/src/gcc-5.3.0/configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --build=x86_64-alpine-linux-musl --host=x86_64-alpine-linux-musl --target=x86_64-alpine-linux-musl --with-pkgversion='Alpine 5.3.0' --enable-checking=release --disable-fixed-point --disable-libstdcxx-pch --disable-multilib --disable-nls --disable-werror --disable-symvers --enable-__cxa_atexit --enable-esp --enable-cloog-backend --enable-languages=c,c++,objc,java,fortran,ada --disable-libssp --disable-libmudflap --disable-libsanitizer --enable-shared --enable-threads --enable-tls --with-system-zlib
Thread model: posix
gcc version 5.3.0 (Alpine 5.3.0)
CC /tmp/build/perf/util/srccode.o
In file included from util/srccode.c:19:0:
/usr/include/sys/fcntl.h:1:2: error: #warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h> [-Werror=cpp]
#warning redirecting incorrect #include <sys/fcntl.h> to <fcntl.h>
^
CC /tmp/build/perf/util/data.o
cc1: all warnings being treated as errors
mv: can't rename '/tmp/build/perf/util/.srccode.o.tmp': No such file or directory
/git/linux/tools/build/Makefile.build:96: recipe for target '/tmp/build/perf/util/srccode.o' failed
make[4]: *** [/tmp/build/perf/util/srccode.o] Error 1
make[4]: *** Waiting for unfinished jobs....
CC /tmp/build/perf/tests/attr.o
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-12-05 22:15 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-12-04 0:18 [PATCH] perf, tools: Support srccode output Andi Kleen
2018-12-05 12:28 ` Jiri Olsa
2018-12-05 16:54 ` Arnaldo Carvalho de Melo
2018-12-05 17:05 ` Jiri Olsa
2018-12-05 17:33 ` Andi Kleen
2018-12-05 22:15 ` Arnaldo Carvalho de Melo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).