Hi,
This patch series provides the commands 'perf branch record' and 'perf branch trace'
version 3. 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 <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
irq_return+0x0 => _start+0x0
irq_return+0x0 => _start+0x0
_start+0x3 => _dl_start+0x0
irq_return+0x0 => _dl_start+0x0
irq_return+0x0 => _dl_start+0x26
irq_return+0x0 => _dl_start+0x2d
_dl_start+0x71 => _dl_start+0x93
_dl_start+0x97 => _dl_start+0x78
...
This is the default behavior of 'perf branch trace'. It prints function+offset.
Example2: 'perf branch -cas trace'
command address function+offset
ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806200b20 _start+0x0
ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806200b20 _start+0x0
ls 0x0000003806200b23 _start+0x3 => ls 0x0000003806204910 _dl_start+0x0
ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806204910 _dl_start+0x0
ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806204936 _dl_start+0x26
ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x000000380620493d _dl_start+0x2d
ls 0x0000003806204981 _dl_start+0x71 => ls 0x00000038062049a3 _dl_start+0x93
ls 0x00000038062049a7 _dl_start+0x97 => ls 0x0000003806204988 _dl_start+0x78
...
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 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 (6):
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 | 54 +++++
tools/perf/Makefile | 1
tools/perf/builtin-branch.c | 329 ++++++++++++++++++++++++++++++
tools/perf/builtin.h | 1
tools/perf/command-list.txt | 1
tools/perf/perf.c | 1
6 files changed, 387 insertions(+), 0 deletions(-)
create mode 100644 tools/perf/Documentation/perf-branch.txt
create mode 100644 tools/perf/builtin-branch.c
--
Akihiro Nagai ([email protected])
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 <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
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 158c30e..f50bd89 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -356,6 +356,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;
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 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 <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-branch.txt | 14 ++++-
tools/perf/builtin-branch.c | 81 +++++++++++++++++++++++++++++-
2 files changed, 89 insertions(+), 6 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index 075cfce..e223267 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,14 @@ 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.
+
SEE ALSO
--------
linkperf:perf-record[1]
diff --git a/tools/perf/builtin-branch.c b/tools/perf/builtin-branch.c
index f338f3a..7dbabf4 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -1,10 +1,28 @@
#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";
static const char * const branch_usage[] = {
- "perf branch record <command>",
- NULL,
+ "perf branch [<options>] {record|trace}",
+ NULL
};
/* arguments to call 'perf record' */
@@ -16,11 +34,66 @@ 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_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_session *session)
+{
+ if (!is_bts_sample(sample, session))
+ return 0;
+
+ /* sample->ip is 'from address', sample->addr is 'to address' */
+ printf(FMT_ADDR " => " FMT_ADDR "\n", sample->ip, sample->addr);
+
+ 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 +128,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);
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 => ls 0x0000003806200b20
ls 0xffffffff8146fe0e => ls 0x0000003806200b20
ls 0x0000003806200b23 => ls 0x0000003806204910
ls 0xffffffff8146fe0e => ls 0x0000003806204910
ls 0xffffffff8146fe0e => ls 0x0000003806204936
ls 0xffffffff8146fe0e => ls 0x000000380620493d
ls 0x0000003806204981 => ls 0x00000038062049a3
ls 0x00000038062049a7 => ls 0x0000003806204988
Signed-off-by: Akihiro Nagai <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-branch.txt | 18 ++++-
tools/perf/builtin-branch.c | 119 ++++++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index e223267..6c9c253 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,13 +20,25 @@ 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
-------
-i::
--input=::
Specify input file name to analyze.
+-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 7dbabf4..22aa25e 100644
--- a/tools/perf/builtin-branch.c
+++ b/tools/perf/builtin-branch.c
@@ -17,6 +17,32 @@
/* 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 */
+#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
+
+/* 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";
@@ -34,8 +60,25 @@ 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_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()
};
@@ -60,20 +103,89 @@ 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)
+{
+ char pid[16];
+ const char *comm;
+
+ if (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);
+ printf("%5s ", pid);
+ }
+ if (print_flags & EI_FLAG_PRINT_COMM) {
+ comm = ei->comm ? : EI_UNKNOWN_TEXT;
+ printf("%-12s ", comm);
+ }
+ if (print_flags & EI_FLAG_PRINT_ADDR)
+ printf(FMT_ADDR " ", ei->addr);
+}
+
+static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
+{
+ __print_exec_info(ei_from);
+ printf("=> ");
+ __print_exec_info(ei_to);
+ printf("\n");
+}
+
+static void print_exec_info_header(void)
+{
+ if (print_flags & EI_FLAG_PRINT_PID)
+ printf("%5s ", "pid");
+ if (print_flags & EI_FLAG_PRINT_COMM)
+ printf("%-12s ", "command");
+ if (print_flags & EI_FLAG_PRINT_ADDR)
+ printf("%-" FMT_ADDR_WIDTH "s ", "address");
+ printf("\n");
+}
+
static int process_sample_event(union perf_event *event __unused,
struct perf_sample *sample, 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' */
- printf(FMT_ADDR " => " FMT_ADDR "\n", sample->ip, sample->addr);
+ 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,
};
@@ -87,7 +199,12 @@ static int __cmd_trace(void)
return EXIT_FAILURE;
}
+ /* if print flags are unset, we use default flags */
+ if (is_flags_unset(print_flags))
+ print_flags = EI_FLAG_PRINT_DEFAULT;
+
setup_pager();
+ print_exec_info_header();
perf_session__process_events(session, &event_ops);
perf_session__delete(session);
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.38-rc8-tip+/build/vmlinux => 0x0000003806200b20 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.38-rc8-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.38-rc8-tip+/build/vmlinux => 0x0000003806204910 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.38-rc8-tip+/build/vmlinux => 0x0000003806204936 /lib64/ld-2.12.90.so
0xffffffff81458f4e /lib/modules/2.6.38-rc8-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 V3:
- Update to latest -tip tree
Changes in V2:
- add comment
Signed-off-by: Akihiro Nagai <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
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 6c9c253..f98b32e 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -39,6 +39,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 22aa25e..3d8a9c5 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 */
#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
@@ -79,6 +81,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()
};
@@ -114,6 +119,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;
@@ -122,12 +128,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)
{
char pid[16];
const char *comm;
+ const char *elfpath;
if (print_flags & EI_FLAG_PRINT_PID) {
if (ei->pid == EI_PID_UNSET)
@@ -142,6 +162,10 @@ static void __print_exec_info(struct exec_info *ei)
}
if (print_flags & EI_FLAG_PRINT_ADDR)
printf(FMT_ADDR " ", ei->addr);
+ if (print_flags & EI_FLAG_PRINT_ELFPATH) {
+ elfpath = ei->elfpath ? : EI_UNKNOWN_TEXT;
+ printf("%-32s ", elfpath);
+ }
}
static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
@@ -160,6 +184,8 @@ static void print_exec_info_header(void)
printf("%-12s ", "command");
if (print_flags & EI_FLAG_PRINT_ADDR)
printf("%-" FMT_ADDR_WIDTH "s ", "address");
+ if (print_flags & EI_FLAG_PRINT_ELFPATH)
+ printf("%-32s ", "elf_filepath");
printf("\n");
}
@@ -186,6 +212,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,
};
@@ -203,6 +230,11 @@ static int __cmd_trace(void)
if (is_flags_unset(print_flags))
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);
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 <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
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 9c7e100..dd06090 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -45,6 +45,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 819443e..efbd8d8 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 */
#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_SYMBOL
@@ -94,6 +97,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()
};
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 V3:
- rename to 'perf branch'
- fix getting elf_path bug
Signed-off-by: Akihiro Nagai <[email protected]>
Reviewed-by: Masami Hiramatsu <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Arnaldo Carvalho de Melo <[email protected]>
---
tools/perf/Documentation/perf-branch.txt | 5 +++
tools/perf/builtin-branch.c | 43 ++++++++++++++++++++++++++++--
2 files changed, 44 insertions(+), 4 deletions(-)
diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
index f98b32e..9c7e100 100644
--- a/tools/perf/Documentation/perf-branch.txt
+++ b/tools/perf/Documentation/perf-branch.txt
@@ -32,7 +32,7 @@ OPTIONS
Specify input file name to analyze.
-a::
--addr::
- Print address. (default)
+ Print address.
-c::
--comm::
Print command name.
@@ -42,6 +42,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 3d8a9c5..819443e 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,9 +34,10 @@ 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 */
-#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
+#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_SYMBOL
/* print item flags */
static unsigned long print_flags;
@@ -45,6 +48,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";
@@ -73,7 +79,7 @@ static int set_print_flags(const struct option *opt, const char *str __unused,
static const struct option branch_options[] = {
OPT_STRING('i', "input", &input_name, "file", "input file name"),
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,
@@ -84,6 +90,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()
};
@@ -129,7 +139,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);
@@ -141,6 +151,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)
@@ -148,6 +165,8 @@ static void __print_exec_info(struct exec_info *ei)
char pid[16];
const char *comm;
const char *elfpath;
+ char *symbol;
+ int symbol_len;
if (print_flags & EI_FLAG_PRINT_PID) {
if (ei->pid == EI_PID_UNSET)
@@ -162,6 +181,22 @@ static void __print_exec_info(struct exec_info *ei)
}
if (print_flags & EI_FLAG_PRINT_ADDR)
printf(FMT_ADDR " ", ei->addr);
+ if (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);
+ printf("%-32s ", symbol);
+ free(symbol);
+ }
+
+print_elfpath:
if (print_flags & EI_FLAG_PRINT_ELFPATH) {
elfpath = ei->elfpath ? : EI_UNKNOWN_TEXT;
printf("%-32s ", elfpath);
@@ -184,6 +219,8 @@ static void print_exec_info_header(void)
printf("%-12s ", "command");
if (print_flags & EI_FLAG_PRINT_ADDR)
printf("%-" FMT_ADDR_WIDTH "s ", "address");
+ if (print_flags & EI_FLAG_PRINT_SYMBOL)
+ printf("%-32s ", "function+offset");
if (print_flags & EI_FLAG_PRINT_ELFPATH)
printf("%-32s ", "elf_filepath");
printf("\n");
On 03/24/11 05:32, Akihiro Nagai wrote:
> 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 => ls 0x0000003806200b20
> ls 0xffffffff8146fe0e => ls 0x0000003806200b20
> ls 0x0000003806200b23 => ls 0x0000003806204910
> ls 0xffffffff8146fe0e => ls 0x0000003806204910
> ls 0xffffffff8146fe0e => ls 0x0000003806204936
> ls 0xffffffff8146fe0e => ls 0x000000380620493d
> ls 0x0000003806204981 => ls 0x00000038062049a3
> ls 0x00000038062049a7 => ls 0x0000003806204988
This can be easily added to perf-script. e.g,
perf record -e branches:u -c 1 -d -- ls /tmp
perf script -i /tmp/perf.data -f hw:comm,pid,event,sym,addr
...
ls 8150 branches: 0x39d30144d0 ffffffff8146a48e ()
ls 8150 branches: 0x39d3014507 ffffffff8146a48e ()
ls 8150 branches: 0x39d3014510 14518 _dl_sysdep_start
(/lib64/ld-2.13.so)
...
ls 8150 branches: 0x39d3015250 1833 process_envvars
(/lib64/ld-2.13.so)
ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
(/lib64/ld-2.13.so)
ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
(/lib64/ld-2.13.so)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index ac574ea..85376b7 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 */
@@ -158,6 +160,8 @@ static void print_sample_start(struct perf_sample
*sample,
printf("%s: ", evname ? evname : "(unknown)");
}
+ if (PRINT_FIELD(ADDR))
+ printf("0x%" PRIx64, sample->addr);
}
static void process_event(union perf_event *event __unused,
@@ -829,7 +833,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()
>
> Signed-off-by: Akihiro Nagai <[email protected]>
> Reviewed-by: Masami Hiramatsu <[email protected]>
> Cc: Peter Zijlstra <[email protected]>
> Cc: Frederic Weisbecker <[email protected]>
> Cc: Paul Mackerras <[email protected]>
> Cc: Ingo Molnar <[email protected]>
> Cc: Arnaldo Carvalho de Melo <[email protected]>
> ---
>
> tools/perf/Documentation/perf-branch.txt | 18 ++++-
> tools/perf/builtin-branch.c | 119 ++++++++++++++++++++++++++++++
> 2 files changed, 133 insertions(+), 4 deletions(-)
>
> diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
> index e223267..6c9c253 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,13 +20,25 @@ 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
> -------
> -i::
> --input=::
> Specify input file name to analyze.
> +-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 7dbabf4..22aa25e 100644
> --- a/tools/perf/builtin-branch.c
> +++ b/tools/perf/builtin-branch.c
> @@ -17,6 +17,32 @@
> /* 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 */
> +#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
> +
> +/* 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";
>
> @@ -34,8 +60,25 @@ 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_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()
> };
>
> @@ -60,20 +103,89 @@ 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)
> +{
> + char pid[16];
> + const char *comm;
> +
> + if (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);
> + printf("%5s ", pid);
> + }
> + if (print_flags & EI_FLAG_PRINT_COMM) {
> + comm = ei->comm ? : EI_UNKNOWN_TEXT;
> + printf("%-12s ", comm);
> + }
> + if (print_flags & EI_FLAG_PRINT_ADDR)
> + printf(FMT_ADDR " ", ei->addr);
> +}
> +
> +static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
> +{
> + __print_exec_info(ei_from);
> + printf("=> ");
> + __print_exec_info(ei_to);
> + printf("\n");
> +}
> +
> +static void print_exec_info_header(void)
> +{
> + if (print_flags & EI_FLAG_PRINT_PID)
> + printf("%5s ", "pid");
> + if (print_flags & EI_FLAG_PRINT_COMM)
> + printf("%-12s ", "command");
> + if (print_flags & EI_FLAG_PRINT_ADDR)
> + printf("%-" FMT_ADDR_WIDTH "s ", "address");
> + printf("\n");
> +}
> +
> static int process_sample_event(union perf_event *event __unused,
> struct perf_sample *sample, 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' */
> - printf(FMT_ADDR " => " FMT_ADDR "\n", sample->ip, sample->addr);
> + 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,
> };
>
> @@ -87,7 +199,12 @@ static int __cmd_trace(void)
> return EXIT_FAILURE;
> }
>
> + /* if print flags are unset, we use default flags */
> + if (is_flags_unset(print_flags))
> + print_flags = EI_FLAG_PRINT_DEFAULT;
> +
> setup_pager();
> + print_exec_info_header();
> perf_session__process_events(session, &event_ops);
> perf_session__delete(session);
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
(2011/03/25 2:05), David Ahern wrote:
>
>
> On 03/24/11 05:32, Akihiro Nagai wrote:
>> 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 => ls 0x0000003806200b20
>> ls 0xffffffff8146fe0e => ls 0x0000003806200b20
>> ls 0x0000003806200b23 => ls 0x0000003806204910
>> ls 0xffffffff8146fe0e => ls 0x0000003806204910
>> ls 0xffffffff8146fe0e => ls 0x0000003806204936
>> ls 0xffffffff8146fe0e => ls 0x000000380620493d
>> ls 0x0000003806204981 => ls 0x00000038062049a3
>> ls 0x00000038062049a7 => ls 0x0000003806204988
>
> This can be easily added to perf-script. e.g,
>
> perf record -e branches:u -c 1 -d -- ls /tmp
>
> perf script -i /tmp/perf.data -f hw:comm,pid,event,sym,addr
>
> ...
> ls 8150 branches: 0x39d30144d0 ffffffff8146a48e ()
> ls 8150 branches: 0x39d3014507 ffffffff8146a48e ()
> ls 8150 branches: 0x39d3014510 14518 _dl_sysdep_start
> (/lib64/ld-2.13.so)
> ...
> ls 8150 branches: 0x39d3015250 1833 process_envvars
> (/lib64/ld-2.13.so)
> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
> (/lib64/ld-2.13.so)
> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
> (/lib64/ld-2.13.so)
It seems to analyze only 'branch from' address and,
print 'branch to' address just in hex.
I would like to analyze both of addresses branch from/to.
Can perf-script do it by writing scripts?
>
>
> diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
> index ac574ea..85376b7 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 */
> @@ -158,6 +160,8 @@ static void print_sample_start(struct perf_sample
> *sample,
>
> printf("%s: ", evname ? evname : "(unknown)");
> }
> + if (PRINT_FIELD(ADDR))
> + printf("0x%" PRIx64, sample->addr);
> }
>
> static void process_event(union perf_event *event __unused,
> @@ -829,7 +833,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()
>
>>
>> Signed-off-by: Akihiro Nagai<[email protected]>
>> Reviewed-by: Masami Hiramatsu<[email protected]>
>> Cc: Peter Zijlstra<[email protected]>
>> Cc: Frederic Weisbecker<[email protected]>
>> Cc: Paul Mackerras<[email protected]>
>> Cc: Ingo Molnar<[email protected]>
>> Cc: Arnaldo Carvalho de Melo<[email protected]>
>> ---
>>
>> tools/perf/Documentation/perf-branch.txt | 18 ++++-
>> tools/perf/builtin-branch.c | 119 ++++++++++++++++++++++++++++++
>> 2 files changed, 133 insertions(+), 4 deletions(-)
>>
>> diff --git a/tools/perf/Documentation/perf-branch.txt b/tools/perf/Documentation/perf-branch.txt
>> index e223267..6c9c253 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,13 +20,25 @@ 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
>> -------
>> -i::
>> --input=::
>> Specify input file name to analyze.
>> +-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 7dbabf4..22aa25e 100644
>> --- a/tools/perf/builtin-branch.c
>> +++ b/tools/perf/builtin-branch.c
>> @@ -17,6 +17,32 @@
>> /* 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 */
>> +#define EI_FLAG_PRINT_DEFAULT EI_FLAG_PRINT_ADDR
>> +
>> +/* 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";
>>
>> @@ -34,8 +60,25 @@ 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_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()
>> };
>>
>> @@ -60,20 +103,89 @@ 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)
>> +{
>> + char pid[16];
>> + const char *comm;
>> +
>> + if (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);
>> + printf("%5s ", pid);
>> + }
>> + if (print_flags& EI_FLAG_PRINT_COMM) {
>> + comm = ei->comm ? : EI_UNKNOWN_TEXT;
>> + printf("%-12s ", comm);
>> + }
>> + if (print_flags& EI_FLAG_PRINT_ADDR)
>> + printf(FMT_ADDR " ", ei->addr);
>> +}
>> +
>> +static void print_exec_info(struct exec_info *ei_from, struct exec_info *ei_to)
>> +{
>> + __print_exec_info(ei_from);
>> + printf("=> ");
>> + __print_exec_info(ei_to);
>> + printf("\n");
>> +}
>> +
>> +static void print_exec_info_header(void)
>> +{
>> + if (print_flags& EI_FLAG_PRINT_PID)
>> + printf("%5s ", "pid");
>> + if (print_flags& EI_FLAG_PRINT_COMM)
>> + printf("%-12s ", "command");
>> + if (print_flags& EI_FLAG_PRINT_ADDR)
>> + printf("%-" FMT_ADDR_WIDTH "s ", "address");
>> + printf("\n");
>> +}
>> +
>> static int process_sample_event(union perf_event *event __unused,
>> struct perf_sample *sample, 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' */
>> - printf(FMT_ADDR " => " FMT_ADDR "\n", sample->ip, sample->addr);
>> + 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,
>> };
>>
>> @@ -87,7 +199,12 @@ static int __cmd_trace(void)
>> return EXIT_FAILURE;
>> }
>>
>> + /* if print flags are unset, we use default flags */
>> + if (is_flags_unset(print_flags))
>> + print_flags = EI_FLAG_PRINT_DEFAULT;
>> +
>> setup_pager();
>> + print_exec_info_header();
>> perf_session__process_events(session,&event_ops);
>> perf_session__delete(session);
>>
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to [email protected]
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
On 03/25/11 04:14, Akihiro Nagai wrote:
>> On 03/24/11 05:32, Akihiro Nagai wrote:
>>> 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 => ls 0x0000003806200b20
>>> ls 0xffffffff8146fe0e => ls 0x0000003806200b20
>>> ls 0x0000003806200b23 => ls 0x0000003806204910
>>> ls 0xffffffff8146fe0e => ls 0x0000003806204910
>>> ls 0xffffffff8146fe0e => ls 0x0000003806204936
>>> ls 0xffffffff8146fe0e => ls 0x000000380620493d
>>> ls 0x0000003806204981 => ls 0x00000038062049a3
>>> ls 0x00000038062049a7 => ls 0x0000003806204988
>>
>> This can be easily added to perf-script. e.g,
>>
>> perf record -e branches:u -c 1 -d -- ls /tmp
>>
>> perf script -i /tmp/perf.data -f hw:comm,pid,event,sym,addr
>>
>> ...
>> ls 8150 branches: 0x39d30144d0 ffffffff8146a48e ()
>> ls 8150 branches: 0x39d3014507 ffffffff8146a48e ()
>> ls 8150 branches: 0x39d3014510 14518 _dl_sysdep_start
>> (/lib64/ld-2.13.so)
>> ...
>> ls 8150 branches: 0x39d3015250 1833 process_envvars
>> (/lib64/ld-2.13.so)
>> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
>> (/lib64/ld-2.13.so)
>> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
>> (/lib64/ld-2.13.so)
> It seems to analyze only 'branch from' address and,
> print 'branch to' address just in hex.
> I would like to analyze both of addresses branch from/to.
from is sample->ip? to is sample->addr? In the above example
0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
>
> Can perf-script do it by writing scripts?
If you are pulling the data from a perf sample then you can accomplish
the same goal within perf-script.
David
(2011/03/26 0:02), David Ahern wrote:
> On 03/25/11 04:14, Akihiro Nagai wrote:
>>> On 03/24/11 05:32, Akihiro Nagai wrote:
>>>> 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 => ls 0x0000003806200b20
>>>> ls 0xffffffff8146fe0e => ls 0x0000003806200b20
>>>> ls 0x0000003806200b23 => ls 0x0000003806204910
>>>> ls 0xffffffff8146fe0e => ls 0x0000003806204910
>>>> ls 0xffffffff8146fe0e => ls 0x0000003806204936
>>>> ls 0xffffffff8146fe0e => ls 0x000000380620493d
>>>> ls 0x0000003806204981 => ls 0x00000038062049a3
>>>> ls 0x00000038062049a7 => ls 0x0000003806204988
>>>
>>> This can be easily added to perf-script. e.g,
>>>
>>> perf record -e branches:u -c 1 -d -- ls /tmp
>>>
>>> perf script -i /tmp/perf.data -f hw:comm,pid,event,sym,addr
>>>
>>> ...
>>> ls 8150 branches: 0x39d30144d0 ffffffff8146a48e ()
>>> ls 8150 branches: 0x39d3014507 ffffffff8146a48e ()
>>> ls 8150 branches: 0x39d3014510 14518 _dl_sysdep_start
>>> (/lib64/ld-2.13.so)
>>> ...
>>> ls 8150 branches: 0x39d3015250 1833 process_envvars
>>> (/lib64/ld-2.13.so)
>>> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
>>> (/lib64/ld-2.13.so)
>>> ls 8150 branches: 0x39d3015260 1526f _dl_next_ld_env_entry
>>> (/lib64/ld-2.13.so)
>> It seems to analyze only 'branch from' address and,
>> print 'branch to' address just in hex.
>> I would like to analyze both of addresses branch from/to.
>
> from is sample->ip? to is sample->addr? In the above example
> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
Yes.
In this example, resolved address is only sample->ip (branch from).
We need the resolved address of sample->addr (branch to) too, because
both of them are addresses of execution code.
For example, we need following output.
...
ls 0x00000038062152a9 _dl_sysdep_start+0x189 /lib64/ld-2.12.90.so => ls 0x00000038062020e0 dl_main+0x0 /lib64/ld-2.12.90.so
ls 0xffffffff814547d2 irq_return+0x0 /lib/modules/2.6.38-rc8-tip+/build/vmlinux => ls 0x00000038062020e0 dl_main+0x0 /lib64/ld-2.12.90.so
ls 0x0000003806202155 dl_main+0x75 /lib64/ld-2.12.90.so => ls 0x00000038062017d0 process_envvars+0x0 /lib64/ld-2.12.90.so
ls 0xffffffff814547d2 irq_return+0x0 /lib/modules/2.6.38-rc8-tip+/build/vmlinux => ls 0x00000038062017d0 process_envvars+0x0 /lib64/ld-2.12.90.so
ls 0x0000003806201833 process_envvars+0x63 /lib64/ld-2.12.90.so => ls 0x0000003806215ec0 _dl_next_ld_env_entry+0x0 /lib64/ld-2.12.90.so
ls 0x0000003806215ed3 _dl_next_ld_env_entry+0x13 /lib64/ld-2.12.90.so => ls 0x0000003806215ee5 _dl_next_ld_env_entry+0x25 /lib64/ld-2.12.90.so
ls 0x0000003806215ee9 _dl_next_ld_env_entry+0x29 /lib64/ld-2.12.90.so => ls 0x0000003806215ed5 _dl_next_ld_env_entry+0x15 /lib64/ld-2.12.90.so
...
This example's left hand side which is separated by "=>" is a result of resolving sample->ip and,
right hand side is sample->addr's.
>
>>
>> Can perf-script do it by writing scripts?
>
> If you are pulling the data from a perf sample then you can accomplish
> the same goal within perf-script.
It seems that perf-script doesn't have the interface of converting
sample->addr to symbol, pid, comm and others. Of course, we can add
the interface to perf-script, and it could be another way to implement
this function using perf-script.
However, since BTS output usually becomes huge, it would be very slow
to convert all the data by python/perl.
>
>
> David
On 03/28/11 04:34, Akihiro Nagai wrote:
>> from is sample->ip? to is sample->addr? In the above example
>> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
>> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> Yes.
> In this example, resolved address is only sample->ip (branch from).
> We need the resolved address of sample->addr (branch to) too, because
> both of them are addresses of execution code.
Ok, now I understand. In that case add conversion of sample->addr to
symbols to perf-script.
>>
>>>
>>> Can perf-script do it by writing scripts?
>>
>> If you are pulling the data from a perf sample then you can accomplish
>> the same goal within perf-script.
> It seems that perf-script doesn't have the interface of converting
> sample->addr to symbol, pid, comm and others. Of course, we can add
> the interface to perf-script, and it could be another way to implement
> this function using perf-script.
> However, since BTS output usually becomes huge, it would be very slow
> to convert all the data by python/perl.
Custom fields are not run through python/perl; they are generated from
C-code. Take a look at tools/perf/builtin-script.c
On Thu, Mar 24, 2011 at 08:31:37PM +0900, Akihiro Nagai wrote:
> Hi,
>
> This patch series provides the commands 'perf branch record' and 'perf branch trace'
> version 3. 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 <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
> irq_return+0x0 => _start+0x0
> irq_return+0x0 => _start+0x0
> _start+0x3 => _dl_start+0x0
> irq_return+0x0 => _dl_start+0x0
> irq_return+0x0 => _dl_start+0x26
> irq_return+0x0 => _dl_start+0x2d
These results are a bit surprising. May be we can
jump once from irq_return to _start, in the first schedule()
of a new task perhaps, but thereafter I would expect
further jumps not to happen from irq_return, but rather
from _start. When we have x as a destination in line n, then
I would expect to have x as a source in n + 1.
Also we are supposed to only trace BTS in userspace, but
perhaps, if we are interrupted, after the execution of the iret instruction,
BTS considers the following jump "iret -> interrupted inst" as a branch
in userspace. After all it makes sense, it is a jump in userspace.
So BTS, because of the way it defines a jump inside userspace,
traces irq returns but not irq entries, that would explain the trace
you gave as an example.
I suspect we want to filter irq returns. ie: if the source comes
from the kernel, then filter it by default. And then we can later
think about an option to enable interrupt return tracing if
people want them.
Thanks.
(2011/03/30 23:46), Frederic Weisbecker wrote:
<snip>
>> '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
>> irq_return+0x0 => _start+0x0
>> irq_return+0x0 => _start+0x0
>> _start+0x3 => _dl_start+0x0
>> irq_return+0x0 => _dl_start+0x0
>> irq_return+0x0 => _dl_start+0x26
>> irq_return+0x0 => _dl_start+0x2d
>
> These results are a bit surprising. May be we can
> jump once from irq_return to _start, in the first schedule()
> of a new task perhaps, but thereafter I would expect
> further jumps not to happen from irq_return, but rather
> from _start. When we have x as a destination in line n, then
> I would expect to have x as a source in n + 1.
Agree with the opinion "irq_start" surprising users.
However, I think it is not a better solution that uses a
previous destination as a next source.
Because, users want to know what happen in userspace and,
do not want to know interrupts from kernel.
I think the better solution is to implement the filter that
eliminate the record including kernel functions from output.
For example, leading example will be filtered like this.
_start+0x3 => _dl_start+0x0
In the future, I think the solution is available that using BTS records
with trace event like irq:irq_handler_entry to analyze interrupt.
However, to do it, we need to fix perf.
>
> Also we are supposed to only trace BTS in userspace, but
> perhaps, if we are interrupted, after the execution of the iret instruction,
> BTS considers the following jump "iret -> interrupted inst" as a branch
> in userspace. After all it makes sense, it is a jump in userspace.
>
> So BTS, because of the way it defines a jump inside userspace,
> traces irq returns but not irq entries, that would explain the trace
> you gave as an example.
>
> I suspect we want to filter irq returns. ie: if the source comes
> from the kernel, then filter it by default. And then we can later
> think about an option to enable interrupt return tracing if
> people want them.
Agree.
I will implement the option that enable/disable the filter.
>
> Thanks.
Thank you for your advise.
On Fri, Apr 01, 2011 at 07:57:05PM +0900, Akihiro Nagai wrote:
> (2011/03/30 23:46), Frederic Weisbecker wrote:
> <snip>
> >>'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
> >>irq_return+0x0 => _start+0x0
> >>irq_return+0x0 => _start+0x0
> >>_start+0x3 => _dl_start+0x0
> >>irq_return+0x0 => _dl_start+0x0
> >>irq_return+0x0 => _dl_start+0x26
> >>irq_return+0x0 => _dl_start+0x2d
> >
> >These results are a bit surprising. May be we can
> >jump once from irq_return to _start, in the first schedule()
> >of a new task perhaps, but thereafter I would expect
> >further jumps not to happen from irq_return, but rather
> >from _start. When we have x as a destination in line n, then
> >I would expect to have x as a source in n + 1.
> Agree with the opinion "irq_start" surprising users.
> However, I think it is not a better solution that uses a
> previous destination as a next source.
> Because, users want to know what happen in userspace and,
> do not want to know interrupts from kernel.
>
> I think the better solution is to implement the filter that
> eliminate the record including kernel functions from output.
Yep.
> For example, leading example will be filtered like this.
>
> _start+0x3 => _dl_start+0x0
>
> In the future, I think the solution is available that using BTS records
> with trace event like irq:irq_handler_entry to analyze interrupt.
> However, to do it, we need to fix perf.
Right.
> >
> >Also we are supposed to only trace BTS in userspace, but
> >perhaps, if we are interrupted, after the execution of the iret instruction,
> >BTS considers the following jump "iret -> interrupted inst" as a branch
> >in userspace. After all it makes sense, it is a jump in userspace.
> >
> >So BTS, because of the way it defines a jump inside userspace,
> >traces irq returns but not irq entries, that would explain the trace
> >you gave as an example.
> >
> >I suspect we want to filter irq returns. ie: if the source comes
> >from the kernel, then filter it by default. And then we can later
> >think about an option to enable interrupt return tracing if
> >people want them.
> Agree.
> I will implement the option that enable/disable the filter.
Cool, thanks!
On Thu, Mar 24, 2011 at 08:31:37PM +0900, Akihiro Nagai wrote:
> Hi,
>
> This patch series provides the commands 'perf branch record' and 'perf branch trace'
> version 3. 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 <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
> irq_return+0x0 => _start+0x0
> irq_return+0x0 => _start+0x0
> _start+0x3 => _dl_start+0x0
> irq_return+0x0 => _dl_start+0x0
> irq_return+0x0 => _dl_start+0x26
> irq_return+0x0 => _dl_start+0x2d
> _dl_start+0x71 => _dl_start+0x93
> _dl_start+0x97 => _dl_start+0x78
> ...
>
> This is the default behavior of 'perf branch trace'. It prints function+offset.
>
>
> Example2: 'perf branch -cas trace'
> command address function+offset
> ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806200b20 _start+0x0
You probably want to display the comm (and/or the pid/tid) only once. Those are not
going to change between the source and destination.
On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
> On 03/28/11 04:34, Akihiro Nagai wrote:
> >> from is sample->ip? to is sample->addr? In the above example
> >> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> >> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> > Yes.
> > In this example, resolved address is only sample->ip (branch from).
> > We need the resolved address of sample->addr (branch to) too, because
> > both of them are addresses of execution code.
>
> Ok, now I understand. In that case add conversion of sample->addr to
> symbols to perf-script.
I agree that we should rather use perf script for branch dumps.
Sorry Akihiro, I think we suggested you to create this dedicated
perf branch by the past. But then perf script became the vanilla dump
tool in the middle and it seems more suitable today.
We can still create a perf branch later in order to produce some more
advanced post-processing tools. But for sample dumps perf script (which starts
to show itself as a misnomer BTW) seems to be the right place.
So, in this context, if we have PERF_SAMPLE_ADDR, we are going to always
follow the ip with a "=>" and then resolve the address, etc...
Yeah it makes sense for this default mode. But what about when we'll want
a function graph kind of output? This will require a totally different
layout. Also PERF_SAMPLE_ADDR may be used for different context in the
future.
Perhaps we want a kind of per evsel callback that makes its own
interpretation of the pid/tid/dso/sym/etc... options asked by the
user?
But well, we can start simple and make and just do the => trick
if we have PERF_SAMPLE_ADDR and resolve addr if the user asked
the sym. Then when we have the graph output, have these per evsel
display callbacks.
On Fri, 2011-04-01 at 17:13 +0200, Frederic Weisbecker wrote:
> On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
> > On 03/28/11 04:34, Akihiro Nagai wrote:
> > >> from is sample->ip? to is sample->addr? In the above example
> > >> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> > >> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> > > Yes.
> > > In this example, resolved address is only sample->ip (branch from).
> > > We need the resolved address of sample->addr (branch to) too, because
> > > both of them are addresses of execution code.
> >
> > Ok, now I understand. In that case add conversion of sample->addr to
> > symbols to perf-script.
>
> I agree that we should rather use perf script for branch dumps.
> Sorry Akihiro, I think we suggested you to create this dedicated
> perf branch by the past. But then perf script became the vanilla dump
> tool in the middle and it seems more suitable today.
>
> We can still create a perf branch later in order to produce some more
> advanced post-processing tools. But for sample dumps perf script (which starts
> to show itself as a misnomer BTW) seems to be the right place.
Why do something with snakes if its perfectly possible to do in C ?
Em Fri, Apr 01, 2011 at 05:15:17PM +0200, Peter Zijlstra escreveu:
> On Fri, 2011-04-01 at 17:13 +0200, Frederic Weisbecker wrote:
> > On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
> > > On 03/28/11 04:34, Akihiro Nagai wrote:
> > > >> from is sample->ip? to is sample->addr? In the above example
> > > >> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> > > >> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> > > > Yes.
> > > > In this example, resolved address is only sample->ip (branch from).
> > > > We need the resolved address of sample->addr (branch to) too, because
> > > > both of them are addresses of execution code.
> > >
> > > Ok, now I understand. In that case add conversion of sample->addr to
> > > symbols to perf-script.
> >
> > I agree that we should rather use perf script for branch dumps.
> > Sorry Akihiro, I think we suggested you to create this dedicated
> > perf branch by the past. But then perf script became the vanilla dump
> > tool in the middle and it seems more suitable today.
> >
> > We can still create a perf branch later in order to produce some more
> > advanced post-processing tools. But for sample dumps perf script (which starts
> > to show itself as a misnomer BTW) seems to be the right place.
>
> Why do something with snakes if its perfectly possible to do in C ?
He is not meaning using python, hence the "misnomer" comment.
- Arnaldo
On 04/01/11 09:13, Frederic Weisbecker wrote:
> On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
>> On 03/28/11 04:34, Akihiro Nagai wrote:
>>>> from is sample->ip? to is sample->addr? In the above example
>>>> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
>>>> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
>>> Yes.
>>> In this example, resolved address is only sample->ip (branch from).
>>> We need the resolved address of sample->addr (branch to) too, because
>>> both of them are addresses of execution code.
>>
>> Ok, now I understand. In that case add conversion of sample->addr to
>> symbols to perf-script.
>
> I agree that we should rather use perf script for branch dumps.
> Sorry Akihiro, I think we suggested you to create this dedicated
> perf branch by the past. But then perf script became the vanilla dump
> tool in the middle and it seems more suitable today.
>
> We can still create a perf branch later in order to produce some more
> advanced post-processing tools. But for sample dumps perf script (which starts
> to show itself as a misnomer BTW) seems to be the right place.
perf-dump?
>
> So, in this context, if we have PERF_SAMPLE_ADDR, we are going to always
> follow the ip with a "=>" and then resolve the address, etc...
>
> Yeah it makes sense for this default mode. But what about when we'll want
> a function graph kind of output? This will require a totally different
> layout. Also PERF_SAMPLE_ADDR may be used for different context in the
> future.
>
> Perhaps we want a kind of per evsel callback that makes its own
> interpretation of the pid/tid/dso/sym/etc... options asked by the
> user?
The print addr function can take the evsel as an input. It includes the
event type which can be used to decide what the address means.
>
> But well, we can start simple and make and just do the => trick
> if we have PERF_SAMPLE_ADDR and resolve addr if the user asked
> the sym. Then when we have the graph output, have these per evsel
> display callbacks.
There is another email thread about page faults. The user wants sample
address resolved to symbols. I was going to look into it next week when
I get back from vacation.
On Fri, 2011-04-01 at 11:11 -0600, David Ahern wrote:
>
> There is another email thread about page faults. The user wants sample
> address resolved to symbols. I was going to look into it next week when
> I get back from vacation.
I know Anton played around with something like that a while back, maybe
he can share.
(2011/04/02 0:13), Frederic Weisbecker wrote:
> On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
>> On 03/28/11 04:34, Akihiro Nagai wrote:
>>>> from is sample->ip? to is sample->addr? In the above example
>>>> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
>>>> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
>>> Yes.
>>> In this example, resolved address is only sample->ip (branch from).
>>> We need the resolved address of sample->addr (branch to) too, because
>>> both of them are addresses of execution code.
>>
>> Ok, now I understand. In that case add conversion of sample->addr to
>> symbols to perf-script.
>
> I agree that we should rather use perf script for branch dumps.
> Sorry Akihiro, I think we suggested you to create this dedicated
> perf branch by the past. But then perf script became the vanilla dump
> tool in the middle and it seems more suitable today.
>
> We can still create a perf branch later in order to produce some more
> advanced post-processing tools. But for sample dumps perf script (which starts
> to show itself as a misnomer BTW) seems to be the right place.
Finally, I would like to create coverage test tools using BTS on perf.
I'm working on the project "Btrax" that is a coverage test tool using BTS.
The URL is: http://sourceforge.net/projects/btrax/
And, I would like to implement other functions on perf-branch too.
For example, call graph, source code browser like perf-annotate which
can show executed codes.
So, I wolud like to continue to develop perf-branch.
(2011/04/01 23:43), Frederic Weisbecker wrote:
> On Thu, Mar 24, 2011 at 08:31:37PM +0900, Akihiro Nagai wrote:
>> Hi,
>>
>> This patch series provides the commands 'perf branch record' and 'perf branch trace'
>> version 3. 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<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
>> irq_return+0x0 => _start+0x0
>> irq_return+0x0 => _start+0x0
>> _start+0x3 => _dl_start+0x0
>> irq_return+0x0 => _dl_start+0x0
>> irq_return+0x0 => _dl_start+0x26
>> irq_return+0x0 => _dl_start+0x2d
>> _dl_start+0x71 => _dl_start+0x93
>> _dl_start+0x97 => _dl_start+0x78
>> ...
>>
>> This is the default behavior of 'perf branch trace'. It prints function+offset.
>>
>>
>> Example2: 'perf branch -cas trace'
>> command address function+offset
>> ls 0xffffffff8146fe0e irq_return+0x0 => ls 0x0000003806200b20 _start+0x0
>
> You probably want to display the comm (and/or the pid/tid) only once. Those are not
> going to change between the source and destination.
Exactly, perf_sample has only one pid/tid field.
So, pid/tid and command don't change between source and destination.
I'll remove desitination's pid/tid and command fields.
Thank you.
On Fri, Apr 01, 2011 at 11:11:10AM -0600, David Ahern wrote:
>
>
> On 04/01/11 09:13, Frederic Weisbecker wrote:
> > On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
> >> On 03/28/11 04:34, Akihiro Nagai wrote:
> >>>> from is sample->ip? to is sample->addr? In the above example
> >>>> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> >>>> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> >>> Yes.
> >>> In this example, resolved address is only sample->ip (branch from).
> >>> We need the resolved address of sample->addr (branch to) too, because
> >>> both of them are addresses of execution code.
> >>
> >> Ok, now I understand. In that case add conversion of sample->addr to
> >> symbols to perf-script.
> >
> > I agree that we should rather use perf script for branch dumps.
> > Sorry Akihiro, I think we suggested you to create this dedicated
> > perf branch by the past. But then perf script became the vanilla dump
> > tool in the middle and it seems more suitable today.
> >
> > We can still create a perf branch later in order to produce some more
> > advanced post-processing tools. But for sample dumps perf script (which starts
> > to show itself as a misnomer BTW) seems to be the right place.
>
> perf-dump?
Yeah. We could make it an alias of perf-script.
> >
> > So, in this context, if we have PERF_SAMPLE_ADDR, we are going to always
> > follow the ip with a "=>" and then resolve the address, etc...
> >
> > Yeah it makes sense for this default mode. But what about when we'll want
> > a function graph kind of output? This will require a totally different
> > layout. Also PERF_SAMPLE_ADDR may be used for different context in the
> > future.
> >
> > Perhaps we want a kind of per evsel callback that makes its own
> > interpretation of the pid/tid/dso/sym/etc... options asked by the
> > user?
>
> The print addr function can take the evsel as an input. It includes the
> event type which can be used to decide what the address means.
Also yeah. But once we'll have the graph output, that may become
a real mess.
>
> >
> > But well, we can start simple and make and just do the => trick
> > if we have PERF_SAMPLE_ADDR and resolve addr if the user asked
> > the sym. Then when we have the graph output, have these per evsel
> > display callbacks.
>
> There is another email thread about page faults. The user wants sample
> address resolved to symbols. I was going to look into it next week when
> I get back from vacation.
What we seem to need for that is to bring a pagefault tracepoint. We had
propositions for that in the past, but work on this is in pause mode it
seems.
On Mon, Apr 04, 2011 at 07:00:40PM +0900, Akihiro Nagai wrote:
> (2011/04/02 0:13), Frederic Weisbecker wrote:
> >On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
> >>On 03/28/11 04:34, Akihiro Nagai wrote:
> >>>>from is sample->ip? to is sample->addr? In the above example
> >>>>0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
> >>>>resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
> >>>Yes.
> >>>In this example, resolved address is only sample->ip (branch from).
> >>>We need the resolved address of sample->addr (branch to) too, because
> >>>both of them are addresses of execution code.
> >>
> >>Ok, now I understand. In that case add conversion of sample->addr to
> >>symbols to perf-script.
> >
> >I agree that we should rather use perf script for branch dumps.
> >Sorry Akihiro, I think we suggested you to create this dedicated
> >perf branch by the past. But then perf script became the vanilla dump
> >tool in the middle and it seems more suitable today.
> >
> >We can still create a perf branch later in order to produce some more
> >advanced post-processing tools. But for sample dumps perf script (which starts
> >to show itself as a misnomer BTW) seems to be the right place.
> Finally, I would like to create coverage test tools using BTS on perf.
> I'm working on the project "Btrax" that is a coverage test tool using BTS.
> The URL is: http://sourceforge.net/projects/btrax/
Cool, what is this tool doing? How is it different from perf branch?
>
> And, I would like to implement other functions on perf-branch too.
> For example, call graph, source code browser like perf-annotate which
> can show executed codes.
> So, I wolud like to continue to develop perf-branch.
And you're very welcome to do so. Such features have a nice potential
I think.
Thanks.
Em Wed, Apr 06, 2011 at 02:15:07PM +0200, Frederic Weisbecker escreveu:
> On Fri, Apr 01, 2011 at 11:11:10AM -0600, David Ahern wrote:
> > On 04/01/11 09:13, Frederic Weisbecker wrote:
> > > But well, we can start simple and make and just do the => trick
> > > if we have PERF_SAMPLE_ADDR and resolve addr if the user asked
> > > the sym. Then when we have the graph output, have these per evsel
> > > display callbacks.
> > There is another email thread about page faults. The user wants sample
> > address resolved to symbols. I was going to look into it next week when
> > I get back from vacation.
> What we seem to need for that is to bring a pagefault tracepoint. We had
> propositions for that in the past, but work on this is in pause mode it
> seems.
Isn't there one in the 'tip/tmp.perf/trace' tmp branch? Lemme see...
Yeah, and it is even yours ;-)
commit 6a824e89c0dfe6bce3d7e85f987ec9c8e7304b34
Author: Frederic Weisbecker <[email protected]>
Date: Fri Nov 12 05:35:06 2010 +0100
perf, mm: Add fault tracing
Part of that are two modified patches from Jiri Olsa who added the
fault tracepoints. I had to split them in two tracepoints so that we get
the faults handling duration.
Originally-from: Frederic Weisbecker <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Can we dust this one off and get the ball rolling again?
- Arnaldo
On Wed, 2011-04-06 at 11:09 -0300, Arnaldo Carvalho de Melo wrote:
> > What we seem to need for that is to bring a pagefault tracepoint. We had
> > propositions for that in the past, but work on this is in pause mode it
> > seems.
Huh, whot? You can get that using PERF_COUNT_SW_PAGE_FAULT and
PERF_SAMPLE_ADDR.
On Wed, Apr 06, 2011 at 04:15:01PM +0200, Peter Zijlstra wrote:
> On Wed, 2011-04-06 at 11:09 -0300, Arnaldo Carvalho de Melo wrote:
> > > What we seem to need for that is to bring a pagefault tracepoint. We had
> > > propositions for that in the past, but work on this is in pause mode it
> > > seems.
>
> Huh, whot? You can get that using PERF_COUNT_SW_PAGE_FAULT and
> PERF_SAMPLE_ADDR.
Where are we doing that? I can't find the code that handles it.
On 04/06/11 08:30, Frederic Weisbecker wrote:
> On Wed, Apr 06, 2011 at 04:15:01PM +0200, Peter Zijlstra wrote:
>> On Wed, 2011-04-06 at 11:09 -0300, Arnaldo Carvalho de Melo wrote:
>>>> What we seem to need for that is to bring a pagefault tracepoint. We had
>>>> propositions for that in the past, but work on this is in pause mode it
>>>> seems.
>>
>> Huh, whot? You can get that using PERF_COUNT_SW_PAGE_FAULT and
>> PERF_SAMPLE_ADDR.
>
> Where are we doing that? I can't find the code that handles it.
That's what the other email thread was about, and the solution is just
that - perf record -e faults -c 1 -d ... Then it comes to dumping the
information. That's easy with the current perf-script.
On Wed, Apr 06, 2011 at 04:15:01PM +0200, Peter Zijlstra wrote:
> On Wed, 2011-04-06 at 11:09 -0300, Arnaldo Carvalho de Melo wrote:
> > > What we seem to need for that is to bring a pagefault tracepoint. We had
> > > propositions for that in the past, but work on this is in pause mode it
> > > seems.
>
> Huh, whot? You can get that using PERF_COUNT_SW_PAGE_FAULT and
> PERF_SAMPLE_ADDR.
Oops, right, found it.
On Wed, Apr 06, 2011 at 08:34:25AM -0600, David Ahern wrote:
>
>
> On 04/06/11 08:30, Frederic Weisbecker wrote:
> > On Wed, Apr 06, 2011 at 04:15:01PM +0200, Peter Zijlstra wrote:
> >> On Wed, 2011-04-06 at 11:09 -0300, Arnaldo Carvalho de Melo wrote:
> >>>> What we seem to need for that is to bring a pagefault tracepoint. We had
> >>>> propositions for that in the past, but work on this is in pause mode it
> >>>> seems.
> >>
> >> Huh, whot? You can get that using PERF_COUNT_SW_PAGE_FAULT and
> >> PERF_SAMPLE_ADDR.
> >
> > Where are we doing that? I can't find the code that handles it.
>
> That's what the other email thread was about, and the solution is just
> that - perf record -e faults -c 1 -d ... Then it comes to dumping the
> information. That's easy with the current perf-script.
Yeah indeed.
Thanks.
On Wed, Apr 06, 2011 at 11:09:58AM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Apr 06, 2011 at 02:15:07PM +0200, Frederic Weisbecker escreveu:
> > On Fri, Apr 01, 2011 at 11:11:10AM -0600, David Ahern wrote:
> > > On 04/01/11 09:13, Frederic Weisbecker wrote:
> > > > But well, we can start simple and make and just do the => trick
> > > > if we have PERF_SAMPLE_ADDR and resolve addr if the user asked
> > > > the sym. Then when we have the graph output, have these per evsel
> > > > display callbacks.
>
> > > There is another email thread about page faults. The user wants sample
> > > address resolved to symbols. I was going to look into it next week when
> > > I get back from vacation.
>
> > What we seem to need for that is to bring a pagefault tracepoint. We had
> > propositions for that in the past, but work on this is in pause mode it
> > seems.
>
> Isn't there one in the 'tip/tmp.perf/trace' tmp branch? Lemme see...
>
> Yeah, and it is even yours ;-)
>
> commit 6a824e89c0dfe6bce3d7e85f987ec9c8e7304b34
> Author: Frederic Weisbecker <[email protected]>
> Date: Fri Nov 12 05:35:06 2010 +0100
>
> perf, mm: Add fault tracing
>
> Part of that are two modified patches from Jiri Olsa who added the
> fault tracepoints. I had to split them in two tracepoints so that we get
> the faults handling duration.
>
> Originally-from: Frederic Weisbecker <[email protected]>
> Signed-off-by: Ingo Molnar <[email protected]>
> Signed-off-by: Thomas Gleixner <[email protected]>
That forgets to mention it's based on Jiri Olsa's patch :)
"tracing,mm - add kernel pagefault tracepoint for x86 & x86_64"
(Message id <[email protected]>).
>
> Can we dust this one off and get the ball rolling again?
I prefer someone comes with a real need before me or Jiri respin
that. There was perf trace but its development seems to be stale
now.
The page fault software event seem to be enough for basic
dump requests. I don't like software events and prefer tracepoints
in general but as long as the current implementation is enough
and people don't need to measure page fault servicing time,
write scripts or so, we are probably fine.
Em Wed, Apr 06, 2011 at 04:55:23PM +0200, Frederic Weisbecker escreveu:
> On Wed, Apr 06, 2011 at 11:09:58AM -0300, Arnaldo Carvalho de Melo wrote:
> > Isn't there one in the 'tip/tmp.perf/trace' tmp branch? Lemme see...
> >
> > Yeah, and it is even yours ;-)
> >
> > commit 6a824e89c0dfe6bce3d7e85f987ec9c8e7304b34
> > Author: Frederic Weisbecker <[email protected]>
> > Date: Fri Nov 12 05:35:06 2010 +0100
> >
> > perf, mm: Add fault tracing
> >
> > Part of that are two modified patches from Jiri Olsa who added the
> > fault tracepoints. I had to split them in two tracepoints so that we get
> > the faults handling duration.
> >
> > Originally-from: Frederic Weisbecker <[email protected]>
> > Signed-off-by: Ingo Molnar <[email protected]>
> > Signed-off-by: Thomas Gleixner <[email protected]>
>
> That forgets to mention it's based on Jiri Olsa's patch :)
>
> "tracing,mm - add kernel pagefault tracepoint for x86 & x86_64"
>
> (Message id <[email protected]>).
>
> >
> > Can we dust this one off and get the ball rolling again?
>
> I prefer someone comes with a real need before me or Jiri respin
> that. There was perf trace but its development seems to be stale
> now.
Yeah, I need to resume work on it, sidetracked now tho.
> The page fault software event seem to be enough for basic
> dump requests. I don't like software events and prefer tracepoints
> in general but as long as the current implementation is enough
> and people don't need to measure page fault servicing time,
> write scripts or so, we are probably fine.
- ARnaldo
(2011/04/06 21:52), Frederic Weisbecker wrote:
> On Mon, Apr 04, 2011 at 07:00:40PM +0900, Akihiro Nagai wrote:
>> (2011/04/02 0:13), Frederic Weisbecker wrote:
>>> On Mon, Mar 28, 2011 at 08:31:23AM -0600, David Ahern wrote:
>>>> On 03/28/11 04:34, Akihiro Nagai wrote:
>>>>> >from is sample->ip? to is sample->addr? In the above example
>>>>>> 0x39d3015260 is the value from sample->addr, 1526f is sample->ip which
>>>>>> resolves to _dl_next_ld_env_entry from /lib64/ld-2.13.so.
>>>>> Yes.
>>>>> In this example, resolved address is only sample->ip (branch from).
>>>>> We need the resolved address of sample->addr (branch to) too, because
>>>>> both of them are addresses of execution code.
>>>>
>>>> Ok, now I understand. In that case add conversion of sample->addr to
>>>> symbols to perf-script.
>>>
>>> I agree that we should rather use perf script for branch dumps.
>>> Sorry Akihiro, I think we suggested you to create this dedicated
>>> perf branch by the past. But then perf script became the vanilla dump
>>> tool in the middle and it seems more suitable today.
>>>
>>> We can still create a perf branch later in order to produce some more
>>> advanced post-processing tools. But for sample dumps perf script (which starts
>>> to show itself as a misnomer BTW) seems to be the right place.
>> Finally, I would like to create coverage test tools using BTS on perf.
>> I'm working on the project "Btrax" that is a coverage test tool using BTS.
>> The URL is: http://sourceforge.net/projects/btrax/
>
> Cool, what is this tool doing? How is it different from perf branch?
Btrax provides following functions by analyzing BTS logs.
1. Show executed/unexecuted codes with colors in HTML.
2. Calculate the ratio of executed codes and all codes of tracee programs.
Finally, I would like to add similar functions to Btrax to perf branch.
Because,
1. I think the combination of BTS and other perf functions realizes
cool stuff.
2. Currently, Btrax is out of tree. So, some people cannot use it
because of unsupported kernel versions. I want many people to use it.
>
>>
>> And, I would like to implement other functions on perf-branch too.
>> For example, call graph, source code browser like perf-annotate which
>> can show executed codes.
>> So, I wolud like to continue to develop perf-branch.
>
> And you're very welcome to do so. Such features have a nice potential
> I think.
Thank you. I believe it too.
>
> Thanks.