All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: Clark Williams <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Andi Kleen <ak@linux.intel.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 45/75] perf tools: Support 'srccode' output
Date: Thu,  6 Dec 2018 18:25:32 -0300	[thread overview]
Message-ID: <20181206212602.20474-46-acme@kernel.org> (raw)
In-Reply-To: <20181206212602.20474-1-acme@kernel.org>

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.

Committer notes:

Fixed the build on Alpine Linux (3.4 .. 3.8) by addressing this
warning:

  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>
    ^~~~~~~
  cc1: all warnings being treated as errors

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Tested-by: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/20181204001848.24769-1-andi@firstfloor.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.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 3ea98fe72f7f..3728b50e52e2 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 a0d58b4d9c32..6751301a755c 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..fcc8630f6dff
--- /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 <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 5920c3bb8ffe..712dd48cc0ca 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.19.2


  parent reply	other threads:[~2018-12-06 21:33 UTC|newest]

Thread overview: 83+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-06 21:24 [GIT PULL 00/75] perf/core improvements and fixes Arnaldo Carvalho de Melo
2018-12-06 21:24 ` Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 01/75] perf build: Give better hint about devel package for libssl Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 02/75] perf stat: Fix shadow stats for clock events Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 03/75] perf stat: Fix CSV mode column output for non-cgroup events Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 04/75] perf map: Remove extra indirection from map__find() Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 05/75] perf env: Also consider env->arch == NULL as local operation Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 06/75] perf machine: Record if a arch has a single user/kernel address space Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 07/75] perf thread: Add fallback functions for cases where cpumode is insufficient Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 08/75] perf tools: Use fallback for sample_addr_correlates_sym() cases Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 09/75] perf script: Use fallbacks for branch stacks Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 10/75] tools lib traceevent: Fix compile warnings in tools/lib/traceevent/event-parse.c Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 11/75] perf tests record: Allow for 'sleep' being 'coreutils' Arnaldo Carvalho de Melo
2018-12-06 21:24 ` [PATCH 12/75] perf test: Fix perf_event_attr test failure Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 13/75] tools include: Adopt ERR_CAST() from the kernel err.h header Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 14/75] perf bpf: Use ERR_CAST instead of ERR_PTR(PTR_ERR()) Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 15/75] perf top: Allow passing a kallsyms file Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 16/75] perf intel-pt: Fix error with config term "pt=0" Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 17/75] tools build feature: Check if libaio is available Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 18/75] perf mmap: Map data buffer for preserving collected data Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 19/75] perf record: Enable asynchronous trace writing Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 20/75] perf record: Extend trace writing to multi AIO Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 21/75] perf beauty mmap_flags: Check if the arch has a mmap.h file Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 22/75] tools lib traceevent: Add sanity check to is_timestamp_in_us() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 23/75] perf annotate: Compute average IPC and IPC coverage per symbol Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 24/75] perf annotate: Create a annotate2 flag in struct symbol Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 25/75] perf report: Display average IPC and IPC coverage per symbol Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 26/75] perf report: Documentation average IPC and IPC coverage Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 27/75] tools lib traceevent: Implement new API tep_get_ref() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 28/75] tools lib traceevent: Added support for pkg-config Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 29/75] tools lib traceevent: Install trace-seq.h API header file Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 30/75] tools lib traceevent, perf tools: Rename 'struct tep_event_format' to 'struct tep_event' Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 31/75] tools lib traceevent: Rename tep_free_format() to tep_free_event() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 32/75] perf tools: traceevent API cleanup, remove __tep_data2host*() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 33/75] tools lib traceevent: traceevent API cleanup Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 34/75] perf beauty mmap_flags: Fixed syntax error Fixed missing ']' error Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 35/75] perf cs-etm: Support for ARM A32/T32 instruction sets in CoreSight trace Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 36/75] perf tests ARM: Disable breakpoint tests 32-bit Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 37/75] perf vendor events intel: Fix diverse typos Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 38/75] tools lib traceevent: Fix diverse typos in comments Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 39/75] perf tools Documentation: Fix diverse typos Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 40/75] perf bpf-loader: Fix debugging message typo Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 41/75] perf tools: Fix diverse comment typos Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 42/75] tools lib subcmd: Fix a few source code " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 43/75] perf tools: Allow specifying proc-map-timeout in config file Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 44/75] perf trace: We need to consider "nr" if "__syscall_nr" is not there Arnaldo Carvalho de Melo
2018-12-06 21:25 ` Arnaldo Carvalho de Melo [this message]
2018-12-06 21:25 ` [PATCH 46/75] perf ordered_events: Rework show_progress for __ordered_events__flush Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 47/75] perf ordered_events: Add private data member Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 48/75] perf top: Save and display the lost count stats Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 49/75] perf top: Move lost events warning to helpline Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 50/75] perf top: Add processing thread Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 51/75] perf top: Use cond variable instead of a lock Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 52/75] perf top: Set the 'session_done' volatile variable when exiting Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 53/75] perf top: Drop samples which are behind the refresh rate Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 54/75] perf top: Save and display the drop count stats Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 55/75] perf top: Display slow reader warning when droping samples Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 56/75] perf top: Move perf_top__reset_sample_counters() to after counts display Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 57/75] perf cs-etm: Add configuration for ETMv3 trace protocol Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 58/75] perf cs-etm: Add support for ETMv3 trace decoding Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 59/75] perf cs-etm: Add support for PTMv1.1 decoding Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 60/75] perf dso: Fix unchecked usage of strncpy() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 61/75] perf header: " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 62/75] " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 63/75] perf help: Remove needless use " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 64/75] perf svghelper: Fix unchecked usage " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 65/75] perf ui helpline: Use strlcpy() as a shorter form of strncpy() + explicit set nul Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 66/75] perf probe: Fix unchecked usage of strncpy() Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 67/75] perf parse-events: " Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 68/75] perf vendor events intel: Fix Load_Miss_Real_Latency on SKL/SKX Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 69/75] perf record: Fix memory leak on AIO objects deallocation Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 70/75] perf config: Modify size factor of snprintf Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 71/75] perf annotate: Introduce basic support for ARC Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25   ` Arnaldo Carvalho de Melo
2018-12-06 21:25 ` [PATCH 72/75] perf ordered_events: Add ordered_events__flush_time interface Arnaldo Carvalho de Melo
2018-12-06 21:26 ` [PATCH 73/75] perf trace: Move event delivery to a new deliver_event() function Arnaldo Carvalho de Melo
2018-12-06 21:26 ` [PATCH 74/75] perf ordered_events: Add first_time() method Arnaldo Carvalho de Melo
2018-12-06 21:26 ` [PATCH 75/75] perf trace: Add ordered processing Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181206212602.20474-46-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=ak@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=williams@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.