Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1602292 > unrolled thread

[PATCH v5 0/5] perf report: Show inline stack

Started byJin Yao <yao.jin@linux.intel.com>
First post2017-03-16 14:50 +0100
Last post2017-03-25 01:30 +0100
Articles 10 — 5 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v5 0/5] perf report: Show inline stack Jin Yao <yao.jin@linux.intel.com> - 2017-03-16 14:50 +0100
    [PATCH v5 2/5] perf report: Find the inline stack for a given address Jin Yao <yao.jin@linux.intel.com> - 2017-03-16 14:50 +0100
      Re: [PATCH v5 2/5] perf report: Find the inline stack for a given  address Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-03-24 19:40 +0100
      Re: [PATCH v5 2/5] perf report: Find the inline stack for a given  address Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com> - 2017-03-25 08:20 +0100
        Re: [PATCH v5 2/5] perf report: Find the inline stack for a given  address "Jin, Yao" <yao.jin@linux.intel.com> - 2017-03-25 13:50 +0100
    [PATCH v5 4/5] perf report: Show inline stack for stdio mode Jin Yao <yao.jin@linux.intel.com> - 2017-03-16 14:50 +0100
    Re: [PATCH v5 0/5] perf report: Show inline stack Milian Wolff <milian.wolff@kdab.com> - 2017-03-18 18:40 +0100
      Re: [PATCH v5 0/5] perf report: Show inline stack Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-03-24 20:10 +0100
        Re: [PATCH v5 0/5] perf report: Show inline stack Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-03-24 20:30 +0100
          Re: [PATCH v5 0/5] perf report: Show inline stack "Jin, Yao" <yao.jin@linux.intel.com> - 2017-03-25 01:30 +0100

#1602292 — [PATCH v5 0/5] perf report: Show inline stack

FromJin Yao <yao.jin@linux.intel.com>
Date2017-03-16 14:50 +0100
Subject[PATCH v5 0/5] perf report: Show inline stack
Message-ID<tlDWV-7vw-5@gated-at.bofh.it>
v5: Update according to Milian Wolff's comments. It groups by address
    (then display file/ line), or by function (then display function name).

    For example:

    1. Show inlined function name
       perf report --stdio -g function --inline

       0.69%     0.00%  inline   ld-2.23.so           [.] dl_main
              |
              ---dl_main
                 |
                  --0.56%--_dl_relocate_object
                           _dl_relocate_object (inline)
                           elf_dynamic_do_Rela (inline)

     2. Show the file/line information
        perf report --stdio -g address --inline

        0.69%     0.00%  inline   ld-2.23.so           [.] _dl_start_user
              |
              ---_dl_start_user .:0
                 _dl_start rtld.c:307
                 /build/glibc-GKVZIf/glibc-2.23/elf/rtld.c:413 (inline)
                 _dl_sysdep_start dl-sysdep.c:250
                 |
                  --0.56%--dl_main rtld.c:2076

    2 patches are updated according to this change.
    perf report: Show inline stack in browser mode
    perf report: Show inline stack in stdio mode

    3 patches are not changed.
    perf report: Find the inline stack for a given address
    perf report: Refactor common code in srcline.c
    perf report: Create new inline option

v4: Remove the options "--inline-line" and "--inline-name". Just use
    a new option "--inline" to print the inline function information.
    The policy is if the inline function name can be resolved then
    print the name in priority. If the name can't be resolved, then
    print the source line number.

    For example:
    perf report --stdio --inline

    0.69%     0.00%  inline   ld-2.23.so           [.] dl_main
           |
           ---dl_main
              |
               --0.56%--_dl_relocate_object
                         |
                         ---_dl_relocate_object (inline)
                            elf_dynamic_do_Rela (inline)

    Following 3 patches are updated according to this change.
    perf report: Show inline stack in browser mode
    perf report: Show inline stack in stdio mode
    perf report: Create new inline option

    Following are not changed.
    perf report: Find the inline stack for a given address
    perf report: Refactor common code in srcline.c

v3: Iterate on RIPs of all callchain entries to check if the RIP is in
    inline functions.

    Reverse the order of the inliner printout if necessary.

    Provide new options "--inline-line" / "--inline-name" to print
    inline function name or print inline function source line.

v2: Thanks so much for Arnaldo's comments!
    The modifications are:

    1. Divide v1 patch "perf report: Find the inline stack for a
       given address" into 2 patches:
       a. perf report: Refactor common code in srcline.c
       b. perf report: Find the inline stack for a given address

       Some function names are changed:
       dso_name_get -> dso__name
       ilist_apend -> inline_list__append
       get_inline_node -> dso__parse_addr_inlines
       free_inline_node -> inline_node__delete

    2. Since the function name are changed, update following patches
       accordingly.
       a. perf report: Show inline stack in stdio mode
       b. perf report: Show inline stack in browser mode

    3. Rebase to latest perf/core branch. This patch is impacted.
       a. perf report: Create a new option "--inline"

v1: Initial post

It would be useful for perf to support a mode to query the
inline stack for callgraph addresses. This would simplify
finding the right code in code that does a lot of inlining.

For example, the c code:

static inline void f3(void)
{
        int i;
        for (i = 0; i < 1000;) {

                if(i%2)
                        i++;
                else
                        i++;
        }
        printf("hello f3\n");   /* D */
}

/* < CALLCHAIN: f2 <- f1 > */
static inline void f2(void)
{
        int i;
        for (i = 0; i < 100; i++) {
                f3();   /* C */
        }
}

/* < CALLCHAIN: f1 <- main > */
static inline void f1(void)
{
        int i;
        for (i = 0; i < 100; i++) {
                f2();   /* B */
        }
}

/* < CALLCHAIN: main <- TOP > */
int main()
{
        struct timeval tv;
        time_t start, end;

        gettimeofday(&tv, NULL);
        start = end = tv.tv_sec;
        while((end - start) < 5) {
                f1();   /* A */
                gettimeofday(&tv, NULL);
                end = tv.tv_sec;
        }
        return 0;
}

The printed inline stack is:

0.05%  test2    test2              [.] main
       |
       ---/home/perf-dev/lck-2867/test/test2.c:27 (inline)
          /home/perf-dev/lck-2867/test/test2.c:35 (inline)
          /home/perf-dev/lck-2867/test/test2.c:45 (inline)
          /home/perf-dev/lck-2867/test/test2.c:61 (inline)

I tag A/B/C/D in above c code to indicate the source line,
actually the inline stack is equal to:

0.05%  test2    test2              [.] main
       |
       ---D
          C
          B
          A

Jin Yao (5):
  perf report: Refactor common code in srcline.c
  perf report: Find the inline stack for a given address
  perf report: Create new inline option
  perf report: Show inline stack for stdio mode
  perf report: Show inline stack for browser mode

 tools/perf/Documentation/perf-report.txt |   4 +
 tools/perf/builtin-report.c              |   2 +
 tools/perf/ui/browsers/hists.c           | 171 ++++++++++++++++++++--
 tools/perf/ui/stdio/hist.c               |  79 ++++++++++-
 tools/perf/util/hist.c                   |   5 +
 tools/perf/util/sort.h                   |   1 +
 tools/perf/util/srcline.c                | 237 +++++++++++++++++++++++++++----
 tools/perf/util/symbol-elf.c             |   5 +
 tools/perf/util/symbol.h                 |   5 +-
 tools/perf/util/util.h                   |  16 +++
 10 files changed, 487 insertions(+), 38 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1602294 — [PATCH v5 2/5] perf report: Find the inline stack for a given address

FromJin Yao <yao.jin@linux.intel.com>
Date2017-03-16 14:50 +0100
Subject[PATCH v5 2/5] perf report: Find the inline stack for a given address
Message-ID<tlDWV-7vw-21@gated-at.bofh.it>
In reply to#1602292
It would be useful for perf to support a mode to query the
inline stack for a given callgraph address. This would simplify
finding the right code in code that does a lot of inlining.

The srcline.c has contained the code which supports to translate
the address to filename:line_nr. This patch just extends the
function to let it support getting the inline stacks.

It introduces the inline_list which will store the inline
function result (filename:line_nr and funcname).

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Tested-by: Milian Wolff <milian.wolff@kdab.com>
---
 tools/perf/util/srcline.c    | 169 +++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/symbol-elf.c |   5 ++
 tools/perf/util/symbol.h     |   2 +
 tools/perf/util/util.h       |  16 ++++
 4 files changed, 187 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index 2953c9f..f9d4b47 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -7,6 +7,7 @@
 #include "util/dso.h"
 #include "util/util.h"
 #include "util/debug.h"
+#include "util/callchain.h"
 
 #include "symbol.h"
 
@@ -30,6 +31,41 @@ static const char *dso__name(struct dso *dso)
 	return dso_name;
 }
 
+static int inline_list__append(char *filename, char *funcname, int line_nr,
+			       struct inline_node *node, struct dso *dso)
+{
+	struct inline_list *ilist;
+	char *demangled;
+
+	ilist = zalloc(sizeof(*ilist));
+	if (ilist == NULL)
+		return -1;
+
+	ilist->filename = filename;
+	ilist->line_nr = line_nr;
+
+	demangled = dso__demangle_sym(dso, 0, funcname);
+	if (demangled == NULL) {
+		ilist->funcname = funcname;
+	} else {
+		ilist->funcname = demangled;
+		if (funcname != NULL)
+			free(funcname);
+	}
+
+	list_add_tail(&ilist->list, &node->val);
+
+	return 0;
+}
+
+static void inline_list__reverse(struct inline_node *node)
+{
+	struct inline_list *ilist, *n;
+
+	list_for_each_entry_safe_reverse(ilist, n, &node->val, list)
+		list_move_tail(&ilist->list, &node->val);
+}
+
 #ifdef HAVE_LIBBFD_SUPPORT
 
 /*
@@ -171,7 +207,7 @@ static void addr2line_cleanup(struct a2l_data *a2l)
 
 static int addr2line(const char *dso_name, u64 addr,
 		     char **file, unsigned int *line, struct dso *dso,
-		     bool unwind_inlines)
+		     bool unwind_inlines, struct inline_node *node)
 {
 	int ret = 0;
 	struct a2l_data *a2l = dso->a2l;
@@ -196,8 +232,21 @@ static int addr2line(const char *dso_name, u64 addr,
 
 		while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
 					     &a2l->funcname, &a2l->line) &&
-		       cnt++ < MAX_INLINE_NEST)
-			;
+		       cnt++ < MAX_INLINE_NEST) {
+
+			if (node != NULL) {
+				if (inline_list__append(strdup(a2l->filename),
+							strdup(a2l->funcname),
+							a2l->line, node,
+							dso) != 0)
+					return 0;
+			}
+		}
+
+		if ((node != NULL) &&
+		    (callchain_param.order != ORDER_CALLEE)) {
+			inline_list__reverse(node);
+		}
 	}
 
 	if (a2l->found && a2l->filename) {
@@ -223,6 +272,35 @@ void dso__free_a2l(struct dso *dso)
 	dso->a2l = NULL;
 }
 
+static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
+	struct dso *dso)
+{
+	char *file = NULL;
+	unsigned int line = 0;
+	struct inline_node *node;
+
+	node = zalloc(sizeof(*node));
+	if (node == NULL) {
+		perror("not enough memory for the inline node");
+		return NULL;
+	}
+
+	INIT_LIST_HEAD(&node->val);
+	node->addr = addr;
+
+	if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node))
+		goto out_free_inline_node;
+
+	if (list_empty(&node->val))
+		goto out_free_inline_node;
+
+	return node;
+
+out_free_inline_node:
+	inline_node__delete(node);
+	return NULL;
+}
+
 #else /* HAVE_LIBBFD_SUPPORT */
 
 static int filename_split(char *filename, unsigned int *line_nr)
@@ -249,7 +327,8 @@ static int filename_split(char *filename, unsigned int *line_nr)
 static int addr2line(const char *dso_name, u64 addr,
 		     char **file, unsigned int *line_nr,
 		     struct dso *dso __maybe_unused,
-		     bool unwind_inlines __maybe_unused)
+		     bool unwind_inlines __maybe_unused,
+		     struct inline_node *node __maybe_unused)
 {
 	FILE *fp;
 	char cmd[PATH_MAX];
@@ -288,6 +367,57 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
 {
 }
 
+static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
+	struct dso *dso __maybe_unused)
+{
+	FILE *fp;
+	char cmd[PATH_MAX];
+	struct inline_node *node;
+	char *filename = NULL;
+	size_t len;
+	unsigned int line_nr = 0;
+
+	scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64,
+		  dso_name, addr);
+
+	fp = popen(cmd, "r");
+	if (fp == NULL) {
+		pr_err("popen failed for %s\n", dso_name);
+		return NULL;
+	}
+
+	node = zalloc(sizeof(*node));
+	if (node == NULL) {
+		perror("not enough memory for the inline node");
+		goto out;
+	}
+
+	INIT_LIST_HEAD(&node->val);
+	node->addr = addr;
+
+	while (getline(&filename, &len, fp) != -1) {
+		if (filename_split(filename, &line_nr) != 1) {
+			free(filename);
+			goto out;
+		}
+
+		if (inline_list__append(filename, NULL, line_nr, node) != 0)
+			goto out;
+
+		filename = NULL;
+	}
+
+out:
+	pclose(fp);
+
+	if (list_empty(&node->val)) {
+		inline_node__delete(node);
+		return NULL;
+	}
+
+	return node;
+}
+
 #endif /* HAVE_LIBBFD_SUPPORT */
 
 /*
@@ -311,7 +441,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
 	if (dso_name == NULL)
 		goto out;
 
-	if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
+	if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines, NULL))
 		goto out;
 
 	if (asprintf(&srcline, "%s:%u",
@@ -351,3 +481,32 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
 {
 	return __get_srcline(dso, addr, sym, show_sym, false);
 }
+
+struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr)
+{
+	const char *dso_name;
+
+	dso_name = dso__name(dso);
+	if (dso_name == NULL)
+		return NULL;
+
+	return addr2inlines(dso_name, addr, dso);
+}
+
+void inline_node__delete(struct inline_node *node)
+{
+	struct inline_list *ilist, *tmp;
+
+	list_for_each_entry_safe(ilist, tmp, &node->val, list) {
+		list_del_init(&ilist->list);
+		if (ilist->filename != NULL)
+			free(ilist->filename);
+
+		if (ilist->funcname != NULL)
+			free(ilist->funcname);
+
+		free(ilist);
+	}
+
+	free(node);
+}
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 4e59dde..3a1dda3 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -390,6 +390,11 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
 	return 0;
 }
 
+char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name)
+{
+	return demangle_sym(dso, kmodule, elf_name);
+}
+
 /*
  * Align offset to 4 bytes as needed for note name and descriptor data.
  */
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 6c358b7..8adf045 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -305,6 +305,8 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss,
 				struct map *map);
 
+char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name);
+
 void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel);
 void symbols__insert(struct rb_root *symbols, struct symbol *sym);
 void symbols__fixup_duplicate(struct rb_root *symbols);
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index b2cfa47..cc0700d 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -364,4 +364,20 @@ int is_printable_array(char *p, unsigned int len);
 int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz);
 
 int unit_number__scnprintf(char *buf, size_t size, u64 n);
+
+struct inline_list {
+	char			*filename;
+	char			*funcname;
+	unsigned int		line_nr;
+	struct list_head	list;
+};
+
+struct inline_node {
+	u64			addr;
+	struct list_head	val;
+};
+
+struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr);
+void inline_node__delete(struct inline_node *node);
+
 #endif /* GIT_COMPAT_UTIL_H */
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1608858 — Re: [PATCH v5 2/5] perf report: Find the inline stack for a given address

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-03-24 19:40 +0100
SubjectRe: [PATCH v5 2/5] perf report: Find the inline stack for a given address
Message-ID<toChY-5vt-19@gated-at.bofh.it>
In reply to#1602294
Em Fri, Mar 17, 2017 at 05:42:24AM +0800, Jin Yao escreveu:
> It would be useful for perf to support a mode to query the
> inline stack for a given callgraph address. This would simplify
> finding the right code in code that does a lot of inlining.
> 
> The srcline.c has contained the code which supports to translate
> the address to filename:line_nr. This patch just extends the
> function to let it support getting the inline stacks.
> 
> It introduces the inline_list which will store the inline
> function result (filename:line_nr and funcname).
> 
> Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
> Tested-by: Milian Wolff <milian.wolff@kdab.com>
> ---
>  tools/perf/util/srcline.c    | 169 +++++++++++++++++++++++++++++++++++++++++--
>  tools/perf/util/symbol-elf.c |   5 ++
>  tools/perf/util/symbol.h     |   2 +
>  tools/perf/util/util.h       |  16 ++++
>  4 files changed, 187 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
> index 2953c9f..f9d4b47 100644
> --- a/tools/perf/util/srcline.c
> +++ b/tools/perf/util/srcline.c
> @@ -7,6 +7,7 @@
>  #include "util/dso.h"
>  #include "util/util.h"
>  #include "util/debug.h"
> +#include "util/callchain.h"
>  
>  #include "symbol.h"
>  
> @@ -30,6 +31,41 @@ static const char *dso__name(struct dso *dso)
>  	return dso_name;
>  }
>  
> +static int inline_list__append(char *filename, char *funcname, int line_nr,
> +			       struct inline_node *node, struct dso *dso)
> +{
> +	struct inline_list *ilist;
> +	char *demangled;
> +
> +	ilist = zalloc(sizeof(*ilist));
> +	if (ilist == NULL)
> +		return -1;
> +
> +	ilist->filename = filename;
> +	ilist->line_nr = line_nr;
> +
> +	demangled = dso__demangle_sym(dso, 0, funcname);
> +	if (demangled == NULL) {
> +		ilist->funcname = funcname;
> +	} else {
> +		ilist->funcname = demangled;
> +		if (funcname != NULL)
> +			free(funcname);

free() can be fed NULL, I'll simplify this thus

> +	}
> +
> +	list_add_tail(&ilist->list, &node->val);
> +
> +	return 0;
> +}
> +
> +static void inline_list__reverse(struct inline_node *node)
> +{
> +	struct inline_list *ilist, *n;
> +
> +	list_for_each_entry_safe_reverse(ilist, n, &node->val, list)
> +		list_move_tail(&ilist->list, &node->val);
> +}
> +
>  #ifdef HAVE_LIBBFD_SUPPORT
>  
>  /*
> @@ -171,7 +207,7 @@ static void addr2line_cleanup(struct a2l_data *a2l)
>  
>  static int addr2line(const char *dso_name, u64 addr,
>  		     char **file, unsigned int *line, struct dso *dso,
> -		     bool unwind_inlines)
> +		     bool unwind_inlines, struct inline_node *node)
>  {
>  	int ret = 0;
>  	struct a2l_data *a2l = dso->a2l;
> @@ -196,8 +232,21 @@ static int addr2line(const char *dso_name, u64 addr,
>  
>  		while (bfd_find_inliner_info(a2l->abfd, &a2l->filename,
>  					     &a2l->funcname, &a2l->line) &&
> -		       cnt++ < MAX_INLINE_NEST)
> -			;
> +		       cnt++ < MAX_INLINE_NEST) {
> +
> +			if (node != NULL) {
> +				if (inline_list__append(strdup(a2l->filename),
> +							strdup(a2l->funcname),
> +							a2l->line, node,
> +							dso) != 0)
> +					return 0;
> +			}
> +		}
> +
> +		if ((node != NULL) &&
> +		    (callchain_param.order != ORDER_CALLEE)) {
> +			inline_list__reverse(node);
> +		}
>  	}
>  
>  	if (a2l->found && a2l->filename) {
> @@ -223,6 +272,35 @@ void dso__free_a2l(struct dso *dso)
>  	dso->a2l = NULL;
>  }
>  
> +static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
> +	struct dso *dso)
> +{
> +	char *file = NULL;
> +	unsigned int line = 0;
> +	struct inline_node *node;
> +
> +	node = zalloc(sizeof(*node));
> +	if (node == NULL) {
> +		perror("not enough memory for the inline node");
> +		return NULL;
> +	}
> +
> +	INIT_LIST_HEAD(&node->val);
> +	node->addr = addr;
> +
> +	if (!addr2line(dso_name, addr, &file, &line, dso, TRUE, node))
> +		goto out_free_inline_node;
> +
> +	if (list_empty(&node->val))
> +		goto out_free_inline_node;
> +
> +	return node;
> +
> +out_free_inline_node:
> +	inline_node__delete(node);
> +	return NULL;
> +}
> +
>  #else /* HAVE_LIBBFD_SUPPORT */
>  
>  static int filename_split(char *filename, unsigned int *line_nr)
> @@ -249,7 +327,8 @@ static int filename_split(char *filename, unsigned int *line_nr)
>  static int addr2line(const char *dso_name, u64 addr,
>  		     char **file, unsigned int *line_nr,
>  		     struct dso *dso __maybe_unused,
> -		     bool unwind_inlines __maybe_unused)
> +		     bool unwind_inlines __maybe_unused,
> +		     struct inline_node *node __maybe_unused)
>  {
>  	FILE *fp;
>  	char cmd[PATH_MAX];
> @@ -288,6 +367,57 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
>  {
>  }
>  
> +static struct inline_node *addr2inlines(const char *dso_name, u64 addr,
> +	struct dso *dso __maybe_unused)
> +{
> +	FILE *fp;
> +	char cmd[PATH_MAX];
> +	struct inline_node *node;
> +	char *filename = NULL;
> +	size_t len;
> +	unsigned int line_nr = 0;
> +
> +	scnprintf(cmd, sizeof(cmd), "addr2line -e %s -i %016"PRIx64,
> +		  dso_name, addr);
> +
> +	fp = popen(cmd, "r");
> +	if (fp == NULL) {
> +		pr_err("popen failed for %s\n", dso_name);
> +		return NULL;
> +	}
> +
> +	node = zalloc(sizeof(*node));
> +	if (node == NULL) {
> +		perror("not enough memory for the inline node");
> +		goto out;
> +	}
> +
> +	INIT_LIST_HEAD(&node->val);
> +	node->addr = addr;
> +
> +	while (getline(&filename, &len, fp) != -1) {
> +		if (filename_split(filename, &line_nr) != 1) {
> +			free(filename);
> +			goto out;
> +		}
> +
> +		if (inline_list__append(filename, NULL, line_nr, node) != 0)
> +			goto out;
> +
> +		filename = NULL;
> +	}
> +
> +out:
> +	pclose(fp);
> +
> +	if (list_empty(&node->val)) {
> +		inline_node__delete(node);
> +		return NULL;
> +	}
> +
> +	return node;
> +}
> +
>  #endif /* HAVE_LIBBFD_SUPPORT */
>  
>  /*
> @@ -311,7 +441,7 @@ char *__get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
>  	if (dso_name == NULL)
>  		goto out;
>  
> -	if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines))
> +	if (!addr2line(dso_name, addr, &file, &line, dso, unwind_inlines, NULL))
>  		goto out;
>  
>  	if (asprintf(&srcline, "%s:%u",
> @@ -351,3 +481,32 @@ char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
>  {
>  	return __get_srcline(dso, addr, sym, show_sym, false);
>  }
> +
> +struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr)
> +{
> +	const char *dso_name;
> +
> +	dso_name = dso__name(dso);
> +	if (dso_name == NULL)
> +		return NULL;
> +
> +	return addr2inlines(dso_name, addr, dso);
> +}
> +
> +void inline_node__delete(struct inline_node *node)
> +{
> +	struct inline_list *ilist, *tmp;
> +
> +	list_for_each_entry_safe(ilist, tmp, &node->val, list) {
> +		list_del_init(&ilist->list);
> +		if (ilist->filename != NULL)
> +			free(ilist->filename);
> +
> +		if (ilist->funcname != NULL)
> +			free(ilist->funcname);
> +
> +		free(ilist);
> +	}
> +
> +	free(node);
> +}
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 4e59dde..3a1dda3 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -390,6 +390,11 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss, struct map *
>  	return 0;
>  }
>  
> +char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name)
> +{
> +	return demangle_sym(dso, kmodule, elf_name);
> +}
> +
>  /*
>   * Align offset to 4 bytes as needed for note name and descriptor data.
>   */
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 6c358b7..8adf045 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -305,6 +305,8 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
>  int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss,
>  				struct map *map);
>  
> +char *dso__demangle_sym(struct dso *dso, int kmodule, char *elf_name);
> +
>  void __symbols__insert(struct rb_root *symbols, struct symbol *sym, bool kernel);
>  void symbols__insert(struct rb_root *symbols, struct symbol *sym);
>  void symbols__fixup_duplicate(struct rb_root *symbols);
> diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
> index b2cfa47..cc0700d 100644
> --- a/tools/perf/util/util.h
> +++ b/tools/perf/util/util.h
> @@ -364,4 +364,20 @@ int is_printable_array(char *p, unsigned int len);
>  int timestamp__scnprintf_usec(u64 timestamp, char *buf, size_t sz);
>  
>  int unit_number__scnprintf(char *buf, size_t size, u64 n);
> +
> +struct inline_list {
> +	char			*filename;
> +	char			*funcname;
> +	unsigned int		line_nr;
> +	struct list_head	list;
> +};
> +
> +struct inline_node {
> +	u64			addr;
> +	struct list_head	val;
> +};
> +
> +struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr);
> +void inline_node__delete(struct inline_node *node);
> +
>  #endif /* GIT_COMPAT_UTIL_H */
> -- 
> 2.7.4

[toc] | [prev] | [next] | [standalone]


#1609112 — Re: [PATCH v5 2/5] perf report: Find the inline stack for a given address

FromRavi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Date2017-03-25 08:20 +0100
SubjectRe: [PATCH v5 2/5] perf report: Find the inline stack for a given address
Message-ID<toO9r-5RU-7@gated-at.bofh.it>
In reply to#1602294
Hi Jin / Arnaldo,

I see a build failure with this patch:

On Friday 17 March 2017 03:12 AM, Jin Yao wrote:
> It would be useful for perf to support a mode to query the
> inline stack for a given callgraph address. This would simplify
> finding the right code in code that does a lot of inlining.
>
> The srcline.c has contained the code which supports to translate
> the address to filename:line_nr. This patch just extends the
> function to let it support getting the inline stacks.
...
> +	while (getline(&filename, &len, fp) != -1) {
> +		if (filename_split(filename, &line_nr) != 1) {
> +			free(filename);
> +			goto out;
> +		}
> +
> +		if (inline_list__append(filename, NULL, line_nr, node) != 0)

util/srcline.c: In function ‘addr2inlines’:
util/srcline.c:403:7: error: too few arguments to function ‘inline_list__append’
   if (inline_list__append(filename, NULL, line_nr, node) != 0)
       ^
util/srcline.c:34:12: note: declared here
 static int inline_list__append(char *filename, char *funcname, int line_nr,
            ^
util/srcline.c: At top level:
util/srcline.c:60:13: error: ‘inline_list__reverse’ defined but not used [-Werror=unused-function]
 static void inline_list__reverse(struct inline_node *node)
             ^
cc1: all warnings being treated as errors
mv: cannot stat ‘util/.srcline.o.tmp’: No such file or directory

Thanks,
Ravi

[toc] | [prev] | [next] | [standalone]


#1609150 — Re: [PATCH v5 2/5] perf report: Find the inline stack for a given address

From"Jin, Yao" <yao.jin@linux.intel.com>
Date2017-03-25 13:50 +0100
SubjectRe: [PATCH v5 2/5] perf report: Find the inline stack for a given address
Message-ID<toTiN-SR-11@gated-at.bofh.it>
In reply to#1609112
Hi Ravi, Arnaldo,

The build error happens when BFD lib is not set in build environment.

Anyway the patch series should be improved to get better compatibility 
for this case. For easy patch management, I send the v6 patch series for 
fixing this issue. Very sorry for the inconvenience.

Thanks

Jin Yao


On 3/25/2017 3:18 PM, Ravi Bangoria wrote:
> Hi Jin / Arnaldo,
>
> I see a build failure with this patch:
>
> On Friday 17 March 2017 03:12 AM, Jin Yao wrote:
>> It would be useful for perf to support a mode to query the
>> inline stack for a given callgraph address. This would simplify
>> finding the right code in code that does a lot of inlining.
>>
>> The srcline.c has contained the code which supports to translate
>> the address to filename:line_nr. This patch just extends the
>> function to let it support getting the inline stacks.
> ...
>> +	while (getline(&filename, &len, fp) != -1) {
>> +		if (filename_split(filename, &line_nr) != 1) {
>> +			free(filename);
>> +			goto out;
>> +		}
>> +
>> +		if (inline_list__append(filename, NULL, line_nr, node) != 0)
> util/srcline.c: In function ‘addr2inlines’:
> util/srcline.c:403:7: error: too few arguments to function ‘inline_list__append’
>     if (inline_list__append(filename, NULL, line_nr, node) != 0)
>         ^
> util/srcline.c:34:12: note: declared here
>   static int inline_list__append(char *filename, char *funcname, int line_nr,
>              ^
> util/srcline.c: At top level:
> util/srcline.c:60:13: error: ‘inline_list__reverse’ defined but not used [-Werror=unused-function]
>   static void inline_list__reverse(struct inline_node *node)
>               ^
> cc1: all warnings being treated as errors
> mv: cannot stat ‘util/.srcline.o.tmp’: No such file or directory
>
> Thanks,
> Ravi
>

[toc] | [prev] | [next] | [standalone]


#1602295 — [PATCH v5 4/5] perf report: Show inline stack for stdio mode

FromJin Yao <yao.jin@linux.intel.com>
Date2017-03-16 14:50 +0100
Subject[PATCH v5 4/5] perf report: Show inline stack for stdio mode
Message-ID<tlDWV-7vw-19@gated-at.bofh.it>
In reply to#1602292
If the address belongs to an inlined function, the source information
back to the first non-inlined function will be printed.

For example:

1. Show inlined function name
   perf report --stdio -g function --inline

     0.69%     0.00%  inline   ld-2.23.so           [.] dl_main
            |
            ---dl_main
               |
                --0.56%--_dl_relocate_object
                          _dl_relocate_object (inline)
                          elf_dynamic_do_Rela (inline)

2. Show the file/line information
   perf report --stdio -g address --inline

     0.69%     0.00%  inline   ld-2.23.so           [.] _dl_start_user
            |
            ---_dl_start_user .:0
               _dl_start rtld.c:307
               /build/glibc-GKVZIf/glibc-2.23/elf/rtld.c:413 (inline)
               _dl_sysdep_start dl-sysdep.c:250
               |
                --0.56%--dl_main rtld.c:2076

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
Tested-by: Milian Wolff <milian.wolff@kdab.com>
---
 tools/perf/ui/stdio/hist.c | 79 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 78 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index 668f4ae..183470f 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -17,6 +17,59 @@ static size_t callchain__fprintf_left_margin(FILE *fp, int left_margin)
 	return ret;
 }
 
+static size_t inline__fprintf(struct map *map, u64 ip, int left_margin,
+			      int depth, int depth_mask, FILE *fp)
+{
+	struct dso *dso;
+	struct inline_node *node;
+	struct inline_list *ilist;
+	int ret = 0, i;
+
+	if (map == NULL)
+		return 0;
+
+	dso = map->dso;
+	if (dso == NULL)
+		return 0;
+
+	if (dso->kernel != DSO_TYPE_USER)
+		return 0;
+
+	node = dso__parse_addr_inlines(dso,
+				       map__rip_2objdump(map, ip));
+	if (node == NULL)
+		return 0;
+
+
+	list_for_each_entry(ilist, &node->val, list) {
+		if ((ilist->filename != NULL) || (ilist->funcname != NULL)) {
+			ret += callchain__fprintf_left_margin(fp, left_margin);
+
+			for (i = 0; i < depth; i++) {
+				if (depth_mask & (1 << i))
+					ret += fprintf(fp, "|");
+				else
+					ret += fprintf(fp, " ");
+				ret += fprintf(fp, "          ");
+			}
+
+			if (callchain_param.key == CCKEY_ADDRESS) {
+				if (ilist->filename != NULL)
+					ret += fprintf(fp, "%s:%d (inline)",
+						       ilist->filename,
+						       ilist->line_nr);
+			} else if (ilist->funcname != NULL)
+				ret += fprintf(fp, "%s (inline)",
+					       ilist->funcname);
+
+			ret += fprintf(fp, "\n");
+		}
+	}
+
+	inline_node__delete(node);
+	return ret;
+}
+
 static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
 					  int left_margin)
 {
@@ -78,6 +131,10 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node,
 	fputs(str, fp);
 	fputc('\n', fp);
 	free(alloc_str);
+
+	if (symbol_conf.inline_name)
+		ret += inline__fprintf(chain->ms.map, chain->ip,
+				       left_margin, depth, depth_mask, fp);
 	return ret;
 }
 
@@ -229,6 +286,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
 			if (!i++ && field_order == NULL &&
 			    sort_order && !prefixcmp(sort_order, "sym"))
 				continue;
+
 			if (!printed) {
 				ret += callchain__fprintf_left_margin(fp, left_margin);
 				ret += fprintf(fp, "|\n");
@@ -251,6 +309,13 @@ static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
 
 			if (++entries_printed == callchain_param.print_limit)
 				break;
+
+			if (symbol_conf.inline_name)
+				ret += inline__fprintf(chain->ms.map,
+						       chain->ip,
+						       left_margin,
+						       0, 0,
+						       fp);
 		}
 		root = &cnode->rb_root;
 	}
@@ -529,6 +594,8 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 			       bool use_callchain)
 {
 	int ret;
+	int callchain_ret = 0;
+	int inline_ret = 0;
 	struct perf_hpp hpp = {
 		.buf		= bf,
 		.size		= size,
@@ -547,7 +614,17 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 	ret = fprintf(fp, "%s\n", bf);
 
 	if (use_callchain)
-		ret += hist_entry_callchain__fprintf(he, total_period, 0, fp);
+		callchain_ret = hist_entry_callchain__fprintf(he, total_period,
+							      0, fp);
+
+	if ((callchain_ret == 0) &&
+	    (symbol_conf.inline_name)) {
+		inline_ret = inline__fprintf(he->ms.map, he->ip, 0, 0, 0, fp);
+		ret += inline_ret;
+		if (inline_ret > 0)
+			ret += fprintf(fp, "\n");
+	} else
+		ret += callchain_ret;
 
 	return ret;
 }
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1603824

FromMilian Wolff <milian.wolff@kdab.com>
Date2017-03-18 18:40 +0100
Message-ID<tmquC-1ef-7@gated-at.bofh.it>
In reply to#1602292

[Multipart message — attachments visible in raw view] — view raw

On Donnerstag, 16. März 2017 22:42:22 CET Jin Yao wrote:
> v5: Update according to Milian Wolff's comments. It groups by address
>     (then display file/ line), or by function (then display function name).

Thank you Jin, that is really good. I tested it and it works really well for 
me.

Arnaldo, could you please consider merging this? It's an extremely useful 
feature and direly missing from perf so far.

That said, Jin, here are some observations that could be improved in the 
future (I don't think any of these should hold back merging this feature now):

For the following example code build with "-O2 -g" and recorded with "--call-
graph dwarf" I observe some output combinations that could potentially be 
improved in the future:

~~~~~~~~~~~~~~~~~~~~
#include <complex>
#include <cmath>
#include <random>
#include <iostream>

using namespace std;

int main()
{
    uniform_real_distribution<double> uniform(-1E5, 1E5);
    default_random_engine engine;
    double s = 0;
    for (int i = 0; i < 10000000; ++i) {
        s += norm(complex<double>(uniform(engine), uniform(engine)));
    }
    cout << s << '\n';
    return 0;
}
~~~~~~~~~~~~~~~~

#1 duplicated entries when grouping by function:

~~~~~~~~~~~~~~~~
perf report --inline --stdio
...
             --35.34%--_start
                       __libc_start_main
                       main
                       main (inline)
                       std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
long, 16807ul, 0ul, 2147483647ul> > (inline)
                       std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
long, 16807ul, 0ul, 2147483647ul> > (inline)
                       std::__detail::_Adaptor<std::linear_congruential_engine<unsigned 
long, 16807ul, 0ul, 2147483647ul>, double>::operator() (inline)
~~~~~~~~~~~~~~~~

Here, we see main twice, once for the "real" frame, and once for an inlined 
one? Then we see the same function twice as inlined frame, which is also odd.

~~~~~~~~~~~~~~~~
perf report --inline --stdio --no-children
...
    59.81%  cpp-inlining  libm-2.25.so      [.] __hypot_finite
            |
            ---__hypot_finite
               hypot
               main
               std::norm<double> (inline)
               main (inline)
               __libc_start_main
               _start
~~~~~~~~~~~~~~~~

Here we see a confusing output. The first "main" frame below "hypot" is 
actually code form cpp's complex header which got inlined into main. That 
associates the wrong function name to this frame, i.e. "main" instead of 
std::norm". When the inline stack is shown below we actually see what happens, 
i.e. we eventually end up in main again, but of course this output is not the 
best as-is.

But, again: I think these are minor issues, and the feature itself is already 
extremely useful and I hope to see it finally merged.

Thanks again Jin for your good work!

Cheers

-- 
Milian Wolff | milian.wolff@kdab.com | Software Engineer
KDAB (Deutschland) GmbH&Co KG, a KDAB Group company
Tel: +49-30-521325470
KDAB - The Qt Experts

[toc] | [prev] | [next] | [standalone]


#1608890

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-03-24 20:10 +0100
Message-ID<toCKZ-5Yy-3@gated-at.bofh.it>
In reply to#1603824
Em Sat, Mar 18, 2017 at 05:41:09PM +0100, Milian Wolff escreveu:
> On Donnerstag, 16. März 2017 22:42:22 CET Jin Yao wrote:
> > v5: Update according to Milian Wolff's comments. It groups by address
> >     (then display file/ line), or by function (then display function name).
> 
> Thank you Jin, that is really good. I tested it and it works really well for 
> me.
> 
> Arnaldo, could you please consider merging this? It's an extremely useful 
> feature and direly missing from perf so far.

Thanks, applied.
 
> That said, Jin, here are some observations that could be improved in the 
> future (I don't think any of these should hold back merging this feature now):
> 
> For the following example code build with "-O2 -g" and recorded with "--call-
> graph dwarf" I observe some output combinations that could potentially be 
> improved in the future:
> 
> ~~~~~~~~~~~~~~~~~~~~
> #include <complex>
> #include <cmath>
> #include <random>
> #include <iostream>
> 
> using namespace std;
> 
> int main()
> {
>     uniform_real_distribution<double> uniform(-1E5, 1E5);
>     default_random_engine engine;
>     double s = 0;
>     for (int i = 0; i < 10000000; ++i) {
>         s += norm(complex<double>(uniform(engine), uniform(engine)));
>     }
>     cout << s << '\n';
>     return 0;
> }
> ~~~~~~~~~~~~~~~~
> 
> #1 duplicated entries when grouping by function:
> 
> ~~~~~~~~~~~~~~~~
> perf report --inline --stdio
> ...
>              --35.34%--_start
>                        __libc_start_main
>                        main
>                        main (inline)
>                        std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
> long, 16807ul, 0ul, 2147483647ul> > (inline)
>                        std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
> long, 16807ul, 0ul, 2147483647ul> > (inline)
>                        std::__detail::_Adaptor<std::linear_congruential_engine<unsigned 
> long, 16807ul, 0ul, 2147483647ul>, double>::operator() (inline)
> ~~~~~~~~~~~~~~~~
> 
> Here, we see main twice, once for the "real" frame, and once for an inlined 
> one? Then we see the same function twice as inlined frame, which is also odd.
> 
> ~~~~~~~~~~~~~~~~
> perf report --inline --stdio --no-children
> ...
>     59.81%  cpp-inlining  libm-2.25.so      [.] __hypot_finite
>             |
>             ---__hypot_finite
>                hypot
>                main
>                std::norm<double> (inline)
>                main (inline)
>                __libc_start_main
>                _start
> ~~~~~~~~~~~~~~~~
> 
> Here we see a confusing output. The first "main" frame below "hypot" is 
> actually code form cpp's complex header which got inlined into main. That 
> associates the wrong function name to this frame, i.e. "main" instead of 
> std::norm". When the inline stack is shown below we actually see what happens, 
> i.e. we eventually end up in main again, but of course this output is not the 
> best as-is.
> 
> But, again: I think these are minor issues, and the feature itself is already 
> extremely useful and I hope to see it finally merged.
> 
> Thanks again Jin for your good work!
> 
> Cheers
> 
> -- 
> Milian Wolff | milian.wolff@kdab.com | Software Engineer
> KDAB (Deutschland) GmbH&Co KG, a KDAB Group company
> Tel: +49-30-521325470
> KDAB - The Qt Experts

[toc] | [prev] | [next] | [standalone]


#1608919

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-03-24 20:30 +0100
Message-ID<toD4n-679-45@gated-at.bofh.it>
In reply to#1608890
Em Fri, Mar 24, 2017 at 04:01:19PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Sat, Mar 18, 2017 at 05:41:09PM +0100, Milian Wolff escreveu:
> > On Donnerstag, 16. März 2017 22:42:22 CET Jin Yao wrote:
> > > v5: Update according to Milian Wolff's comments. It groups by address
> > >     (then display file/ line), or by function (then display function name).
> > 
> > Thank you Jin, that is really good. I tested it and it works really well for 
> > me.
> > 
> > Arnaldo, could you please consider merging this? It's an extremely useful 
> > feature and direly missing from perf so far.
> 
> Thanks, applied.

But it fails testing in some cases, see below, will try to fix later, if nobody
beats me to it, what I have is in acme/perf/core, git.kernel.org


  make -C tools/perf build-test

<SNIP>
make_minimal_O: cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 FEATURES_DUMP=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP -j4 O=/tmp/tmp.dQoIXBCebw DESTDIR=/tmp/tmp.zgrFKdJikV
cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 FEATURES_DUMP=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP -j4 O=/tmp/tmp.dQoIXBCebw DESTDIR=/tmp/tmp.zgrFKdJikV
  BUILD:   Doing 'make -j4' parallel build
  HOSTCC   /tmp/tmp.dQoIXBCebw/fixdep.o
  HOSTLD   /tmp/tmp.dQoIXBCebw/fixdep-in.o
  LINK     /tmp/tmp.dQoIXBCebw/fixdep
Makefile.config:458: Disabling post unwind, no support found.
Makefile.config:594: Python support disabled by user
  GEN      /tmp/tmp.dQoIXBCebw/common-cmds.h
Warning: x86_64's syscall_64.tbl differs from kernel
  MKDIR    /tmp/tmp.dQoIXBCebw/fd/
  CC       /tmp/tmp.dQoIXBCebw/fd/array.o
  CC       /tmp/tmp.dQoIXBCebw/event-parse.o
  MKDIR    /tmp/tmp.dQoIXBCebw/fs/
  CC       /tmp/tmp.dQoIXBCebw/fs/fs.o
  LD       /tmp/tmp.dQoIXBCebw/fd/libapi-in.o
  CC       /tmp/tmp.dQoIXBCebw/cpu.o
  CC       /tmp/tmp.dQoIXBCebw/debug.o
  PERF_VERSION = 4.11.rc2.g8bc82f
  CC       /tmp/tmp.dQoIXBCebw/exec-cmd.o
  CC       /tmp/tmp.dQoIXBCebw/str_error_r.o
  MKDIR    /tmp/tmp.dQoIXBCebw/pmu-events/
  MKDIR    /tmp/tmp.dQoIXBCebw/fs/
  HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/json.o
  CC       /tmp/tmp.dQoIXBCebw/fs/tracing_path.o
  MKDIR    /tmp/tmp.dQoIXBCebw/pmu-events/
  HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/jsmn.o
  CC       /tmp/tmp.dQoIXBCebw/help.o
  LD       /tmp/tmp.dQoIXBCebw/fs/libapi-in.o
  HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/jevents.o
  LD       /tmp/tmp.dQoIXBCebw/libapi-in.o
  AR       /tmp/tmp.dQoIXBCebw/libapi.a
  CC       /tmp/tmp.dQoIXBCebw/plugin_jbd2.o
  CC       /tmp/tmp.dQoIXBCebw/event-plugin.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_jbd2-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_hrtimer.o
  HOSTLD   /tmp/tmp.dQoIXBCebw/pmu-events/jevents-in.o
  CC       /tmp/tmp.dQoIXBCebw/perf-read-vdso32
  LD       /tmp/tmp.dQoIXBCebw/plugin_hrtimer-in.o
  GEN      perf-archive
  CC       /tmp/tmp.dQoIXBCebw/plugin_kmem.o
  GEN      perf-with-kcore
  CC       /tmp/tmp.dQoIXBCebw/trace-seq.o
  MKDIR    /tmp/tmp.dQoIXBCebw/util/
  CC       /tmp/tmp.dQoIXBCebw/util/alias.o
  CC       /tmp/tmp.dQoIXBCebw/pager.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_kmem-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_kvm.o
  CC       /tmp/tmp.dQoIXBCebw/parse-filter.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_kvm-in.o
  CC       /tmp/tmp.dQoIXBCebw/parse-options.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_mac80211.o
  MKDIR    /tmp/tmp.dQoIXBCebw/util/
  CC       /tmp/tmp.dQoIXBCebw/util/annotate.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_mac80211-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_sched_switch.o
  CC       /tmp/tmp.dQoIXBCebw/parse-utils.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_sched_switch-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_function.o
  CC       /tmp/tmp.dQoIXBCebw/kbuffer-parse.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_function-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_xen.o
  LD       /tmp/tmp.dQoIXBCebw/libtraceevent-in.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_xen-in.o
  LINK     /tmp/tmp.dQoIXBCebw/libtraceevent.a
  CC       /tmp/tmp.dQoIXBCebw/plugin_scsi.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-bench.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_scsi-in.o
  CC       /tmp/tmp.dQoIXBCebw/plugin_cfg80211.o
  LD       /tmp/tmp.dQoIXBCebw/plugin_cfg80211-in.o
  LINK     /tmp/tmp.dQoIXBCebw/plugin_jbd2.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_hrtimer.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_kmem.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_kvm.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_mac80211.so
  CC       /tmp/tmp.dQoIXBCebw/run-command.o
  LINK     /tmp/tmp.dQoIXBCebw/plugin_sched_switch.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_function.so
  CC       /tmp/tmp.dQoIXBCebw/builtin-annotate.o
  LINK     /tmp/tmp.dQoIXBCebw/plugin_xen.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_scsi.so
  LINK     /tmp/tmp.dQoIXBCebw/plugin_cfg80211.so
  LINK     /tmp/tmp.dQoIXBCebw/pmu-events/jevents
  CC       /tmp/tmp.dQoIXBCebw/sigchain.o
  GEN      /tmp/tmp.dQoIXBCebw/libtraceevent-dynamic-list
  GEN      /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events.c
  CC       /tmp/tmp.dQoIXBCebw/subcmd-config.o
  LD       /tmp/tmp.dQoIXBCebw/libsubcmd-in.o
  CC       /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events.o
  AR       /tmp/tmp.dQoIXBCebw/libsubcmd.a
  CC       /tmp/tmp.dQoIXBCebw/util/block-range.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-config.o
  CC       /tmp/tmp.dQoIXBCebw/util/build-id.o
  CC       /tmp/tmp.dQoIXBCebw/util/config.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-diff.o
  LD       /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events-in.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-evlist.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-ftrace.o
  CC       /tmp/tmp.dQoIXBCebw/util/ctype.o
  CC       /tmp/tmp.dQoIXBCebw/util/db-export.o
  CC       /tmp/tmp.dQoIXBCebw/util/env.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-help.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-sched.o
  CC       /tmp/tmp.dQoIXBCebw/util/event.o
  CC       /tmp/tmp.dQoIXBCebw/util/evlist.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-buildid-list.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-buildid-cache.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-kallsyms.o
  CC       /tmp/tmp.dQoIXBCebw/util/evsel.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-list.o
  CC       /tmp/tmp.dQoIXBCebw/util/evsel_fprintf.o
  CC       /tmp/tmp.dQoIXBCebw/arch/common.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-record.o
  CC       /tmp/tmp.dQoIXBCebw/util/find_bit.o
  CC       /tmp/tmp.dQoIXBCebw/util/kallsyms.o
  MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/util/
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/header.o
  CC       /tmp/tmp.dQoIXBCebw/util/levenshtein.o
  MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/util/
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/tsc.o
  CC       /tmp/tmp.dQoIXBCebw/util/llvm-utils.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/pmu.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-report.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/kvm-stat.o
  BISON    /tmp/tmp.dQoIXBCebw/util/parse-events-bison.c
  CC       /tmp/tmp.dQoIXBCebw/util/perf_regs.o
  CC       /tmp/tmp.dQoIXBCebw/util/path.o
  CC       /tmp/tmp.dQoIXBCebw/util/rbtree.o
  CC       /tmp/tmp.dQoIXBCebw/util/libstring.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/perf_regs.o
  CC       /tmp/tmp.dQoIXBCebw/util/bitmap.o
  CC       /tmp/tmp.dQoIXBCebw/util/hweight.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/group.o
  CC       /tmp/tmp.dQoIXBCebw/util/quote.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-stat.o
  LD       /tmp/tmp.dQoIXBCebw/arch/x86/util/libperf-in.o
  MKDIR    /tmp/tmp.dQoIXBCebw/ui/
  CC       /tmp/tmp.dQoIXBCebw/ui/setup.o
  MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/tests/
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/arch-tests.o
  MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/tests/
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/rdpmc.o
  CC       /tmp/tmp.dQoIXBCebw/util/strbuf.o
  MKDIR    /tmp/tmp.dQoIXBCebw/ui/
  CC       /tmp/tmp.dQoIXBCebw/ui/helpline.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/perf-time-to-tsc.o
  CC       /tmp/tmp.dQoIXBCebw/util/string.o
  CC       /tmp/tmp.dQoIXBCebw/ui/progress.o
  CC       /tmp/tmp.dQoIXBCebw/ui/util.o
  CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/intel-cqm.o
  CC       /tmp/tmp.dQoIXBCebw/ui/hist.o
  CC       /tmp/tmp.dQoIXBCebw/util/strlist.o
  LD       /tmp/tmp.dQoIXBCebw/arch/x86/tests/libperf-in.o
  LD       /tmp/tmp.dQoIXBCebw/arch/x86/libperf-in.o
  LD       /tmp/tmp.dQoIXBCebw/arch/libperf-in.o
  MKDIR    /tmp/tmp.dQoIXBCebw/scripts/
  LD       /tmp/tmp.dQoIXBCebw/scripts/libperf-in.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-timechart.o
  CC       /tmp/tmp.dQoIXBCebw/util/strfilter.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-top.o
  CC       /tmp/tmp.dQoIXBCebw/util/top.o
  CC       /tmp/tmp.dQoIXBCebw/util/usage.o
  CC       /tmp/tmp.dQoIXBCebw/util/dso.o
  MKDIR    /tmp/tmp.dQoIXBCebw/ui/stdio/
  CC       /tmp/tmp.dQoIXBCebw/ui/stdio/hist.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-script.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-kmem.o
  LD       /tmp/tmp.dQoIXBCebw/ui/libperf-in.o
  CC       /tmp/tmp.dQoIXBCebw/util/symbol.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-lock.o
  CC       /tmp/tmp.dQoIXBCebw/util/symbol_fprintf.o
  CC       /tmp/tmp.dQoIXBCebw/util/color.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-kvm.o
  CC       /tmp/tmp.dQoIXBCebw/util/header.o
  CC       /tmp/tmp.dQoIXBCebw/util/callchain.o
  CC       /tmp/tmp.dQoIXBCebw/util/values.o
  CC       /tmp/tmp.dQoIXBCebw/util/debug.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-inject.o
  CC       /tmp/tmp.dQoIXBCebw/util/machine.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-mem.o
  CC       /tmp/tmp.dQoIXBCebw/util/map.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-data.o
  CC       /tmp/tmp.dQoIXBCebw/util/pstack.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-version.o
  CC       /tmp/tmp.dQoIXBCebw/util/session.o
  CC       /tmp/tmp.dQoIXBCebw/builtin-c2c.o
  CC       /tmp/tmp.dQoIXBCebw/util/ordered-events.o
  CC       /tmp/tmp.dQoIXBCebw/util/namespaces.o
  MKDIR    /tmp/tmp.dQoIXBCebw/bench/
  CC       /tmp/tmp.dQoIXBCebw/bench/sched-messaging.o
  CC       /tmp/tmp.dQoIXBCebw/util/comm.o
  MKDIR    /tmp/tmp.dQoIXBCebw/bench/
  CC       /tmp/tmp.dQoIXBCebw/bench/sched-pipe.o
  CC       /tmp/tmp.dQoIXBCebw/util/thread.o
  CC       /tmp/tmp.dQoIXBCebw/bench/mem-functions.o
  CC       /tmp/tmp.dQoIXBCebw/util/thread_map.o
  CC       /tmp/tmp.dQoIXBCebw/util/trace-event-parse.o
  MKDIR    /tmp/tmp.dQoIXBCebw/tests/
  CC       /tmp/tmp.dQoIXBCebw/tests/builtin-test.o
  CC       /tmp/tmp.dQoIXBCebw/bench/futex-hash.o
  CC       /tmp/tmp.dQoIXBCebw/util/parse-events-bison.o
  CC       /tmp/tmp.dQoIXBCebw/bench/futex-wake.o
  BISON    /tmp/tmp.dQoIXBCebw/util/pmu-bison.c
  CC       /tmp/tmp.dQoIXBCebw/util/trace-event-read.o
  MKDIR    /tmp/tmp.dQoIXBCebw/tests/
  CC       /tmp/tmp.dQoIXBCebw/tests/parse-events.o
  CC       /tmp/tmp.dQoIXBCebw/bench/futex-wake-parallel.o
  CC       /tmp/tmp.dQoIXBCebw/util/trace-event-info.o
  CC       /tmp/tmp.dQoIXBCebw/bench/futex-requeue.o
  CC       /tmp/tmp.dQoIXBCebw/util/trace-event-scripting.o
  CC       /tmp/tmp.dQoIXBCebw/bench/futex-lock-pi.o
  CC       /tmp/tmp.dQoIXBCebw/util/trace-event.o
  CC       /tmp/tmp.dQoIXBCebw/bench/mem-memcpy-x86-64-asm.o
  CC       /tmp/tmp.dQoIXBCebw/bench/mem-memset-x86-64-asm.o
  CC       /tmp/tmp.dQoIXBCebw/util/svghelper.o
  LD       /tmp/tmp.dQoIXBCebw/bench/perf-in.o
  CC       /tmp/tmp.dQoIXBCebw/perf.o
  CC       /tmp/tmp.dQoIXBCebw/util/sort.o
  CC       /tmp/tmp.dQoIXBCebw/tests/dso-data.o
  CC       /tmp/tmp.dQoIXBCebw/tests/attr.o
  CC       /tmp/tmp.dQoIXBCebw/util/hist.o
  CC       /tmp/tmp.dQoIXBCebw/tests/vmlinux-kallsyms.o
  CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall.o
  CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall-all-cpus.o
  CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall-tp-fields.o
  CC       /tmp/tmp.dQoIXBCebw/tests/mmap-basic.o
  CC       /tmp/tmp.dQoIXBCebw/tests/perf-record.o
  CC       /tmp/tmp.dQoIXBCebw/util/util.o
  CC       /tmp/tmp.dQoIXBCebw/tests/evsel-roundtrip-name.o
  CC       /tmp/tmp.dQoIXBCebw/tests/evsel-tp-sched.o
  CC       /tmp/tmp.dQoIXBCebw/tests/fdarray.o
  CC       /tmp/tmp.dQoIXBCebw/util/xyarray.o
  CC       /tmp/tmp.dQoIXBCebw/tests/pmu.o
  CC       /tmp/tmp.dQoIXBCebw/util/cpumap.o
  CC       /tmp/tmp.dQoIXBCebw/tests/hists_common.o
  CC       /tmp/tmp.dQoIXBCebw/util/cgroup.o
  CC       /tmp/tmp.dQoIXBCebw/tests/hists_link.o
  CC       /tmp/tmp.dQoIXBCebw/tests/hists_filter.o
  CC       /tmp/tmp.dQoIXBCebw/util/target.o
  CC       /tmp/tmp.dQoIXBCebw/tests/hists_output.o
  CC       /tmp/tmp.dQoIXBCebw/util/rblist.o
  CC       /tmp/tmp.dQoIXBCebw/util/intlist.o
  CC       /tmp/tmp.dQoIXBCebw/tests/hists_cumulate.o
  CC       /tmp/tmp.dQoIXBCebw/util/vdso.o
  CC       /tmp/tmp.dQoIXBCebw/util/counts.o
  CC       /tmp/tmp.dQoIXBCebw/util/stat.o
  CC       /tmp/tmp.dQoIXBCebw/util/stat-shadow.o
  CC       /tmp/tmp.dQoIXBCebw/tests/python-use.o
  CC       /tmp/tmp.dQoIXBCebw/tests/bp_signal.o
  CC       /tmp/tmp.dQoIXBCebw/tests/bp_signal_overflow.o
  CC       /tmp/tmp.dQoIXBCebw/util/record.o
  CC       /tmp/tmp.dQoIXBCebw/tests/task-exit.o
  CC       /tmp/tmp.dQoIXBCebw/tests/sw-clock.o
  CC       /tmp/tmp.dQoIXBCebw/util/srcline.o
  CC       /tmp/tmp.dQoIXBCebw/tests/mmap-thread-lookup.o
  CC       /tmp/tmp.dQoIXBCebw/util/data.o
  CC       /tmp/tmp.dQoIXBCebw/tests/thread-mg-share.o
  CC       /tmp/tmp.dQoIXBCebw/util/tsc.o
  CC       /tmp/tmp.dQoIXBCebw/tests/switch-tracking.o
  CC       /tmp/tmp.dQoIXBCebw/util/cloexec.o
  CC       /tmp/tmp.dQoIXBCebw/tests/keep-tracking.o
  CC       /tmp/tmp.dQoIXBCebw/util/call-path.o
  CC       /tmp/tmp.dQoIXBCebw/util/thread-stack.o
  CC       /tmp/tmp.dQoIXBCebw/util/parse-branch-options.o
  CC       /tmp/tmp.dQoIXBCebw/tests/code-reading.o
  CC       /tmp/tmp.dQoIXBCebw/tests/sample-parsing.o
  CC       /tmp/tmp.dQoIXBCebw/util/dump-insn.o
  CC       /tmp/tmp.dQoIXBCebw/util/parse-regs-options.o
  CC       /tmp/tmp.dQoIXBCebw/util/term.o
  CC       /tmp/tmp.dQoIXBCebw/tests/parse-no-sample-id-all.o
  CC       /tmp/tmp.dQoIXBCebw/util/help-unknown-cmd.o
  CC       /tmp/tmp.dQoIXBCebw/tests/kmod-path.o
  CC       /tmp/tmp.dQoIXBCebw/util/mem-events.o
  CC       /tmp/tmp.dQoIXBCebw/tests/thread-map.o
  CC       /tmp/tmp.dQoIXBCebw/util/vsprintf.o
  CC       /tmp/tmp.dQoIXBCebw/util/drv_configs.o
  CC       /tmp/tmp.dQoIXBCebw/tests/llvm.o
  CC       /tmp/tmp.dQoIXBCebw/util/time-utils.o
  CC       /tmp/tmp.dQoIXBCebw/tests/bpf.o
  CC       /tmp/tmp.dQoIXBCebw/tests/topology.o
  BISON    /tmp/tmp.dQoIXBCebw/util/expr-bison.c
  CC       /tmp/tmp.dQoIXBCebw/util/symbol-minimal.o
  MKDIR    /tmp/tmp.dQoIXBCebw/util/scripting-engines/
  LD       /tmp/tmp.dQoIXBCebw/util/scripting-engines/libperf-in.o
  CC       /tmp/tmp.dQoIXBCebw/util/zlib.o
  CC       /tmp/tmp.dQoIXBCebw/tests/cpumap.o
  CC       /tmp/tmp.dQoIXBCebw/util/lzma.o
  CC       /tmp/tmp.dQoIXBCebw/tests/stat.o
  CC       /tmp/tmp.dQoIXBCebw/tests/event_update.o
  CC       /tmp/tmp.dQoIXBCebw/util/demangle-java.o
  CC       /tmp/tmp.dQoIXBCebw/tests/event-times.o
  CC       /tmp/tmp.dQoIXBCebw/util/demangle-rust.o
  CC       /tmp/tmp.dQoIXBCebw/tests/expr.o
  CC       /tmp/tmp.dQoIXBCebw/util/perf-hooks.o
  CC       /tmp/tmp.dQoIXBCebw/tests/backward-ring-buffer.o
  CC       /tmp/tmp.dQoIXBCebw/tests/sdt.o
  CC       /tmp/tmp.dQoIXBCebw/tests/is_printable_array.o
  FLEX     /tmp/tmp.dQoIXBCebw/util/parse-events-flex.c
  FLEX     /tmp/tmp.dQoIXBCebw/util/pmu-flex.c
  CC       /tmp/tmp.dQoIXBCebw/util/pmu-bison.o
  CC       /tmp/tmp.dQoIXBCebw/tests/bitmap.o
  CC       /tmp/tmp.dQoIXBCebw/tests/perf-hooks.o
  CC       /tmp/tmp.dQoIXBCebw/tests/clang.o
  CC       /tmp/tmp.dQoIXBCebw/util/expr-bison.o
  CC       /tmp/tmp.dQoIXBCebw/tests/unit_number__scnprintf.o
  CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-base.o
  CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-kbuild.o
  CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-prologue.o
  CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-relocation.o
  LD       /tmp/tmp.dQoIXBCebw/tests/perf-in.o
  CC       /tmp/tmp.dQoIXBCebw/util/parse-events.o
  CC       /tmp/tmp.dQoIXBCebw/util/pmu.o
  CC       /tmp/tmp.dQoIXBCebw/util/parse-events-flex.o
  LD       /tmp/tmp.dQoIXBCebw/perf-in.o
  CC       /tmp/tmp.dQoIXBCebw/util/pmu-flex.o
  LD       /tmp/tmp.dQoIXBCebw/util/libperf-in.o
  LD       /tmp/tmp.dQoIXBCebw/libperf-in.o
  AR       /tmp/tmp.dQoIXBCebw/libperf.a
  LINK     /tmp/tmp.dQoIXBCebw/perf
/tmp/tmp.dQoIXBCebw/libperf.a(libperf-in.o): In function `inline_list__append':
/home/acme/git/linux/tools/perf/util/srcline.c:47: undefined reference to `dso__demangle_sym'
collect2: error: ld returned 1 exit status
Makefile.perf:420: recipe for target '/tmp/tmp.dQoIXBCebw/perf' failed
make[4]: *** [/tmp/tmp.dQoIXBCebw/perf] Error 1
Makefile.perf:204: recipe for target 'sub-make' failed
make[3]: *** [sub-make] Error 2
Makefile:68: recipe for target 'all' failed
make[2]: *** [all] Error 2
tests/make:296: recipe for target 'make_minimal_O' failed
make[1]: *** [make_minimal_O] Error 1
Makefile:102: recipe for target 'build-test' failed
make: *** [build-test] Error 2
make: Leaving directory '/home/acme/git/linux/tools/perf'
[acme@jouet linux]$ 

  
> > That said, Jin, here are some observations that could be improved in the 
> > future (I don't think any of these should hold back merging this feature now):
> > 
> > For the following example code build with "-O2 -g" and recorded with "--call-
> > graph dwarf" I observe some output combinations that could potentially be 
> > improved in the future:
> > 
> > ~~~~~~~~~~~~~~~~~~~~
> > #include <complex>
> > #include <cmath>
> > #include <random>
> > #include <iostream>
> > 
> > using namespace std;
> > 
> > int main()
> > {
> >     uniform_real_distribution<double> uniform(-1E5, 1E5);
> >     default_random_engine engine;
> >     double s = 0;
> >     for (int i = 0; i < 10000000; ++i) {
> >         s += norm(complex<double>(uniform(engine), uniform(engine)));
> >     }
> >     cout << s << '\n';
> >     return 0;
> > }
> > ~~~~~~~~~~~~~~~~
> > 
> > #1 duplicated entries when grouping by function:
> > 
> > ~~~~~~~~~~~~~~~~
> > perf report --inline --stdio
> > ...
> >              --35.34%--_start
> >                        __libc_start_main
> >                        main
> >                        main (inline)
> >                        std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
> > long, 16807ul, 0ul, 2147483647ul> > (inline)
> >                        std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned 
> > long, 16807ul, 0ul, 2147483647ul> > (inline)
> >                        std::__detail::_Adaptor<std::linear_congruential_engine<unsigned 
> > long, 16807ul, 0ul, 2147483647ul>, double>::operator() (inline)
> > ~~~~~~~~~~~~~~~~
> > 
> > Here, we see main twice, once for the "real" frame, and once for an inlined 
> > one? Then we see the same function twice as inlined frame, which is also odd.
> > 
> > ~~~~~~~~~~~~~~~~
> > perf report --inline --stdio --no-children
> > ...
> >     59.81%  cpp-inlining  libm-2.25.so      [.] __hypot_finite
> >             |
> >             ---__hypot_finite
> >                hypot
> >                main
> >                std::norm<double> (inline)
> >                main (inline)
> >                __libc_start_main
> >                _start
> > ~~~~~~~~~~~~~~~~
> > 
> > Here we see a confusing output. The first "main" frame below "hypot" is 
> > actually code form cpp's complex header which got inlined into main. That 
> > associates the wrong function name to this frame, i.e. "main" instead of 
> > std::norm". When the inline stack is shown below we actually see what happens, 
> > i.e. we eventually end up in main again, but of course this output is not the 
> > best as-is.
> > 
> > But, again: I think these are minor issues, and the feature itself is already 
> > extremely useful and I hope to see it finally merged.
> > 
> > Thanks again Jin for your good work!
> > 
> > Cheers
> > 
> > -- 
> > Milian Wolff | milian.wolff@kdab.com | Software Engineer
> > KDAB (Deutschland) GmbH&Co KG, a KDAB Group company
> > Tel: +49-30-521325470
> > KDAB - The Qt Experts
> 
> 

[toc] | [prev] | [next] | [standalone]


#1609043

From"Jin, Yao" <yao.jin@linux.intel.com>
Date2017-03-25 01:30 +0100
Message-ID<toHKF-16C-3@gated-at.bofh.it>
In reply to#1608919
Hi Arnaldo,

I checked it needed to add dso__dmangle_sym() in symbol-minimal.c.

make -C tools/perf build-test

..........

iqhvUMsN DESTDIR=/tmp/tmp.9zqX9FtV0p
Makefile:203: Please install asciidoc xmlto to have the man pages installed
              make_no_slang_O: cd . && make NO_SLANG=1 
FEATURES_DUMP=/home/jinyao/skl-ws/perf-dev/tmp/acme/tools/perf/BUILD_TEST_FEATURE_DUMP 
-j8 O=/tmp/tmp.eDBcxsrMuA DESTDIR=/tmp/tmp.0wwJYGzYTr
OK

I will send a patch "perf report: Fix build-test error for 
make_minimal_O target" to fix that.

Thanks so much for your help!

Thanks

Jin Yao

On 3/25/2017 3:24 AM, Arnaldo Carvalho de Melo wrote:
> Em Fri, Mar 24, 2017 at 04:01:19PM -0300, Arnaldo Carvalho de Melo escreveu:
>> Em Sat, Mar 18, 2017 at 05:41:09PM +0100, Milian Wolff escreveu:
>>> On Donnerstag, 16. März 2017 22:42:22 CET Jin Yao wrote:
>>>> v5: Update according to Milian Wolff's comments. It groups by address
>>>>      (then display file/ line), or by function (then display function name).
>>> Thank you Jin, that is really good. I tested it and it works really well for
>>> me.
>>>
>>> Arnaldo, could you please consider merging this? It's an extremely useful
>>> feature and direly missing from perf so far.
>> Thanks, applied.
> But it fails testing in some cases, see below, will try to fix later, if nobody
> beats me to it, what I have is in acme/perf/core, git.kernel.org
>
>
>    make -C tools/perf build-test
>
> <SNIP>
> make_minimal_O: cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 FEATURES_DUMP=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP -j4 O=/tmp/tmp.dQoIXBCebw DESTDIR=/tmp/tmp.zgrFKdJikV
> cd . && make NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1 NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1 NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1 NO_LIBDW_DWARF_UNWIND=1 NO_AUXTRACE=1 NO_LIBBPF=1 NO_LIBCRYPTO=1 NO_SDT=1 NO_JVMTI=1 FEATURES_DUMP=/home/acme/git/linux/tools/perf/BUILD_TEST_FEATURE_DUMP -j4 O=/tmp/tmp.dQoIXBCebw DESTDIR=/tmp/tmp.zgrFKdJikV
>    BUILD:   Doing 'make -j4' parallel build
>    HOSTCC   /tmp/tmp.dQoIXBCebw/fixdep.o
>    HOSTLD   /tmp/tmp.dQoIXBCebw/fixdep-in.o
>    LINK     /tmp/tmp.dQoIXBCebw/fixdep
> Makefile.config:458: Disabling post unwind, no support found.
> Makefile.config:594: Python support disabled by user
>    GEN      /tmp/tmp.dQoIXBCebw/common-cmds.h
> Warning: x86_64's syscall_64.tbl differs from kernel
>    MKDIR    /tmp/tmp.dQoIXBCebw/fd/
>    CC       /tmp/tmp.dQoIXBCebw/fd/array.o
>    CC       /tmp/tmp.dQoIXBCebw/event-parse.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/fs/
>    CC       /tmp/tmp.dQoIXBCebw/fs/fs.o
>    LD       /tmp/tmp.dQoIXBCebw/fd/libapi-in.o
>    CC       /tmp/tmp.dQoIXBCebw/cpu.o
>    CC       /tmp/tmp.dQoIXBCebw/debug.o
>    PERF_VERSION = 4.11.rc2.g8bc82f
>    CC       /tmp/tmp.dQoIXBCebw/exec-cmd.o
>    CC       /tmp/tmp.dQoIXBCebw/str_error_r.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/pmu-events/
>    MKDIR    /tmp/tmp.dQoIXBCebw/fs/
>    HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/json.o
>    CC       /tmp/tmp.dQoIXBCebw/fs/tracing_path.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/pmu-events/
>    HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/jsmn.o
>    CC       /tmp/tmp.dQoIXBCebw/help.o
>    LD       /tmp/tmp.dQoIXBCebw/fs/libapi-in.o
>    HOSTCC   /tmp/tmp.dQoIXBCebw/pmu-events/jevents.o
>    LD       /tmp/tmp.dQoIXBCebw/libapi-in.o
>    AR       /tmp/tmp.dQoIXBCebw/libapi.a
>    CC       /tmp/tmp.dQoIXBCebw/plugin_jbd2.o
>    CC       /tmp/tmp.dQoIXBCebw/event-plugin.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_jbd2-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_hrtimer.o
>    HOSTLD   /tmp/tmp.dQoIXBCebw/pmu-events/jevents-in.o
>    CC       /tmp/tmp.dQoIXBCebw/perf-read-vdso32
>    LD       /tmp/tmp.dQoIXBCebw/plugin_hrtimer-in.o
>    GEN      perf-archive
>    CC       /tmp/tmp.dQoIXBCebw/plugin_kmem.o
>    GEN      perf-with-kcore
>    CC       /tmp/tmp.dQoIXBCebw/trace-seq.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/util/
>    CC       /tmp/tmp.dQoIXBCebw/util/alias.o
>    CC       /tmp/tmp.dQoIXBCebw/pager.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_kmem-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_kvm.o
>    CC       /tmp/tmp.dQoIXBCebw/parse-filter.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_kvm-in.o
>    CC       /tmp/tmp.dQoIXBCebw/parse-options.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_mac80211.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/util/
>    CC       /tmp/tmp.dQoIXBCebw/util/annotate.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_mac80211-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_sched_switch.o
>    CC       /tmp/tmp.dQoIXBCebw/parse-utils.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_sched_switch-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_function.o
>    CC       /tmp/tmp.dQoIXBCebw/kbuffer-parse.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_function-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_xen.o
>    LD       /tmp/tmp.dQoIXBCebw/libtraceevent-in.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_xen-in.o
>    LINK     /tmp/tmp.dQoIXBCebw/libtraceevent.a
>    CC       /tmp/tmp.dQoIXBCebw/plugin_scsi.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-bench.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_scsi-in.o
>    CC       /tmp/tmp.dQoIXBCebw/plugin_cfg80211.o
>    LD       /tmp/tmp.dQoIXBCebw/plugin_cfg80211-in.o
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_jbd2.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_hrtimer.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_kmem.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_kvm.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_mac80211.so
>    CC       /tmp/tmp.dQoIXBCebw/run-command.o
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_sched_switch.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_function.so
>    CC       /tmp/tmp.dQoIXBCebw/builtin-annotate.o
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_xen.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_scsi.so
>    LINK     /tmp/tmp.dQoIXBCebw/plugin_cfg80211.so
>    LINK     /tmp/tmp.dQoIXBCebw/pmu-events/jevents
>    CC       /tmp/tmp.dQoIXBCebw/sigchain.o
>    GEN      /tmp/tmp.dQoIXBCebw/libtraceevent-dynamic-list
>    GEN      /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events.c
>    CC       /tmp/tmp.dQoIXBCebw/subcmd-config.o
>    LD       /tmp/tmp.dQoIXBCebw/libsubcmd-in.o
>    CC       /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events.o
>    AR       /tmp/tmp.dQoIXBCebw/libsubcmd.a
>    CC       /tmp/tmp.dQoIXBCebw/util/block-range.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-config.o
>    CC       /tmp/tmp.dQoIXBCebw/util/build-id.o
>    CC       /tmp/tmp.dQoIXBCebw/util/config.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-diff.o
>    LD       /tmp/tmp.dQoIXBCebw/pmu-events/pmu-events-in.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-evlist.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-ftrace.o
>    CC       /tmp/tmp.dQoIXBCebw/util/ctype.o
>    CC       /tmp/tmp.dQoIXBCebw/util/db-export.o
>    CC       /tmp/tmp.dQoIXBCebw/util/env.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-help.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-sched.o
>    CC       /tmp/tmp.dQoIXBCebw/util/event.o
>    CC       /tmp/tmp.dQoIXBCebw/util/evlist.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-buildid-list.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-buildid-cache.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-kallsyms.o
>    CC       /tmp/tmp.dQoIXBCebw/util/evsel.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-list.o
>    CC       /tmp/tmp.dQoIXBCebw/util/evsel_fprintf.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/common.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-record.o
>    CC       /tmp/tmp.dQoIXBCebw/util/find_bit.o
>    CC       /tmp/tmp.dQoIXBCebw/util/kallsyms.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/util/
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/header.o
>    CC       /tmp/tmp.dQoIXBCebw/util/levenshtein.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/util/
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/tsc.o
>    CC       /tmp/tmp.dQoIXBCebw/util/llvm-utils.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/pmu.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-report.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/kvm-stat.o
>    BISON    /tmp/tmp.dQoIXBCebw/util/parse-events-bison.c
>    CC       /tmp/tmp.dQoIXBCebw/util/perf_regs.o
>    CC       /tmp/tmp.dQoIXBCebw/util/path.o
>    CC       /tmp/tmp.dQoIXBCebw/util/rbtree.o
>    CC       /tmp/tmp.dQoIXBCebw/util/libstring.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/perf_regs.o
>    CC       /tmp/tmp.dQoIXBCebw/util/bitmap.o
>    CC       /tmp/tmp.dQoIXBCebw/util/hweight.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/util/group.o
>    CC       /tmp/tmp.dQoIXBCebw/util/quote.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-stat.o
>    LD       /tmp/tmp.dQoIXBCebw/arch/x86/util/libperf-in.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/ui/
>    CC       /tmp/tmp.dQoIXBCebw/ui/setup.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/tests/
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/arch-tests.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/arch/x86/tests/
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/rdpmc.o
>    CC       /tmp/tmp.dQoIXBCebw/util/strbuf.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/ui/
>    CC       /tmp/tmp.dQoIXBCebw/ui/helpline.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/perf-time-to-tsc.o
>    CC       /tmp/tmp.dQoIXBCebw/util/string.o
>    CC       /tmp/tmp.dQoIXBCebw/ui/progress.o
>    CC       /tmp/tmp.dQoIXBCebw/ui/util.o
>    CC       /tmp/tmp.dQoIXBCebw/arch/x86/tests/intel-cqm.o
>    CC       /tmp/tmp.dQoIXBCebw/ui/hist.o
>    CC       /tmp/tmp.dQoIXBCebw/util/strlist.o
>    LD       /tmp/tmp.dQoIXBCebw/arch/x86/tests/libperf-in.o
>    LD       /tmp/tmp.dQoIXBCebw/arch/x86/libperf-in.o
>    LD       /tmp/tmp.dQoIXBCebw/arch/libperf-in.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/scripts/
>    LD       /tmp/tmp.dQoIXBCebw/scripts/libperf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-timechart.o
>    CC       /tmp/tmp.dQoIXBCebw/util/strfilter.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-top.o
>    CC       /tmp/tmp.dQoIXBCebw/util/top.o
>    CC       /tmp/tmp.dQoIXBCebw/util/usage.o
>    CC       /tmp/tmp.dQoIXBCebw/util/dso.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/ui/stdio/
>    CC       /tmp/tmp.dQoIXBCebw/ui/stdio/hist.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-script.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-kmem.o
>    LD       /tmp/tmp.dQoIXBCebw/ui/libperf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/util/symbol.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-lock.o
>    CC       /tmp/tmp.dQoIXBCebw/util/symbol_fprintf.o
>    CC       /tmp/tmp.dQoIXBCebw/util/color.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-kvm.o
>    CC       /tmp/tmp.dQoIXBCebw/util/header.o
>    CC       /tmp/tmp.dQoIXBCebw/util/callchain.o
>    CC       /tmp/tmp.dQoIXBCebw/util/values.o
>    CC       /tmp/tmp.dQoIXBCebw/util/debug.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-inject.o
>    CC       /tmp/tmp.dQoIXBCebw/util/machine.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-mem.o
>    CC       /tmp/tmp.dQoIXBCebw/util/map.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-data.o
>    CC       /tmp/tmp.dQoIXBCebw/util/pstack.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-version.o
>    CC       /tmp/tmp.dQoIXBCebw/util/session.o
>    CC       /tmp/tmp.dQoIXBCebw/builtin-c2c.o
>    CC       /tmp/tmp.dQoIXBCebw/util/ordered-events.o
>    CC       /tmp/tmp.dQoIXBCebw/util/namespaces.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/bench/
>    CC       /tmp/tmp.dQoIXBCebw/bench/sched-messaging.o
>    CC       /tmp/tmp.dQoIXBCebw/util/comm.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/bench/
>    CC       /tmp/tmp.dQoIXBCebw/bench/sched-pipe.o
>    CC       /tmp/tmp.dQoIXBCebw/util/thread.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/mem-functions.o
>    CC       /tmp/tmp.dQoIXBCebw/util/thread_map.o
>    CC       /tmp/tmp.dQoIXBCebw/util/trace-event-parse.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/tests/
>    CC       /tmp/tmp.dQoIXBCebw/tests/builtin-test.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/futex-hash.o
>    CC       /tmp/tmp.dQoIXBCebw/util/parse-events-bison.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/futex-wake.o
>    BISON    /tmp/tmp.dQoIXBCebw/util/pmu-bison.c
>    CC       /tmp/tmp.dQoIXBCebw/util/trace-event-read.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/tests/
>    CC       /tmp/tmp.dQoIXBCebw/tests/parse-events.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/futex-wake-parallel.o
>    CC       /tmp/tmp.dQoIXBCebw/util/trace-event-info.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/futex-requeue.o
>    CC       /tmp/tmp.dQoIXBCebw/util/trace-event-scripting.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/futex-lock-pi.o
>    CC       /tmp/tmp.dQoIXBCebw/util/trace-event.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/mem-memcpy-x86-64-asm.o
>    CC       /tmp/tmp.dQoIXBCebw/bench/mem-memset-x86-64-asm.o
>    CC       /tmp/tmp.dQoIXBCebw/util/svghelper.o
>    LD       /tmp/tmp.dQoIXBCebw/bench/perf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/perf.o
>    CC       /tmp/tmp.dQoIXBCebw/util/sort.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/dso-data.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/attr.o
>    CC       /tmp/tmp.dQoIXBCebw/util/hist.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/vmlinux-kallsyms.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall-all-cpus.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/openat-syscall-tp-fields.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/mmap-basic.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/perf-record.o
>    CC       /tmp/tmp.dQoIXBCebw/util/util.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/evsel-roundtrip-name.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/evsel-tp-sched.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/fdarray.o
>    CC       /tmp/tmp.dQoIXBCebw/util/xyarray.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/pmu.o
>    CC       /tmp/tmp.dQoIXBCebw/util/cpumap.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/hists_common.o
>    CC       /tmp/tmp.dQoIXBCebw/util/cgroup.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/hists_link.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/hists_filter.o
>    CC       /tmp/tmp.dQoIXBCebw/util/target.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/hists_output.o
>    CC       /tmp/tmp.dQoIXBCebw/util/rblist.o
>    CC       /tmp/tmp.dQoIXBCebw/util/intlist.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/hists_cumulate.o
>    CC       /tmp/tmp.dQoIXBCebw/util/vdso.o
>    CC       /tmp/tmp.dQoIXBCebw/util/counts.o
>    CC       /tmp/tmp.dQoIXBCebw/util/stat.o
>    CC       /tmp/tmp.dQoIXBCebw/util/stat-shadow.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/python-use.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/bp_signal.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/bp_signal_overflow.o
>    CC       /tmp/tmp.dQoIXBCebw/util/record.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/task-exit.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/sw-clock.o
>    CC       /tmp/tmp.dQoIXBCebw/util/srcline.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/mmap-thread-lookup.o
>    CC       /tmp/tmp.dQoIXBCebw/util/data.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/thread-mg-share.o
>    CC       /tmp/tmp.dQoIXBCebw/util/tsc.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/switch-tracking.o
>    CC       /tmp/tmp.dQoIXBCebw/util/cloexec.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/keep-tracking.o
>    CC       /tmp/tmp.dQoIXBCebw/util/call-path.o
>    CC       /tmp/tmp.dQoIXBCebw/util/thread-stack.o
>    CC       /tmp/tmp.dQoIXBCebw/util/parse-branch-options.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/code-reading.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/sample-parsing.o
>    CC       /tmp/tmp.dQoIXBCebw/util/dump-insn.o
>    CC       /tmp/tmp.dQoIXBCebw/util/parse-regs-options.o
>    CC       /tmp/tmp.dQoIXBCebw/util/term.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/parse-no-sample-id-all.o
>    CC       /tmp/tmp.dQoIXBCebw/util/help-unknown-cmd.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/kmod-path.o
>    CC       /tmp/tmp.dQoIXBCebw/util/mem-events.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/thread-map.o
>    CC       /tmp/tmp.dQoIXBCebw/util/vsprintf.o
>    CC       /tmp/tmp.dQoIXBCebw/util/drv_configs.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/llvm.o
>    CC       /tmp/tmp.dQoIXBCebw/util/time-utils.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/bpf.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/topology.o
>    BISON    /tmp/tmp.dQoIXBCebw/util/expr-bison.c
>    CC       /tmp/tmp.dQoIXBCebw/util/symbol-minimal.o
>    MKDIR    /tmp/tmp.dQoIXBCebw/util/scripting-engines/
>    LD       /tmp/tmp.dQoIXBCebw/util/scripting-engines/libperf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/util/zlib.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/cpumap.o
>    CC       /tmp/tmp.dQoIXBCebw/util/lzma.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/stat.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/event_update.o
>    CC       /tmp/tmp.dQoIXBCebw/util/demangle-java.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/event-times.o
>    CC       /tmp/tmp.dQoIXBCebw/util/demangle-rust.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/expr.o
>    CC       /tmp/tmp.dQoIXBCebw/util/perf-hooks.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/backward-ring-buffer.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/sdt.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/is_printable_array.o
>    FLEX     /tmp/tmp.dQoIXBCebw/util/parse-events-flex.c
>    FLEX     /tmp/tmp.dQoIXBCebw/util/pmu-flex.c
>    CC       /tmp/tmp.dQoIXBCebw/util/pmu-bison.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/bitmap.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/perf-hooks.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/clang.o
>    CC       /tmp/tmp.dQoIXBCebw/util/expr-bison.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/unit_number__scnprintf.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-base.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-kbuild.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-prologue.o
>    CC       /tmp/tmp.dQoIXBCebw/tests/llvm-src-relocation.o
>    LD       /tmp/tmp.dQoIXBCebw/tests/perf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/util/parse-events.o
>    CC       /tmp/tmp.dQoIXBCebw/util/pmu.o
>    CC       /tmp/tmp.dQoIXBCebw/util/parse-events-flex.o
>    LD       /tmp/tmp.dQoIXBCebw/perf-in.o
>    CC       /tmp/tmp.dQoIXBCebw/util/pmu-flex.o
>    LD       /tmp/tmp.dQoIXBCebw/util/libperf-in.o
>    LD       /tmp/tmp.dQoIXBCebw/libperf-in.o
>    AR       /tmp/tmp.dQoIXBCebw/libperf.a
>    LINK     /tmp/tmp.dQoIXBCebw/perf
> /tmp/tmp.dQoIXBCebw/libperf.a(libperf-in.o): In function `inline_list__append':
> /home/acme/git/linux/tools/perf/util/srcline.c:47: undefined reference to `dso__demangle_sym'
> collect2: error: ld returned 1 exit status
> Makefile.perf:420: recipe for target '/tmp/tmp.dQoIXBCebw/perf' failed
> make[4]: *** [/tmp/tmp.dQoIXBCebw/perf] Error 1
> Makefile.perf:204: recipe for target 'sub-make' failed
> make[3]: *** [sub-make] Error 2
> Makefile:68: recipe for target 'all' failed
> make[2]: *** [all] Error 2
> tests/make:296: recipe for target 'make_minimal_O' failed
> make[1]: *** [make_minimal_O] Error 1
> Makefile:102: recipe for target 'build-test' failed
> make: *** [build-test] Error 2
> make: Leaving directory '/home/acme/git/linux/tools/perf'
> [acme@jouet linux]$
>
>    
>>> That said, Jin, here are some observations that could be improved in the
>>> future (I don't think any of these should hold back merging this feature now):
>>>
>>> For the following example code build with "-O2 -g" and recorded with "--call-
>>> graph dwarf" I observe some output combinations that could potentially be
>>> improved in the future:
>>>
>>> ~~~~~~~~~~~~~~~~~~~~
>>> #include <complex>
>>> #include <cmath>
>>> #include <random>
>>> #include <iostream>
>>>
>>> using namespace std;
>>>
>>> int main()
>>> {
>>>      uniform_real_distribution<double> uniform(-1E5, 1E5);
>>>      default_random_engine engine;
>>>      double s = 0;
>>>      for (int i = 0; i < 10000000; ++i) {
>>>          s += norm(complex<double>(uniform(engine), uniform(engine)));
>>>      }
>>>      cout << s << '\n';
>>>      return 0;
>>> }
>>> ~~~~~~~~~~~~~~~~
>>>
>>> #1 duplicated entries when grouping by function:
>>>
>>> ~~~~~~~~~~~~~~~~
>>> perf report --inline --stdio
>>> ...
>>>               --35.34%--_start
>>>                         __libc_start_main
>>>                         main
>>>                         main (inline)
>>>                         std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned
>>> long, 16807ul, 0ul, 2147483647ul> > (inline)
>>>                         std::uniform_real_distribution<double>::operator()<std::linear_congruential_engine<unsigned
>>> long, 16807ul, 0ul, 2147483647ul> > (inline)
>>>                         std::__detail::_Adaptor<std::linear_congruential_engine<unsigned
>>> long, 16807ul, 0ul, 2147483647ul>, double>::operator() (inline)
>>> ~~~~~~~~~~~~~~~~
>>>
>>> Here, we see main twice, once for the "real" frame, and once for an inlined
>>> one? Then we see the same function twice as inlined frame, which is also odd.
>>>
>>> ~~~~~~~~~~~~~~~~
>>> perf report --inline --stdio --no-children
>>> ...
>>>      59.81%  cpp-inlining  libm-2.25.so      [.] __hypot_finite
>>>              |
>>>              ---__hypot_finite
>>>                 hypot
>>>                 main
>>>                 std::norm<double> (inline)
>>>                 main (inline)
>>>                 __libc_start_main
>>>                 _start
>>> ~~~~~~~~~~~~~~~~
>>>
>>> Here we see a confusing output. The first "main" frame below "hypot" is
>>> actually code form cpp's complex header which got inlined into main. That
>>> associates the wrong function name to this frame, i.e. "main" instead of
>>> std::norm". When the inline stack is shown below we actually see what happens,
>>> i.e. we eventually end up in main again, but of course this output is not the
>>> best as-is.
>>>
>>> But, again: I think these are minor issues, and the feature itself is already
>>> extremely useful and I hope to see it finally merged.
>>>
>>> Thanks again Jin for your good work!
>>>
>>> Cheers
>>>
>>> -- 
>>> Milian Wolff | milian.wolff@kdab.com | Software Engineer
>>> KDAB (Deutschland) GmbH&Co KG, a KDAB Group company
>>> Tel: +49-30-521325470
>>> KDAB - The Qt Experts
>>

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web