* [PATCH -tip v4 0/7] perf: Introduce branch sub commands
@ 2011-05-26 5:02 Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 1/7] perf: new subcommand perf branch record Akihiro Nagai
` (7 more replies)
0 siblings, 8 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:02 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager
Hi,
This patch series provides the commands 'perf branch record' and
'perf branch trace' version 4. These commands record and analyze
a BTS (Branch Trace Store) log. And, they provide the interface
to use BTS log for application developers.
BTS is a facility of Intel x86 processors, which records the address of
'branch to/from' on every branch/jump instruction and interrupt.
This facility is very useful for developers to test their software,
for example, coverage test, execution path analysis, dynamic step count ...etc.
These test tools have a big advantage, which user doesn't have to modify target
executable binaries, because the BTS is a hardware feauture.
But, there are few applications using BTS. Reasons I guess are ...
- Few people know what BTS is.
- Few people know how to use BTS on Linux box.
- It's hard to analyze the BTS log because it includes just a series of
addresses.
So, I want to provide a user-friendly interface to BTS for application
developers.
About new sub commands
========================
'perf branch record' provides an easy way to record BTS log.
Usage is 'perf branch record <command>'. This command is just an alias to
'perf record -e branches:u -c 1 -d <command>'. But, new one is more simple
and more intuitive.
'perf branch trace' can parse and analyze recorded BTS log and print various
information of execution path. This command can show address, pid, command name,
function+offset, file path of elf.
You can choose the printed information with option.
Example: 'perf branch trace'
function+offset
_start+0x3 => _dl_start+0x0
_dl_start+0x71 => _dl_start+0x93
_dl_start+0x97 => _dl_start+0x78
_dl_start+0x97 => _dl_start+0x78
_dl_start+0xa3 => _dl_start+0x3c0
_dl_start+0x3c8 => _dl_start+0x3e8
...
This is the default behavior of 'perf branch trace'. It prints function+offset.
Example2: 'perf branch -cas trace'
command address function+offset
ls 0x0000003e9b000b23 _start+0x3 => 0x0000003e9b004540 _dl_start+0x0
ls 0x0000003e9b0045b1 _dl_start+0x71 => 0x0000003e9b0045d3 _dl_start+0x93
ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
ls 0x0000003e9b0045e3 _dl_start+0xa3 => 0x0000003e9b004900 _dl_start+0x3c0
ls 0x0000003e9b004908 _dl_start+0x3c8 => 0x0000003e9b004928 _dl_start+0x3e8
...
In the future, I'd like to make this more informative. For example
- Show source file path
- Show line number
- Show inlined function name
- Draw call graph
- Browse source code and coloring
- Make BTS record fast
and more!
Changes in V4:
- Add kenel filter
- Print PID and command only once in a line
- Add output TSV mode
Changes in V3:
- Update to the latest -tip tree
- Rename to 'perf branch'
- Process only BTS records
- Fix bug of getting elf_filepath
- Fix return value of __cmd_trace
Changes in V2:
- Update to the latest -tip tree
- Add bts explanation to the subcommand list
- Remove the patch already merged (add OPT_CALLBACK_DEFAULT_NOOPT)
- Add comments
- Add new function to the todo list
Thanks,
---
Akihiro Nagai (7):
perf branch trace: add kernel filter
perf branch trace: add print all option
perf branch trace: print function+offset
perf branch trace: print file path of the executed elf
perf branch trace: print pid and command
perf branch: Introduce new sub command 'perf branch trace'
perf: new subcommand perf branch record
tools/perf/Documentation/perf-branch.txt | 62 +++++
tools/perf/Makefile | 1
tools/perf/builtin-branch.c | 361 ++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1
tools/perf/command-list.txt | 1
tools/perf/perf.c | 1
6 files changed, 427 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/Documentation/perf-branch.txt
create mode 100644 tools/perf/builtin-branch.c
--
Akihiro Nagai (akihiro.nagai.hw@hitachi.com)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH -tip v4 1/7] perf: new subcommand perf branch record
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 2/7] perf branch: Introduce new sub command 'perf branch trace' Akihiro Nagai
` (6 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
Introduce the easy way to record the bts log, 'perf branch record'.
This command records the bts log while the specified command is executing,
and save to the file "perf.data"
Usage:
perf branch record <tracee command>
Example:
# perf branch record ls -l
(ls -l outputs)
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.007 MB perf.data (~320 samples) ]
# ls
perf.data
Changes in V3:
- rename to 'perf branch'
Changes in V2:
- Update to the latest -tip tree
- add bts explanation to the subcommand list
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 25 ++++++++++++
tools/perf/Makefile | 1
tools/perf/builtin-branch.c | 62 ++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1
tools/perf/command-list.txt | 1
tools/perf/perf.c | 1
6 files changed, 91 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/Documentation/perf-branch.txt
create mode 100644 tools/perf/builtin-branch.c
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
new file mode 100644
index 0000000..075cfce
--- /dev/null
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -0,0 +1,25 @@
+perf-branch(1)
+==============
+
+NAME
+----
+perf-branch - Record branch-trace-store log
+
+SYNOPSIS
+--------
+[verse]
+'perf branch' record <command>
+
+DESCRIPTION
+-----------
+This command records a branch-trace-store log.
+Branch-trace-store is a facility of processors. It can record
+addresses of from/to which the execution of a program branches,
+at every branch instruction and interrupt.
+
+'perf branch record <command>' records branch-trace-store log while
+the specified command is executing. And, save to the file "perf.data".
+
+SEE ALSO
+--------
+linkperf:perf-record[1]
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 1455413..d42b04c 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -370,6 +370,7 @@ BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
BUILTIN_OBJS += $(OUTPUT)builtin-test.o
BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
+BUILTIN_OBJS += $(OUTPUT)builtin-branch.o
PERFLIBS = $(LIB_FILE)
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
new file mode 100644
index 0000000..f338f3a
--- /dev/null
+++ b/tools/perf/builtin-branch.c
@@ -0,0 +1,62 @@
+#include "builtin.h"
+#include "perf.h"
+#include "util/parse-options.h"
+
+static const char * const branch_usage[] = {
+ "perf branch record <command>",
+ NULL,
+};
+
+/* arguments to call 'perf record' */
+static const char * const record_args[] = {
+ "record",
+ "-f",
+ "-e", "branches:u",
+ "-c", "1",
+ "-d",
+};
+
+/* dummy struct option to call parse_options() */
+static const struct option branch_options[] = {
+ OPT_END()
+};
+
+static int __cmd_record(int argc, const char **argv)
+{
+ unsigned int rec_argc, i, j;
+ const char **rec_argv;
+ int rc;
+
+ /* prepare the arguments list to call 'perf record' */
+ rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+ rec_argv = calloc(rec_argc + 1, sizeof(char *));
+
+ for (i = 0; i < ARRAY_SIZE(record_args); i++)
+ rec_argv[i] = record_args[i];
+
+ for (j = 1; j < (unsigned int)argc; j++, i++)
+ rec_argv[i] = argv[j];
+
+ BUG_ON(i != rec_argc);
+
+ /* call 'perf record' */
+ rc = cmd_record(i, rec_argv, NULL);
+
+ free(rec_argv);
+ return rc;
+}
+
+int cmd_branch(int argc, const char **argv, const char *prefix __used)
+{
+ argc = parse_options(argc, argv, branch_options, branch_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION);
+ if (!argc)
+ usage_with_options(branch_usage, branch_options);
+
+ if (!strcmp(argv[0], "record"))
+ return __cmd_record(argc, argv);
+ else
+ usage_with_options(branch_usage, branch_options);
+
+ return 0;
+}
diff --git a/tools/perf/builtin.h b/tools/perf/builtin.h
index 4702e24..89fefdc 100644
--- a/tools/perf/builtin.h
+++ b/tools/perf/builtin.h
@@ -36,5 +36,6 @@ extern int cmd_lock(int argc, const char **argv, const char *prefix);
extern int cmd_kvm(int argc, const char **argv, const char *prefix);
extern int cmd_test(int argc, const char **argv, const char *prefix);
extern int cmd_inject(int argc, const char **argv, const char *prefix);
+extern int cmd_branch(int argc, const char **argv, const char *prefix);
#endif
diff --git a/tools/perf/command-list.txt b/tools/perf/command-list.txt
index d695fe4..537f655 100644
--- a/tools/perf/command-list.txt
+++ b/tools/perf/command-list.txt
@@ -23,3 +23,4 @@ perf-kmem mainporcelain common
perf-lock mainporcelain common
perf-kvm mainporcelain common
perf-test mainporcelain common
+perf-branch mainporcelain common
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index ec635b7..cfd9318 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -332,6 +332,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "kvm", cmd_kvm, 0 },
{ "test", cmd_test, 0 },
{ "inject", cmd_inject, 0 },
+ { "branch", cmd_branch, 0 },
};
unsigned int i;
static const char ext[] = STRIP_EXTENSION;
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 2/7] perf branch: Introduce new sub command 'perf branch trace'
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 1/7] perf: new subcommand perf branch record Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 3/7] perf branch trace: print pid and command Akihiro Nagai
` (5 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
Introduce new sub command 'perf branch trace'.
This command parses and prints the bts log recorded by
'perf branch record'.
Usage:
- First, record the bts log 'perf branch record <command>'
- Second, parse and print bts log 'perf branch trace'
Output:
0xffffffff8146fe0e => 0x0000003806200b20
0x0000003806200b23 => 0x0000003806204910
0xffffffff8146fe0e => 0x0000003806204910
0xffffffff8146fe0e => 0x0000003806204936
0xffffffff8146fe0e => 0x000000380620493d
0x0000003806204981 => 0x00000038062049a3
0x00000038062049a7 => 0x0000003806204988
...
Changes in V4:
- Update to the latest -tip tree
- Add output TSV mode
Changes in V3:
- Update to the latest -tip tree
- Rename to 'perf branch'
- Process only BTS record
- Fix return value of __cmd_trace
Changes in V2:
- Update to the latest -tip tree
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 17 +++++-
tools/perf/builtin-branch.c | 92 +++++++++++++++++++++++++++++-
2 files changed, 103 insertions(+), 6 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index 075cfce..15ee496 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -3,16 +3,16 @@ perf-branch(1)
NAME
----
-perf-branch - Record branch-trace-store log
+perf-branch - Record and print branch-trace-store log
SYNOPSIS
--------
[verse]
-'perf branch' record <command>
+'perf branch' [<options>] {record|trace}
DESCRIPTION
-----------
-This command records a branch-trace-store log.
+This command records and prints a branch-trace-store log.
Branch-trace-store is a facility of processors. It can record
addresses of from/to which the execution of a program branches,
at every branch instruction and interrupt.
@@ -20,6 +20,17 @@ at every branch instruction and interrupt.
'perf branch record <command>' records branch-trace-store log while
the specified command is executing. And, save to the file "perf.data".
+'perf branch trace' parses recorded branch-trace-store log and prints it.
+
+OPTIONS
+-------
+-i::
+--input=::
+ Specify input file name to analyze.
+-t::
+--tsv::
+ Output TSV format.
+
SEE ALSO
--------
linkperf:perf-record[1]
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index f338f3a..5b0297e 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -1,10 +1,33 @@
#include "builtin.h"
#include "perf.h"
#include "util/parse-options.h"
+#include "util/session.h"
+#include "util/cache.h"
+#include "util/trace-event.h"
+#include "util/evlist.h"
+#include "util/evsel.h"
+#include <inttypes.h>
+
+/* format string of specifying min width to print address */
+#if __WORDSIZE == 32
+#define FMT_ADDR_WIDTH "10" /* length of "0x" + 32bit address */
+#else
+#define FMT_ADDR_WIDTH "18" /* length of "0x" + 64bit address */
+#endif
+/* format string to print address */
+#define FMT_ADDR "%#0" FMT_ADDR_WIDTH "lx"
+
+/* default input file name to analyze */
+static const char *input_name = "perf.data";
+
+/* output tsv mode */
+static bool output_tsv;
+#define output_item_addr(addr) printf(output_tsv ? FMT_ADDR "\t" : \
+ FMT_ADDR " ", addr)
static const char * const branch_usage[] = {
- "perf branch record <command>",
- NULL,
+ "perf branch [<options>] {record|trace}",
+ NULL
};
/* arguments to call 'perf record' */
@@ -16,11 +39,72 @@ static const char * const record_args[] = {
"-d",
};
-/* dummy struct option to call parse_options() */
static const struct option branch_options[] = {
+ OPT_STRING('i', "input", &input_name, "file", "input file name"),
+ OPT_BOOLEAN('t', "tsv", &output_tsv, "output tsv format"),
OPT_END()
};
+static bool is_bts_event(struct perf_evsel *evsel)
+{
+ struct perf_event_attr *attr = &evsel->attr;
+
+ return (attr->config & PERF_COUNT_HW_BRANCH_INSTRUCTIONS &&
+ attr->type == PERF_TYPE_HARDWARE &&
+ attr->sample_period == 1);
+}
+
+static bool is_bts_sample(struct perf_sample *sample,
+ struct perf_session *session)
+{
+ struct perf_evsel *evsel;
+
+ evsel = perf_evlist__id2evsel(session->evlist, sample->id);
+ if (!evsel)
+ return false;
+
+ return is_bts_event(evsel);
+}
+
+static int process_sample_event(union perf_event *event __unused,
+ struct perf_sample *sample, struct perf_evsel *evsel __unused,
+ struct perf_session *session)
+{
+ if (!is_bts_sample(sample, session))
+ return 0;
+
+ /* sample->ip is 'from address', sample->addr is 'to address' */
+ output_item_addr(sample->ip);
+ if (!output_tsv)
+ printf("=> ");
+ output_item_addr(sample->addr);
+ printf("\n");
+
+ return 0;
+}
+
+static struct perf_event_ops event_ops = {
+ .sample = process_sample_event,
+ .ordered_samples = false,
+};
+
+static int __cmd_trace(void)
+{
+ struct perf_session *session;
+
+ session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops);
+ if (!session) {
+ fprintf(stderr, "failed to create perf_session.\n");
+ return EXIT_FAILURE;
+ }
+
+ setup_pager();
+ perf_session__process_events(session, &event_ops);
+ perf_session__delete(session);
+
+ return EXIT_SUCCESS;
+}
+
static int __cmd_record(int argc, const char **argv)
{
unsigned int rec_argc, i, j;
@@ -55,6 +139,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix __used)
if (!strcmp(argv[0], "record"))
return __cmd_record(argc, argv);
+ else if (!strcmp(argv[0], "trace"))
+ return __cmd_trace();
else
usage_with_options(branch_usage, branch_options);
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 3/7] perf branch trace: print pid and command
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 1/7] perf: new subcommand perf branch record Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 2/7] perf branch: Introduce new sub command 'perf branch trace' Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 4/7] perf branch trace: print file path of the executed elf Akihiro Nagai
` (4 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
Provide the function to print pid and command name to
'perf branch trace'. Users can select items to print with options.
For example,
'perf branch -p trace' prints only pid,
'perf branch -ac trace' prints address and comamnd name.
'perf branch trace' prints only address (default)
This is output sample (perf branch -ac trace):
command address
ls 0xffffffff8146fe0e => 0x0000003806200b20
ls 0xffffffff8146fe0e => 0x0000003806200b20
ls 0x0000003806200b23 => 0x0000003806204910
ls 0xffffffff8146fe0e => 0x0000003806204910
ls 0xffffffff8146fe0e => 0x0000003806204936
ls 0xffffffff8146fe0e => 0x000000380620493d
ls 0x0000003806204981 => 0x00000038062049a3
ls 0x00000038062049a7 => 0x0000003806204988
Pid and command are never changed between branch_to and branch_from.
So perf branch prints them only branch_from field.
Changes in V4
- comm and pid are only printed in branch_from field
- support output tsv mode
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 18 +++-
tools/perf/builtin-branch.c | 138 +++++++++++++++++++++++++++++-
2 files changed, 148 insertions(+), 8 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index 15ee496..f3a4e13 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -3,7 +3,7 @@ perf-branch(1)
NAME
----
-perf-branch - Record and print branch-trace-store log
+perf-branch - Record and analyze branch-trace-store log
SYNOPSIS
--------
@@ -12,7 +12,7 @@ SYNOPSIS
DESCRIPTION
-----------
-This command records and prints a branch-trace-store log.
+This command records and analyzes a branch-trace-store log.
Branch-trace-store is a facility of processors. It can record
addresses of from/to which the execution of a program branches,
at every branch instruction and interrupt.
@@ -20,7 +20,10 @@ at every branch instruction and interrupt.
'perf branch record <command>' records branch-trace-store log while
the specified command is executing. And, save to the file "perf.data".
-'perf branch trace' parses recorded branch-trace-store log and prints it.
+'perf branch trace' analyzes recorded branch-trace-store log and prints it.
+The command can select the item to print. For example,
+ 'perf branch -a trace' : prints only address
+ 'perf branch -acp trace' : prints address, command name and pid
OPTIONS
-------
@@ -30,6 +33,15 @@ OPTIONS
-t::
--tsv::
Output TSV format.
+-a::
+--addr::
+ Print address. (default)
+-c::
+--comm::
+ Print command name.
+-p::
+--pid::
+ Print pid.
SEE ALSO
--------
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index 5b0297e..6e37c775 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -17,6 +17,45 @@
/* format string to print address */
#define FMT_ADDR "%#0" FMT_ADDR_WIDTH "lx"
+/* printable items */
+struct exec_info {
+ u64 addr; /* recorded address by bts */
+ pid_t pid; /* tracee process pid */
+ const char *comm; /* command name */
+};
+
+#define EI_PID_UNSET -1
+
+/* flags which item print */
+#define EI_FLAG_PRINT_ADDR (1 << 0)
+#define EI_FLAG_PRINT_PID (1 << 1)
+#define EI_FLAG_PRINT_COMM (1 << 2)
+
+/*
+ * It's used when no print item specified.
+ * It must be selected from EI_FLAG_REQUIRED.
+ */
+#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
+
+/* the flags must be printed at least. */
+#define EI_FLAG_REQUIRED EI_FLAG_PRINT_ADDR
+
+/*
+ * The items which are not printed in branch_to field.
+ * Currently, Pid and command are never changed between branch_to and
+ * branch_from. So, don't print them in branch_to field.
+ */
+#define EI_MASK_BRANCH_TO (~(EI_FLAG_PRINT_COMM | EI_FLAG_PRINT_PID))
+
+/* print item flags */
+static unsigned long print_flags;
+
+#define is_flags_unset(flags) ((flags) == 0)
+
+/* print it when we cannnot analyze and get the information */
+#define EI_UNKNOWN_TEXT "(unknown)"
+#define EI_UNKNOWN_TEXT_LEN (sizeof(EI_UNKNOWN_TEXT))
+
/* default input file name to analyze */
static const char *input_name = "perf.data";
@@ -24,6 +63,7 @@ static const char *input_name = "perf.data";
static bool output_tsv;
#define output_item_addr(addr) printf(output_tsv ? FMT_ADDR "\t" : \
FMT_ADDR " ", addr)
+#define output_item_str(fmt, str) printf(output_tsv ? "%s\t" : fmt, str)
static const char * const branch_usage[] = {
"perf branch [<options>] {record|trace}",
@@ -39,9 +79,26 @@ static const char * const record_args[] = {
"-d",
};
+/* set print flags call from parse_options() */
+static int set_print_flags(const struct option *opt, const char *str __unused,
+ int unset __unused)
+{
+ print_flags |= (unsigned long)opt->defval;
+ return 0;
+}
+
static const struct option branch_options[] = {
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_BOOLEAN('t', "tsv", &output_tsv, "output tsv format"),
+ OPT_CALLBACK_DEFAULT_NOOPT('a', "addr", NULL, NULL,
+ "print address (default)", set_print_flags,
+ (void *)EI_FLAG_PRINT_ADDR),
+ OPT_CALLBACK_DEFAULT_NOOPT('p', "pid", NULL, NULL,
+ "print pid", set_print_flags,
+ (void *)EI_FLAG_PRINT_PID),
+ OPT_CALLBACK_DEFAULT_NOOPT('c', "comm", NULL, NULL,
+ "print command name", set_print_flags,
+ (void *)EI_FLAG_PRINT_COMM),
OPT_END()
};
@@ -66,25 +123,91 @@ static bool is_bts_sample(struct perf_sample *sample,
return is_bts_event(evsel);
}
+static void init_exec_info(struct exec_info *ei)
+{
+ memset(ei, 0, sizeof(*ei));
+ ei->pid = EI_PID_UNSET;
+}
+
+/* collect printable items to struct exec_info */
+static void fill_exec_info(struct exec_info *ei,
+ struct perf_session *session, union perf_event *event, u64 addr)
+{
+ struct thread *thread;
+
+ ei->addr = addr;
+ ei->pid = event->ip.pid;
+
+ thread = perf_session__findnew(session, event->ip.pid);
+ if (!thread)
+ return;
+ ei->comm = thread->comm;
+}
+
+static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
+{
+ char pid[16];
+ const char *comm;
+
+ if (ei_print_flags & EI_FLAG_PRINT_PID) {
+ if (ei->pid == EI_PID_UNSET)
+ strncpy(pid, EI_UNKNOWN_TEXT, EI_UNKNOWN_TEXT_LEN);
+ else
+ snprintf(pid, 16, "%d", ei->pid);
+ output_item_str("%5s ", pid);
+ }
+ if (ei_print_flags & EI_FLAG_PRINT_COMM) {
+ comm = ei->comm ? : EI_UNKNOWN_TEXT;
+ output_item_str("%-12s ", comm);
+ }
+ if (ei_print_flags & EI_FLAG_PRINT_ADDR)
+ output_item_addr(ei->addr);
+}
+
+static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
+{
+ __print_exec_info(ei_from, print_flags);
+ if (!output_tsv)
+ printf("=> ");
+ __print_exec_info(ei_to, print_flags & EI_MASK_BRANCH_TO);
+ printf("\n");
+}
+
+static void print_exec_info_header(void)
+{
+ if (print_flags & EI_FLAG_PRINT_PID)
+ output_item_str("%5s ", "pid");
+ if (print_flags & EI_FLAG_PRINT_COMM)
+ output_item_str("%-12s ", "command");
+ if (print_flags & EI_FLAG_PRINT_ADDR)
+ output_item_str("%-" FMT_ADDR_WIDTH "s ", "address");
+ printf("\n");
+}
+
static int process_sample_event(union perf_event *event __unused,
struct perf_sample *sample, struct perf_evsel *evsel __unused,
struct perf_session *session)
{
+ struct exec_info ei_from, ei_to;
+
if (!is_bts_sample(sample, session))
return 0;
+ init_exec_info(&ei_from);
+ init_exec_info(&ei_to);
+
/* sample->ip is 'from address', sample->addr is 'to address' */
- output_item_addr(sample->ip);
- if (!output_tsv)
- printf("=> ");
- output_item_addr(sample->addr);
- printf("\n");
+ fill_exec_info(&ei_from, session, event, sample->ip);
+ fill_exec_info(&ei_to, session, event, sample->addr);
+
+ print_exec_info(&ei_from, &ei_to);
return 0;
}
static struct perf_event_ops event_ops = {
.sample = process_sample_event,
+ .comm = perf_event__process_comm,
.ordered_samples = false,
};
@@ -98,7 +221,12 @@ static int __cmd_trace(void)
return EXIT_FAILURE;
}
+ /* To avoid meaningless output, we add default printable item. */
+ if (is_flags_unset(print_flags & EI_FLAG_REQUIRED))
+ print_flags |= EI_FLAG_PRINT_DEFAULT;
+
setup_pager();
+ print_exec_info_header();
perf_session__process_events(session, &event_ops);
perf_session__delete(session);
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 4/7] perf branch trace: print file path of the executed elf
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
` (2 preceding siblings ...)
2011-05-26 5:03 ` [PATCH -tip v4 3/7] perf branch trace: print pid and command Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 5/7] perf branch trace: print function+offset Akihiro Nagai
` (3 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
Provide the function to print file path to the executed elf.
Users can enable it with option '-e' or '--elfpath'.
For example,
'perf branch -ae trace'
This command prints address and file path of elf.
And, output is:
address elf_filepath
0xffffffff81458f4e /lib/modules/2.6.39-rc3-tip+/build/vmlinux => 0x0000003806200b20 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.39-rc3-tip+/build/vmlinux => 0x0000003806200b20 /lib64/ld-2.12.90.so
0x0000003806200b23 /lib64/ld-2.12.90.so => 0x0000003806204910 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.39-rc3-tip+/build/vmlinux => 0x0000003806204910 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.39-rc3-tip+/build/vmlinux => 0x0000003806204936 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.39-rc3-tip+/build/vmlinux => 0x000000380620493d /lib64/ld-2.12.90.so
0x0000003806204981 /lib64/ld-2.12.90.so => 0x00000038062049a3 /lib64/ld-2.12.90.so
0x00000038062049a7 /lib64/ld-2.12.90.so => 0x0000003806204988 /lib64/ld-2.12.90.so
...
Changes in V4
- support output tsv mode
Changes in V3:
- Update to latest -tip tree
Changes in V2:
- add comment
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 3 +++
tools/perf/builtin-branch.c | 32 ++++++++++++++++++++++++++++++
2 files changed, 35 insertions(+), 0 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index f3a4e13..b3e5cf33 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -42,6 +42,9 @@ OPTIONS
-p::
--pid::
Print pid.
+-e::
+--elfpath::
+ Print file path of executed elf.
SEE ALSO
--------
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index 6e37c775..0b96461 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -22,6 +22,7 @@ struct exec_info {
u64 addr; /* recorded address by bts */
pid_t pid; /* tracee process pid */
const char *comm; /* command name */
+ const char *elfpath; /* file path to elf */
};
#define EI_PID_UNSET -1
@@ -30,6 +31,7 @@ struct exec_info {
#define EI_FLAG_PRINT_ADDR (1 << 0)
#define EI_FLAG_PRINT_PID (1 << 1)
#define EI_FLAG_PRINT_COMM (1 << 2)
+#define EI_FLAG_PRINT_ELFPATH (1 << 3)
/*
* It's used when no print item specified.
@@ -99,6 +101,9 @@ static const struct option branch_options[] = {
OPT_CALLBACK_DEFAULT_NOOPT('c', "comm", NULL, NULL,
"print command name", set_print_flags,
(void *)EI_FLAG_PRINT_COMM),
+ OPT_CALLBACK_DEFAULT_NOOPT('e', "elfpath", NULL, NULL,
+ "print file path to elf", set_print_flags,
+ (void *)EI_FLAG_PRINT_ELFPATH),
OPT_END()
};
@@ -134,6 +139,7 @@ static void fill_exec_info(struct exec_info *ei,
struct perf_session *session, union perf_event *event, u64 addr)
{
struct thread *thread;
+ struct addr_location al;
ei->addr = addr;
ei->pid = event->ip.pid;
@@ -142,12 +148,26 @@ static void fill_exec_info(struct exec_info *ei,
if (!thread)
return;
ei->comm = thread->comm;
+
+ /* get file path to elf */
+ memset(&al, 0, sizeof(al));
+ thread__find_addr_map(thread, session, PERF_RECORD_MISC_USER,
+ MAP__FUNCTION, event->ip.pid, addr, &al);
+ if (!al.map)
+ thread__find_addr_map(thread, session, PERF_RECORD_MISC_KERNEL,
+ MAP__FUNCTION, event->ip.pid, addr, &al);
+ if (!al.map)
+ return;
+ /* resolve vmlinux path */
+ map__load(al.map, NULL);
+ ei->elfpath = al.map->dso->long_name;
}
static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
{
char pid[16];
const char *comm;
+ const char *elfpath;
if (ei_print_flags & EI_FLAG_PRINT_PID) {
if (ei->pid == EI_PID_UNSET)
@@ -162,6 +182,10 @@ static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
}
if (ei_print_flags & EI_FLAG_PRINT_ADDR)
output_item_addr(ei->addr);
+ if (ei_print_flags & EI_FLAG_PRINT_ELFPATH) {
+ elfpath = ei->elfpath ? : EI_UNKNOWN_TEXT;
+ output_item_str("%-32s ", elfpath);
+ }
}
static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
@@ -181,6 +205,8 @@ static void print_exec_info_header(void)
output_item_str("%-12s ", "command");
if (print_flags & EI_FLAG_PRINT_ADDR)
output_item_str("%-" FMT_ADDR_WIDTH "s ", "address");
+ if (print_flags & EI_FLAG_PRINT_ELFPATH)
+ output_item_str("%-32s ", "elf_filepath");
printf("\n");
}
@@ -208,6 +234,7 @@ static int process_sample_event(union perf_event *event __unused,
static struct perf_event_ops event_ops = {
.sample = process_sample_event,
.comm = perf_event__process_comm,
+ .mmap = perf_event__process_mmap,
.ordered_samples = false,
};
@@ -225,6 +252,11 @@ static int __cmd_trace(void)
if (is_flags_unset(print_flags & EI_FLAG_REQUIRED))
print_flags |= EI_FLAG_PRINT_DEFAULT;
+ /* setup kernel maps to resolve vmlinux file path */
+ perf_session__create_kernel_maps(session);
+ if (symbol__init() < 0)
+ fprintf(stderr, "failed to initialize symbol.\n");
+
setup_pager();
print_exec_info_header();
perf_session__process_events(session, &event_ops);
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 5/7] perf branch trace: print function+offset
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
` (3 preceding siblings ...)
2011-05-26 5:03 ` [PATCH -tip v4 4/7] perf branch trace: print file path of the executed elf Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 6/7] perf branch trace: add print all option Akihiro Nagai
` (2 subsequent siblings)
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
Provide the function to print function+offset.
And, set it as the default behavior of 'perf branch trace'.
To use this function, users can also specify the option '-s' or '--symbol'.
Example: 'perf branch -as trace'
This command prints address and function+offset.
Output sample:
address function+offset
0xffffffff8146fe0e irq_return+0x0 => 0x00007fd4038e3b20 _start+0x0
...
0x000000380661ee79 __libc_start_main+0xf9 => 0x00000000004035c3 main+0x0
0xffffffff8146ef4e irq_return+0x0 => 0x00000000004035c3 main+0x0
0x00000000004035e8 main+0x25 => 0x000000000040bca0 set_program_name+0x0
0xffffffff8146ef4e irq_return+0x0 => 0x000000000040bca0 set_program_name+0x0
0x000000000040bcae set_program_name+0xe => 0x00000000004023d0 strrchr@plt+0x0
0x00000000004023d0 strrchr@plt+0x0 => 0x00000000004023d6 strrchr@plt+0x6
...
0x0000000000403e0c main+0x849 => 0x00000000004021f0 exit@plt+0x0
0x00000000004021f0 exit@plt+0x0 => 0x00000000004021f6 exit@plt+0x6
0x00000000004021fb exit@plt+0xb => 0x00000000004020d0 _init+0x18
0x00000000004020d6 _init+0x1e => 0x00000038062149d0 _dl_runtime_resolve+0x0
...
Changes in V4:
- support output tsv mode
Changes in V3:
- rename to 'perf branch'
- fix getting elf_path bug
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 5 +++
tools/perf/builtin-branch.c | 45 +++++++++++++++++++++++++++---
2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index b3e5cf33..9b7b1e1 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -35,7 +35,7 @@ OPTIONS
Output TSV format.
-a::
--addr::
- Print address. (default)
+ Print address.
-c::
--comm::
Print command name.
@@ -45,6 +45,9 @@ OPTIONS
-e::
--elfpath::
Print file path of executed elf.
+-s::
+--symbol::
+ Print function name and offset. (default)
SEE ALSO
--------
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index 0b96461..708b056 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -23,6 +23,8 @@ struct exec_info {
pid_t pid; /* tracee process pid */
const char *comm; /* command name */
const char *elfpath; /* file path to elf */
+ const char *function; /* function name */
+ u64 offset; /* offset from top of the function */
};
#define EI_PID_UNSET -1
@@ -32,15 +34,16 @@ struct exec_info {
#define EI_FLAG_PRINT_PID (1 << 1)
#define EI_FLAG_PRINT_COMM (1 << 2)
#define EI_FLAG_PRINT_ELFPATH (1 << 3)
+#define EI_FLAG_PRINT_SYMBOL (1 << 4)
/*
* It's used when no print item specified.
* It must be selected from EI_FLAG_REQUIRED.
*/
-#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
+#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_SYMBOL
/* the flags must be printed at least. */
-#define EI_FLAG_REQUIRED EI_FLAG_PRINT_ADDR
+#define EI_FLAG_REQUIRED (EI_FLAG_PRINT_ADDR | EI_FLAG_PRINT_SYMBOL)
/*
* The items which are not printed in branch_to field.
@@ -58,6 +61,9 @@ static unsigned long print_flags;
#define EI_UNKNOWN_TEXT "(unknown)"
#define EI_UNKNOWN_TEXT_LEN (sizeof(EI_UNKNOWN_TEXT))
+/* 'function+offset' lengh = function + '+' + %#18lx + '\0' */
+#define symbol_buf_size(func_name) (strlen(func_name) + 1 + 18 + 1)
+
/* default input file name to analyze */
static const char *input_name = "perf.data";
@@ -93,7 +99,7 @@ static const struct option branch_options[] = {
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_BOOLEAN('t', "tsv", &output_tsv, "output tsv format"),
OPT_CALLBACK_DEFAULT_NOOPT('a', "addr", NULL, NULL,
- "print address (default)", set_print_flags,
+ "print address", set_print_flags,
(void *)EI_FLAG_PRINT_ADDR),
OPT_CALLBACK_DEFAULT_NOOPT('p', "pid", NULL, NULL,
"print pid", set_print_flags,
@@ -104,6 +110,10 @@ static const struct option branch_options[] = {
OPT_CALLBACK_DEFAULT_NOOPT('e', "elfpath", NULL, NULL,
"print file path to elf", set_print_flags,
(void *)EI_FLAG_PRINT_ELFPATH),
+ OPT_CALLBACK_DEFAULT_NOOPT('s', "symbol", NULL, NULL,
+ "print function+offset (default)",
+ set_print_flags,
+ (void *)EI_FLAG_PRINT_SYMBOL),
OPT_END()
};
@@ -149,7 +159,7 @@ static void fill_exec_info(struct exec_info *ei,
return;
ei->comm = thread->comm;
- /* get file path to elf */
+ /* get file path to elf, and symbol information */
memset(&al, 0, sizeof(al));
thread__find_addr_map(thread, session, PERF_RECORD_MISC_USER,
MAP__FUNCTION, event->ip.pid, addr, &al);
@@ -161,6 +171,13 @@ static void fill_exec_info(struct exec_info *ei,
/* resolve vmlinux path */
map__load(al.map, NULL);
ei->elfpath = al.map->dso->long_name;
+
+ al.addr = al.map->map_ip(al.map, addr);
+ al.sym = map__find_symbol(al.map, al.addr, NULL);
+ if (!al.sym)
+ return;
+ ei->function = al.sym->name;
+ ei->offset = al.addr - al.sym->start;
}
static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
@@ -168,6 +185,8 @@ static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
char pid[16];
const char *comm;
const char *elfpath;
+ char *symbol;
+ int symbol_len;
if (ei_print_flags & EI_FLAG_PRINT_PID) {
if (ei->pid == EI_PID_UNSET)
@@ -182,6 +201,22 @@ static void __print_exec_info(struct exec_info *ei, int ei_print_flags)
}
if (ei_print_flags & EI_FLAG_PRINT_ADDR)
output_item_addr(ei->addr);
+ if (ei_print_flags & EI_FLAG_PRINT_SYMBOL) {
+ if (!ei->function) {
+ /* when function is unknown, offset must be unknown */
+ printf("%-32s ", EI_UNKNOWN_TEXT);
+ goto print_elfpath;
+ }
+
+ symbol_len = symbol_buf_size(ei->function);
+ symbol = malloc(symbol_len);
+ snprintf(symbol, symbol_len, "%s+0x%lx",
+ ei->function, ei->offset);
+ output_item_str("%-32s ", symbol);
+ free(symbol);
+ }
+
+print_elfpath:
if (ei_print_flags & EI_FLAG_PRINT_ELFPATH) {
elfpath = ei->elfpath ? : EI_UNKNOWN_TEXT;
output_item_str("%-32s ", elfpath);
@@ -205,6 +240,8 @@ static void print_exec_info_header(void)
output_item_str("%-12s ", "command");
if (print_flags & EI_FLAG_PRINT_ADDR)
output_item_str("%-" FMT_ADDR_WIDTH "s ", "address");
+ if (print_flags & EI_FLAG_PRINT_SYMBOL)
+ output_item_str("%-32s ", "function+offset");
if (print_flags & EI_FLAG_PRINT_ELFPATH)
output_item_str("%-32s ", "elf_filepath");
printf("\n");
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 6/7] perf branch trace: add print all option
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
` (4 preceding siblings ...)
2011-05-26 5:03 ` [PATCH -tip v4 5/7] perf branch trace: print function+offset Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 7/7] perf branch trace: add kernel filter Akihiro Nagai
2011-05-26 13:28 ` [PATCH -tip v4 0/7] perf: Introduce branch sub commands Frederic Weisbecker
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
For ease of use, add option printing all information '-A' or '--all'.
This option can print following information.
- pid
- command name
- address
- function+offset
- elf file path
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 3 +++
tools/perf/builtin-branch.c | 6 ++++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index 9b7b1e1..a034f12 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -48,6 +48,9 @@ OPTIONS
-s::
--symbol::
Print function name and offset. (default)
+-A::
+--all::
+ Print all information.
SEE ALSO
--------
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index 708b056..51cdcd4 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -36,6 +36,9 @@ struct exec_info {
#define EI_FLAG_PRINT_ELFPATH (1 << 3)
#define EI_FLAG_PRINT_SYMBOL (1 << 4)
+/* all print flags are enabled */
+#define EI_FLAG_PRINT_ALL -1UL
+
/*
* It's used when no print item specified.
* It must be selected from EI_FLAG_REQUIRED.
@@ -114,6 +117,9 @@ static const struct option branch_options[] = {
"print function+offset (default)",
set_print_flags,
(void *)EI_FLAG_PRINT_SYMBOL),
+ OPT_CALLBACK_DEFAULT_NOOPT('A', "all", NULL, NULL,
+ "print all items", set_print_flags,
+ (void *)EI_FLAG_PRINT_ALL),
OPT_END()
};
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH -tip v4 7/7] perf branch trace: add kernel filter
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
` (5 preceding siblings ...)
2011-05-26 5:03 ` [PATCH -tip v4 6/7] perf branch trace: add print all option Akihiro Nagai
@ 2011-05-26 5:03 ` Akihiro Nagai
2011-05-26 13:28 ` [PATCH -tip v4 0/7] perf: Introduce branch sub commands Frederic Weisbecker
7 siblings, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-26 5:03 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
Frederic Weisbecker
Cc: linux-kernel, Masami Hiramatsu, pp-manager, Akihiro Nagai,
Peter Zijlstra, Frederic Weisbecker, Paul Mackerras, Ingo Molnar,
Arnaldo Carvalho de Melo
This patch introduces filter to eliminate kernel functions from
'perf branch trace' output. 'perf branch record' records
'kernel to user' logs, but it doesn't record 'user to kernel' logs.
So users may be surprised at kernel functions which are appeared suddenly.
If you want to see all recorded BTS logs, you can disable this filter
with the option '--no-kernel-filter'.
Usage:
# perf branch --no-kernel-filter trace
Signed-off-by: Akihiro Nagai <akihiro.nagai.hw@hitachi.com>
Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
---
tools/perf/Documentation/perf-branch.txt | 5 +++++
tools/perf/builtin-branch.c | 12 +++++++++++-
2 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index a034f12..9635f22 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -51,6 +51,11 @@ OPTIONS
-A::
--all::
Print all information.
+--no-kernel-filter::
+ Disable kernel filter and print all recorded branch-trace-store logs.
+ The logs recorded by 'perf branch record' include 'kernel to user'
+ logs because of processors' specification. In the default behavior,
+ 'perf branch trace' doesn't show it. This option disables this filter.
SEE ALSO
--------
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index 51cdcd4..8b49c30 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -25,6 +25,7 @@ struct exec_info {
const char *elfpath; /* file path to elf */
const char *function; /* function name */
u64 offset; /* offset from top of the function */
+ enum dso_kernel_type kernel; /* to distingish kernel or user*/
};
#define EI_PID_UNSET -1
@@ -60,6 +61,9 @@ static unsigned long print_flags;
#define is_flags_unset(flags) ((flags) == 0)
+/* kernel filter is disabled or not */
+static bool no_kernel_filter;
+
/* print it when we cannnot analyze and get the information */
#define EI_UNKNOWN_TEXT "(unknown)"
#define EI_UNKNOWN_TEXT_LEN (sizeof(EI_UNKNOWN_TEXT))
@@ -120,6 +124,8 @@ static const struct option branch_options[] = {
OPT_CALLBACK_DEFAULT_NOOPT('A', "all", NULL, NULL,
"print all items", set_print_flags,
(void *)EI_FLAG_PRINT_ALL),
+ OPT_BOOLEAN('\0', "no-kernel-filter", &no_kernel_filter,
+ "disable kernel filter"),
OPT_END()
};
@@ -148,6 +154,7 @@ static void init_exec_info(struct exec_info *ei)
{
memset(ei, 0, sizeof(*ei));
ei->pid = EI_PID_UNSET;
+ ei->kernel = DSO_TYPE_USER;
}
/* collect printable items to struct exec_info */
@@ -177,6 +184,7 @@ static void fill_exec_info(struct exec_info *ei,
/* resolve vmlinux path */
map__load(al.map, NULL);
ei->elfpath = al.map->dso->long_name;
+ ei->kernel = al.map->dso->kernel;
al.addr = al.map->map_ip(al.map, addr);
al.sym = map__find_symbol(al.map, al.addr, NULL);
@@ -269,7 +277,9 @@ static int process_sample_event(union perf_event *event __unused,
fill_exec_info(&ei_from, session, event, sample->ip);
fill_exec_info(&ei_to, session, event, sample->addr);
- print_exec_info(&ei_from, &ei_to);
+ if (no_kernel_filter || (ei_from.kernel == DSO_TYPE_USER &&
+ ei_to.kernel == DSO_TYPE_USER))
+ print_exec_info(&ei_from, &ei_to);
return 0;
}
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
` (6 preceding siblings ...)
2011-05-26 5:03 ` [PATCH -tip v4 7/7] perf branch trace: add kernel filter Akihiro Nagai
@ 2011-05-26 13:28 ` Frederic Weisbecker
2011-05-26 16:24 ` David Ahern
2011-06-10 7:17 ` Akihiro Nagai
7 siblings, 2 replies; 16+ messages in thread
From: Frederic Weisbecker @ 2011-05-26 13:28 UTC (permalink / raw)
To: Akihiro Nagai
Cc: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
linux-kernel, Masami Hiramatsu, pp-manager, David Ahern
(Adding David Ahern in Cc)
Ok that's all good except this needs to use the "perf script" centralized
dump.
Currently running "perf script" without an actual script dumps
the events by default, whatever kind of event they are: hardware,
software, tracepoints, ...
So we want the branch output to be supported there, so we can reuse
some code and interface.
For example, "perf script -f branch:comm,tid,sym" would print the
comm, tid and the sym for to and from addresses.
That's better than creating a new set of options in a new command
that people need to relearn while everybody could simply get
familiarized with common perf script options.
Of course we can still have a "perf branch" command, which could
be a tiny shortcut that maps to perf record and perf script.
Like:
perf branch record
perf branch [trace] -f tid,sym,comm
Would map to:
perf record branch:u
perf script -f branch:tid,sym,comm
And may be if one day we can do something more tricky than a
linear output for branches (like source code coloring/browsing),
then it may be implemented inside perf branch and not rely on
another subcommand. Until then we are only dealing with raw linear
dump, and that's a core job for perf script where we want to
centralize that kind of facility.
Thanks.
On Thu, May 26, 2011 at 02:02:46PM +0900, Akihiro Nagai wrote:
> Hi,
>
> This patch series provides the commands 'perf branch record' and
> 'perf branch trace' version 4. These commands record and analyze
> a BTS (Branch Trace Store) log. And, they provide the interface
> to use BTS log for application developers.
>
> BTS is a facility of Intel x86 processors, which records the address of
> 'branch to/from' on every branch/jump instruction and interrupt.
> This facility is very useful for developers to test their software,
> for example, coverage test, execution path analysis, dynamic step count ...etc.
> These test tools have a big advantage, which user doesn't have to modify target
> executable binaries, because the BTS is a hardware feauture.
>
> But, there are few applications using BTS. Reasons I guess are ...
> - Few people know what BTS is.
> - Few people know how to use BTS on Linux box.
> - It's hard to analyze the BTS log because it includes just a series of
> addresses.
>
> So, I want to provide a user-friendly interface to BTS for application
> developers.
>
>
> About new sub commands
> ========================
> 'perf branch record' provides an easy way to record BTS log.
> Usage is 'perf branch record <command>'. This command is just an alias to
> 'perf record -e branches:u -c 1 -d <command>'. But, new one is more simple
> and more intuitive.
>
> 'perf branch trace' can parse and analyze recorded BTS log and print various
> information of execution path. This command can show address, pid, command name,
> function+offset, file path of elf.
> You can choose the printed information with option.
>
> Example: 'perf branch trace'
>
> function+offset
> _start+0x3 => _dl_start+0x0
> _dl_start+0x71 => _dl_start+0x93
> _dl_start+0x97 => _dl_start+0x78
> _dl_start+0x97 => _dl_start+0x78
> _dl_start+0xa3 => _dl_start+0x3c0
> _dl_start+0x3c8 => _dl_start+0x3e8
> ...
>
> This is the default behavior of 'perf branch trace'. It prints function+offset.
>
> Example2: 'perf branch -cas trace'
> command address function+offset
> ls 0x0000003e9b000b23 _start+0x3 => 0x0000003e9b004540 _dl_start+0x0
> ls 0x0000003e9b0045b1 _dl_start+0x71 => 0x0000003e9b0045d3 _dl_start+0x93
> ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
> ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
> ls 0x0000003e9b0045e3 _dl_start+0xa3 => 0x0000003e9b004900 _dl_start+0x3c0
> ls 0x0000003e9b004908 _dl_start+0x3c8 => 0x0000003e9b004928 _dl_start+0x3e8
> ...
>
> In the future, I'd like to make this more informative. For example
> - Show source file path
> - Show line number
> - Show inlined function name
> - Draw call graph
> - Browse source code and coloring
> - Make BTS record fast
> and more!
>
> Changes in V4:
> - Add kenel filter
> - Print PID and command only once in a line
> - Add output TSV mode
>
> Changes in V3:
> - Update to the latest -tip tree
> - Rename to 'perf branch'
> - Process only BTS records
> - Fix bug of getting elf_filepath
> - Fix return value of __cmd_trace
>
> Changes in V2:
> - Update to the latest -tip tree
> - Add bts explanation to the subcommand list
> - Remove the patch already merged (add OPT_CALLBACK_DEFAULT_NOOPT)
> - Add comments
> - Add new function to the todo list
>
> Thanks,
>
> ---
>
> Akihiro Nagai (7):
> perf branch trace: add kernel filter
> perf branch trace: add print all option
> perf branch trace: print function+offset
> perf branch trace: print file path of the executed elf
> perf branch trace: print pid and command
> perf branch: Introduce new sub command 'perf branch trace'
> perf: new subcommand perf branch record
>
>
> tools/perf/Documentation/perf-branch.txt | 62 +++++
> tools/perf/Makefile | 1
> tools/perf/builtin-branch.c | 361 ++++++++++++++++++++++++++++++
> tools/perf/builtin.h | 1
> tools/perf/command-list.txt | 1
> tools/perf/perf.c | 1
> 6 files changed, 427 insertions(+), 0 deletions(-)
> create mode 100644 tools/perf/Documentation/perf-branch.txt
> create mode 100644 tools/perf/builtin-branch.c
>
> --
> Akihiro Nagai (akihiro.nagai.hw@hitachi.com)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-26 13:28 ` [PATCH -tip v4 0/7] perf: Introduce branch sub commands Frederic Weisbecker
@ 2011-05-26 16:24 ` David Ahern
2011-05-30 13:31 ` Akihiro Nagai
2011-06-10 7:17 ` Akihiro Nagai
1 sibling, 1 reply; 16+ messages in thread
From: David Ahern @ 2011-05-26 16:24 UTC (permalink / raw)
To: Frederic Weisbecker, Akihiro Nagai
Cc: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
linux-kernel, Masami Hiramatsu, pp-manager
[-- Attachment #1: Type: text/plain, Size: 6188 bytes --]
On 05/26/2011 07:28 AM, Frederic Weisbecker wrote:
> (Adding David Ahern in Cc)
>
> Ok that's all good except this needs to use the "perf script" centralized
> dump.
>
> Currently running "perf script" without an actual script dumps
> the events by default, whatever kind of event they are: hardware,
> software, tracepoints, ...
> So we want the branch output to be supported there, so we can reuse
> some code and interface.
>
> For example, "perf script -f branch:comm,tid,sym" would print the
> comm, tid and the sym for to and from addresses.
>
> That's better than creating a new set of options in a new command
> that people need to relearn while everybody could simply get
> familiarized with common perf script options.
>
> Of course we can still have a "perf branch" command, which could
> be a tiny shortcut that maps to perf record and perf script.
>
> Like:
>
> perf branch record
> perf branch [trace] -f tid,sym,comm
>
> Would map to:
>
> perf record branch:u
> perf script -f branch:tid,sym,comm
>
> And may be if one day we can do something more tricky than a
> linear output for branches (like source code coloring/browsing),
> then it may be implemented inside perf branch and not rely on
> another subcommand. Until then we are only dealing with raw linear
> dump, and that's a core job for perf script where we want to
> centralize that kind of facility.
I mentioned that when v3 was posted.
The sample address can be converted to symbols and the output can be
added to perf-script rather easily. Attached is an example. I was going
to submit it back in April and got distracted. I'll rebase, move the
addr->sym conversion to a function and submit later today.
David
>
> Thanks.
>
> On Thu, May 26, 2011 at 02:02:46PM +0900, Akihiro Nagai wrote:
>> Hi,
>>
>> This patch series provides the commands 'perf branch record' and
>> 'perf branch trace' version 4. These commands record and analyze
>> a BTS (Branch Trace Store) log. And, they provide the interface
>> to use BTS log for application developers.
>>
>> BTS is a facility of Intel x86 processors, which records the address of
>> 'branch to/from' on every branch/jump instruction and interrupt.
>> This facility is very useful for developers to test their software,
>> for example, coverage test, execution path analysis, dynamic step count ...etc.
>> These test tools have a big advantage, which user doesn't have to modify target
>> executable binaries, because the BTS is a hardware feauture.
>>
>> But, there are few applications using BTS. Reasons I guess are ...
>> - Few people know what BTS is.
>> - Few people know how to use BTS on Linux box.
>> - It's hard to analyze the BTS log because it includes just a series of
>> addresses.
>>
>> So, I want to provide a user-friendly interface to BTS for application
>> developers.
>>
>>
>> About new sub commands
>> ========================
>> 'perf branch record' provides an easy way to record BTS log.
>> Usage is 'perf branch record <command>'. This command is just an alias to
>> 'perf record -e branches:u -c 1 -d <command>'. But, new one is more simple
>> and more intuitive.
>>
>> 'perf branch trace' can parse and analyze recorded BTS log and print various
>> information of execution path. This command can show address, pid, command name,
>> function+offset, file path of elf.
>> You can choose the printed information with option.
>>
>> Example: 'perf branch trace'
>>
>> function+offset
>> _start+0x3 => _dl_start+0x0
>> _dl_start+0x71 => _dl_start+0x93
>> _dl_start+0x97 => _dl_start+0x78
>> _dl_start+0x97 => _dl_start+0x78
>> _dl_start+0xa3 => _dl_start+0x3c0
>> _dl_start+0x3c8 => _dl_start+0x3e8
>> ...
>>
>> This is the default behavior of 'perf branch trace'. It prints function+offset.
>>
>> Example2: 'perf branch -cas trace'
>> command address function+offset
>> ls 0x0000003e9b000b23 _start+0x3 => 0x0000003e9b004540 _dl_start+0x0
>> ls 0x0000003e9b0045b1 _dl_start+0x71 => 0x0000003e9b0045d3 _dl_start+0x93
>> ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
>> ls 0x0000003e9b0045d7 _dl_start+0x97 => 0x0000003e9b0045b8 _dl_start+0x78
>> ls 0x0000003e9b0045e3 _dl_start+0xa3 => 0x0000003e9b004900 _dl_start+0x3c0
>> ls 0x0000003e9b004908 _dl_start+0x3c8 => 0x0000003e9b004928 _dl_start+0x3e8
>> ...
>>
>> In the future, I'd like to make this more informative. For example
>> - Show source file path
>> - Show line number
>> - Show inlined function name
>> - Draw call graph
>> - Browse source code and coloring
>> - Make BTS record fast
>> and more!
>>
>> Changes in V4:
>> - Add kenel filter
>> - Print PID and command only once in a line
>> - Add output TSV mode
>>
>> Changes in V3:
>> - Update to the latest -tip tree
>> - Rename to 'perf branch'
>> - Process only BTS records
>> - Fix bug of getting elf_filepath
>> - Fix return value of __cmd_trace
>>
>> Changes in V2:
>> - Update to the latest -tip tree
>> - Add bts explanation to the subcommand list
>> - Remove the patch already merged (add OPT_CALLBACK_DEFAULT_NOOPT)
>> - Add comments
>> - Add new function to the todo list
>>
>> Thanks,
>>
>> ---
>>
>> Akihiro Nagai (7):
>> perf branch trace: add kernel filter
>> perf branch trace: add print all option
>> perf branch trace: print function+offset
>> perf branch trace: print file path of the executed elf
>> perf branch trace: print pid and command
>> perf branch: Introduce new sub command 'perf branch trace'
>> perf: new subcommand perf branch record
>>
>>
>> tools/perf/Documentation/perf-branch.txt | 62 +++++
>> tools/perf/Makefile | 1
>> tools/perf/builtin-branch.c | 361 ++++++++++++++++++++++++++++++
>> tools/perf/builtin.h | 1
>> tools/perf/command-list.txt | 1
>> tools/perf/perf.c | 1
>> 6 files changed, 427 insertions(+), 0 deletions(-)
>> create mode 100644 tools/perf/Documentation/perf-branch.txt
>> create mode 100644 tools/perf/builtin-branch.c
>>
>> --
>> Akihiro Nagai (akihiro.nagai.hw@hitachi.com)
[-- Attachment #2: perf-sample-addr.patch --]
[-- Type: text/plain, Size: 3024 bytes --]
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 6debb9c..55f9967 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -32,6 +32,7 @@ enum perf_output_field {
PERF_OUTPUT_EVNAME = 1U << 5,
PERF_OUTPUT_TRACE = 1U << 6,
PERF_OUTPUT_SYM = 1U << 7,
+ PERF_OUTPUT_ADDR = 1U << 8,
};
struct output_option {
@@ -46,6 +47,7 @@ struct output_option {
{.str = "event", .field = PERF_OUTPUT_EVNAME},
{.str = "trace", .field = PERF_OUTPUT_TRACE},
{.str = "sym", .field = PERF_OUTPUT_SYM},
+ {.str = "addr", .field = PERF_OUTPUT_ADDR},
};
/* default set to maintain compatibility with current format */
@@ -71,7 +73,8 @@ static struct {
.fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
- PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
+ PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM |
+ PERF_OUTPUT_ADDR,
.invalid_fields = PERF_OUTPUT_TRACE,
},
@@ -173,6 +176,11 @@ static int perf_evsel__check_attr(struct perf_session *session,
PERF_OUTPUT_CPU))
return -EINVAL;
+ if (PRINT_FIELD(ADDR) &&
+ perf_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
+ PERF_OUTPUT_ADDR))
+ return -EINVAL;
+
return 0;
}
@@ -260,7 +268,7 @@ static void print_sample_start(struct perf_sample *sample,
}
}
-static void process_event(union perf_event *event __unused,
+static void process_event(union perf_event *event,
struct perf_sample *sample,
struct perf_evsel *evsel,
struct perf_session *session,
@@ -273,6 +281,31 @@ static void process_event(union perf_event *event __unused,
print_sample_start(sample, thread, attr);
+ if (PRINT_FIELD(ADDR)) {
+ struct addr_location al;
+ u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ const char *symname, *dsoname;
+
+ thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+ event->ip.pid, sample->addr, &al);
+ if (al.map)
+ al.sym = map__find_symbol(al.map, al.addr, NULL);
+ else
+ al.sym = NULL;
+
+ if (al.sym && al.sym->name)
+ symname = al.sym->name;
+ else
+ symname = "";
+
+ if (al.map && al.map->dso && al.map->dso->name)
+ dsoname = al.map->dso->name;
+ else
+ dsoname = "";
+
+ printf("%16" PRIx64 " %s (%s)", al.addr, symname, dsoname);
+ }
+
if (PRINT_FIELD(TRACE))
print_trace_event(sample->cpu, sample->raw_data,
sample->raw_size);
@@ -972,7 +1005,7 @@ static const struct option options[] = {
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_CALLBACK('f', "fields", NULL, "str",
- "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace. Fields: comm,tid,pid,time,cpu,event,trace,sym",
+ "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace. Fields: comm,tid,pid,time,cpu,event,trace,sym,addr",
parse_output_fields),
OPT_END()
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-26 16:24 ` David Ahern
@ 2011-05-30 13:31 ` Akihiro Nagai
2011-05-30 15:26 ` David Ahern
0 siblings, 1 reply; 16+ messages in thread
From: Akihiro Nagai @ 2011-05-30 13:31 UTC (permalink / raw)
To: David Ahern
Cc: Frederic Weisbecker, Arnaldo Carvalho de Melo, Ingo Molnar,
Peter Zijlstra, linux-kernel, Masami Hiramatsu, pp-manager
(2011/05/27 1:24), David Ahern wrote:
>
>
> On 05/26/2011 07:28 AM, Frederic Weisbecker wrote:
>> (Adding David Ahern in Cc)
>>
>> Ok that's all good except this needs to use the "perf script" centralized
>> dump.
>>
>> Currently running "perf script" without an actual script dumps
>> the events by default, whatever kind of event they are: hardware,
>> software, tracepoints, ...
>> So we want the branch output to be supported there, so we can reuse
>> some code and interface.
>>
>> For example, "perf script -f branch:comm,tid,sym" would print the
>> comm, tid and the sym for to and from addresses.
>>
>> That's better than creating a new set of options in a new command
>> that people need to relearn while everybody could simply get
>> familiarized with common perf script options.
>>
>> Of course we can still have a "perf branch" command, which could
>> be a tiny shortcut that maps to perf record and perf script.
>>
>> Like:
>>
>> perf branch record
>> perf branch [trace] -f tid,sym,comm
>>
>> Would map to:
>>
>> perf record branch:u
>> perf script -f branch:tid,sym,comm
>>
>> And may be if one day we can do something more tricky than a
>> linear output for branches (like source code coloring/browsing),
>> then it may be implemented inside perf branch and not rely on
>> another subcommand. Until then we are only dealing with raw linear
>> dump, and that's a core job for perf script where we want to
>> centralize that kind of facility.
>
> I mentioned that when v3 was posted.
>
> The sample address can be converted to symbols and the output can be
> added to perf-script rather easily. Attached is an example. I was going
> to submit it back in April and got distracted. I'll rebase, move the
> addr->sym conversion to a function and submit later today.
OK.
I agreed with implementing it on perf script.
I'd like to try it.
Thank you.
>
> David
>
>>
>> Thanks.
>>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-30 13:31 ` Akihiro Nagai
@ 2011-05-30 15:26 ` David Ahern
2011-05-30 16:11 ` Frederic Weisbecker
2011-06-10 4:24 ` Akihiro Nagai
0 siblings, 2 replies; 16+ messages in thread
From: David Ahern @ 2011-05-30 15:26 UTC (permalink / raw)
To: Akihiro Nagai
Cc: Frederic Weisbecker, Arnaldo Carvalho de Melo, Ingo Molnar,
Peter Zijlstra, linux-kernel, Masami Hiramatsu, pp-manager
[-- Attachment #1: Type: text/plain, Size: 671 bytes --]
On 05/30/2011 07:31 AM, Akihiro Nagai wrote:
>> The sample address can be converted to symbols and the output can be
>> added to perf-script rather easily. Attached is an example. I was going
>> to submit it back in April and got distracted. I'll rebase, move the
>> addr->sym conversion to a function and submit later today.
> OK.
> I agreed with implementing it on perf script.
> I'd like to try it.
Updated patch. It applies on top of:
http://lkml.org/lkml/2011/5/27/385
Hopefully for BTS you only have to change the sample_addr_correlates_sym
function.
I still need to look into out why some of the addresses for page-faults
are not resolving to symbols.
David
[-- Attachment #2: perf-addr.patch --]
[-- Type: text/plain, Size: 5990 bytes --]
diff --git a/tools/perf/Documentation/perf-script.txt b/tools/perf/Documentation/perf-script.txt
index 1e744c2..c6068cb 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -115,8 +115,8 @@ OPTIONS
-f::
--fields::
Comma separated list of fields to print. Options are:
- comm, tid, pid, time, cpu, event, trace, ip, sym, dso. Field
- list can be prepended with the type, trace, sw or hw,
+ comm, tid, pid, time, cpu, event, trace, ip, sym, dso, addr.
+ 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 6fcaa87..841ce49 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -33,6 +33,7 @@ enum perf_output_field {
PERF_OUTPUT_IP = 1U << 7,
PERF_OUTPUT_SYM = 1U << 8,
PERF_OUTPUT_DSO = 1U << 9,
+ PERF_OUTPUT_ADDR = 1U << 10,
};
struct output_option {
@@ -49,6 +50,7 @@ struct output_option {
{.str = "ip", .field = PERF_OUTPUT_IP},
{.str = "sym", .field = PERF_OUTPUT_SYM},
{.str = "dso", .field = PERF_OUTPUT_DSO},
+ {.str = "addr", .field = PERF_OUTPUT_ADDR},
};
/* default set to maintain compatibility with current format */
@@ -173,14 +175,22 @@ static int perf_evsel__check_attr(struct perf_evsel *evsel,
!(attr->sample_type & PERF_SAMPLE_CALLCHAIN))
symbol_conf.use_callchain = false;
}
- if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP)) {
- pr_err("Display of symbols requested but IP is not selected.\n"
- "No addresses to convert to symbols.\n");
+
+ if (PRINT_FIELD(ADDR) &&
+ perf_event_attr__check_stype(attr, PERF_SAMPLE_ADDR, "ADDR",
+ PERF_OUTPUT_ADDR))
+ return -EINVAL;
+
+ if (PRINT_FIELD(SYM) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
+ pr_err("Display of symbols requested but neither sample IP nor "
+ "sample address\nis selected. Hence, no addresses to convert "
+ "to symbols.\n");
return -EINVAL;
}
- if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP)) {
- pr_err("Display of DSO requested but IP is not selected.\n"
- "No addresses to convert to dso.\n");
+ if (PRINT_FIELD(DSO) && !PRINT_FIELD(IP) && !PRINT_FIELD(ADDR)) {
+ pr_err("Display of DSO requested but neither sample IP nor "
+ "sample address\nis selected. Hence, no addresses to convert "
+ "to DSO.\n");
return -EINVAL;
}
@@ -288,6 +298,59 @@ static void print_sample_start(struct perf_sample *sample,
}
}
+static bool sample_addr_correlates_sym(struct perf_event_attr *attr)
+{
+ if ((attr->type == PERF_TYPE_SOFTWARE) &&
+ ((attr->config == PERF_COUNT_SW_PAGE_FAULTS) ||
+ (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MIN) ||
+ (attr->config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)))
+ return true;
+
+ return false;
+}
+
+static void print_sample_addr(union perf_event *event,
+ struct perf_sample *sample,
+ struct perf_session *session,
+ struct thread *thread,
+ struct perf_event_attr *attr)
+{
+ struct addr_location al;
+ u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
+ const char *symname, *dsoname;
+
+ printf("%16" PRIx64, sample->addr);
+
+ if (!sample_addr_correlates_sym(attr))
+ return;
+
+ thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION,
+ event->ip.pid, sample->addr, &al);
+ al.cpu = sample->cpu;
+ al.sym = NULL;
+
+ if (al.map)
+ al.sym = map__find_symbol(al.map, al.addr, NULL);
+
+ if (PRINT_FIELD(SYM)) {
+ if (al.sym && al.sym->name)
+ symname = al.sym->name;
+ else
+ symname = "";
+
+ printf(" %16s", symname);
+ }
+
+ if (PRINT_FIELD(DSO)) {
+ if (al.map && al.map->dso && al.map->dso->name)
+ dsoname = al.map->dso->name;
+ else
+ dsoname = "";
+
+ printf(" (%s)", dsoname);
+ }
+}
+
static void process_event(union perf_event *event __unused,
struct perf_sample *sample,
struct perf_evsel *evsel,
@@ -305,6 +368,9 @@ static void process_event(union perf_event *event __unused,
print_trace_event(sample->cpu, sample->raw_data,
sample->raw_size);
+ if (PRINT_FIELD(ADDR))
+ print_sample_addr(event, sample, session, thread, attr);
+
if (PRINT_FIELD(IP)) {
if (!symbol_conf.use_callchain)
printf(" ");
@@ -1003,7 +1069,7 @@ static const struct option options[] = {
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
"Look for files with symbols relative to this directory"),
OPT_CALLBACK('f', "fields", NULL, "str",
- "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym",
+ "comma separated output fields prepend with 'type:'. Valid types: hw,sw,trace,raw. Fields: comm,tid,pid,time,cpu,event,trace,sym,dso,addr",
parse_output_fields),
OPT_END()
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index cca29ed..669e18a 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -361,6 +361,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
array++;
}
+ data->addr = 0;
if (type & PERF_SAMPLE_ADDR) {
data->addr = *array;
array++;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 360d8c4..21e6c91 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -698,9 +698,9 @@ static void dump_sample(struct perf_session *session, union perf_event *event,
if (!dump_trace)
return;
- printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 "\n",
+ printf("(IP, %d): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n",
event->header.misc, sample->pid, sample->tid, sample->ip,
- sample->period);
+ sample->period, sample->addr);
if (session->sample_type & PERF_SAMPLE_CALLCHAIN)
callchain__printf(sample);
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-30 15:26 ` David Ahern
@ 2011-05-30 16:11 ` Frederic Weisbecker
2011-05-30 19:00 ` Arnaldo Carvalho de Melo
2011-06-10 4:24 ` Akihiro Nagai
1 sibling, 1 reply; 16+ messages in thread
From: Frederic Weisbecker @ 2011-05-30 16:11 UTC (permalink / raw)
To: David Ahern
Cc: Akihiro Nagai, Arnaldo Carvalho de Melo, Ingo Molnar,
Peter Zijlstra, linux-kernel, Masami Hiramatsu, pp-manager
On Mon, May 30, 2011 at 09:26:28AM -0600, David Ahern wrote:
> On 05/30/2011 07:31 AM, Akihiro Nagai wrote:
> >> The sample address can be converted to symbols and the output can be
> >> added to perf-script rather easily. Attached is an example. I was going
> >> to submit it back in April and got distracted. I'll rebase, move the
> >> addr->sym conversion to a function and submit later today.
> > OK.
> > I agreed with implementing it on perf script.
> > I'd like to try it.
>
> Updated patch. It applies on top of:
> http://lkml.org/lkml/2011/5/27/385
>
> Hopefully for BTS you only have to change the sample_addr_correlates_sym
> function.
>
> I still need to look into out why some of the addresses for page-faults
> are not resolving to symbols.
Perhaps it only resolves instruction faults because you only resolve with
MAP__FUNCTION. You can try MAP__VARIABLE as well when that fails.
But that is going to only help with faults on global vars, ie: only
a few part of them. Further information would require some dwarf processing.
Your patch looks good though. Mind resending it with appropriate title/changelog
and signed-off-by tag?
thanks.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-30 16:11 ` Frederic Weisbecker
@ 2011-05-30 19:00 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 16+ messages in thread
From: Arnaldo Carvalho de Melo @ 2011-05-30 19:00 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: David Ahern, Akihiro Nagai, Ingo Molnar, Peter Zijlstra,
linux-kernel, Masami Hiramatsu, pp-manager, David Miller
Em Mon, May 30, 2011 at 06:11:49PM +0200, Frederic Weisbecker escreveu:
> On Mon, May 30, 2011 at 09:26:28AM -0600, David Ahern wrote:
> > On 05/30/2011 07:31 AM, Akihiro Nagai wrote:
> > >> The sample address can be converted to symbols and the output can be
> > >> added to perf-script rather easily. Attached is an example. I was going
> > >> to submit it back in April and got distracted. I'll rebase, move the
> > >> addr->sym conversion to a function and submit later today.
> > > OK.
> > > I agreed with implementing it on perf script.
> > > I'd like to try it.
> >
> > Updated patch. It applies on top of:
> > http://lkml.org/lkml/2011/5/27/385
> >
> > Hopefully for BTS you only have to change the sample_addr_correlates_sym
> > function.
> >
> > I still need to look into out why some of the addresses for page-faults
> > are not resolving to symbols.
>
> Perhaps it only resolves instruction faults because you only resolve with
> MAP__FUNCTION. You can try MAP__VARIABLE as well when that fails.
>
> But that is going to only help with faults on global vars, ie: only
> a few part of them. Further information would require some dwarf processing.
>
> Your patch looks good though. Mind resending it with appropriate title/changelog
> and signed-off-by tag?
Just for reference: I thought about removing this split but David Miller
told me that there are architectures where we can't do that, i.e. there
is no guarantee of an unified addr space for variables and code, such as
SPARC.
- Arnaldo
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-30 15:26 ` David Ahern
2011-05-30 16:11 ` Frederic Weisbecker
@ 2011-06-10 4:24 ` Akihiro Nagai
1 sibling, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-06-10 4:24 UTC (permalink / raw)
To: David Ahern
Cc: Frederic Weisbecker, Arnaldo Carvalho de Melo, Ingo Molnar,
Peter Zijlstra, linux-kernel, Masami Hiramatsu, pp-manager
(2011/05/31 0:26), David Ahern wrote:
> On 05/30/2011 07:31 AM, Akihiro Nagai wrote:
>>> The sample address can be converted to symbols and the output can be
>>> added to perf-script rather easily. Attached is an example. I was going
>>> to submit it back in April and got distracted. I'll rebase, move the
>>> addr->sym conversion to a function and submit later today.
>> OK.
>> I agreed with implementing it on perf script.
>> I'd like to try it.
>
> Updated patch. It applies on top of:
> http://lkml.org/lkml/2011/5/27/385
It looks good.
>
> Hopefully for BTS you only have to change the sample_addr_correlates_sym
> function.
Yes.
I'd like to enhance perf-script like this:
# perf script -f ip,addr,comm,sym,dso
output format is:
<comm> <ip> <sym_ip> <dso_ip> <addr> <sym_addr> <dso_addr>
actual output sample is:
ls 0xffffffff81460b92 common_interrupt /lib/modules/3.0/build/vmlinux 0x0000003e9b000b20 _start /lib64/ld-2.13.so
ls 0x0000003e9b000b23 _start /lib64/ld-2.13.so 0x0000003e9b004540 _dl_start /lib64/ld-2.13.so
...
By specifying 'ip' and 'addr' together, perf-script resolves
symbol and dso's path about both of 'ip' and 'addr'.
>
> I still need to look into out why some of the addresses for page-faults
> are not resolving to symbols.
I'd like to improve it referring perf branch's source codes.
Thank you.
>
> David
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH -tip v4 0/7] perf: Introduce branch sub commands
2011-05-26 13:28 ` [PATCH -tip v4 0/7] perf: Introduce branch sub commands Frederic Weisbecker
2011-05-26 16:24 ` David Ahern
@ 2011-06-10 7:17 ` Akihiro Nagai
1 sibling, 0 replies; 16+ messages in thread
From: Akihiro Nagai @ 2011-06-10 7:17 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Arnaldo Carvalho de Melo, Ingo Molnar, Peter Zijlstra,
linux-kernel, Masami Hiramatsu, pp-manager, David Ahern
(2011/05/26 22:28), Frederic Weisbecker wrote:
> (Adding David Ahern in Cc)
>
> Ok that's all good except this needs to use the "perf script" centralized
> dump.
>
> Currently running "perf script" without an actual script dumps
> the events by default, whatever kind of event they are: hardware,
> software, tracepoints, ...
> So we want the branch output to be supported there, so we can reuse
> some code and interface.
>
> For example, "perf script -f branch:comm,tid,sym" would print the
> comm, tid and the sym for to and from addresses.
>
> That's better than creating a new set of options in a new command
> that people need to relearn while everybody could simply get
> familiarized with common perf script options.
>
> Of course we can still have a "perf branch" command, which could
> be a tiny shortcut that maps to perf record and perf script.
>
> Like:
>
> perf branch record
> perf branch [trace] -f tid,sym,comm
>
> Would map to:
>
> perf record branch:u
> perf script -f branch:tid,sym,comm
>
> And may be if one day we can do something more tricky than a
> linear output for branches (like source code coloring/browsing),
> then it may be implemented inside perf branch and not rely on
> another subcommand. Until then we are only dealing with raw linear
> dump, and that's a core job for perf script where we want to
> centralize that kind of facility.
OK.
I agreed that the core job is dumpimg BTS logs on perf script.
Next, I'd like to implement the perf-branch's functions and
additional interfaces to perf script.
For example, resoving symbols and dso about branch_to address and,
adding interfaces to get source file path, line number using debuginfo.
I presented about perf-branch's future plan in LinuxCon Japan 2011,
please refer the follwing slide.
http://events.linuxfoundation.org/events/linuxcon-japan/nagai
(The slide will be available soon)
Thank you.
>
> Thanks.
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2011-06-10 7:17 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-05-26 5:02 [PATCH -tip v4 0/7] perf: Introduce branch sub commands Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 1/7] perf: new subcommand perf branch record Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 2/7] perf branch: Introduce new sub command 'perf branch trace' Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 3/7] perf branch trace: print pid and command Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 4/7] perf branch trace: print file path of the executed elf Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 5/7] perf branch trace: print function+offset Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 6/7] perf branch trace: add print all option Akihiro Nagai
2011-05-26 5:03 ` [PATCH -tip v4 7/7] perf branch trace: add kernel filter Akihiro Nagai
2011-05-26 13:28 ` [PATCH -tip v4 0/7] perf: Introduce branch sub commands Frederic Weisbecker
2011-05-26 16:24 ` David Ahern
2011-05-30 13:31 ` Akihiro Nagai
2011-05-30 15:26 ` David Ahern
2011-05-30 16:11 ` Frederic Weisbecker
2011-05-30 19:00 ` Arnaldo Carvalho de Melo
2011-06-10 4:24 ` Akihiro Nagai
2011-06-10 7:17 ` Akihiro Nagai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox