Line format follows tracepoints precedent:

 comm-pid [cpu] secs.usecs: event: IP symbol dso

Example:
    perf record -v -ga -e cs -c 1 -- sleep 5
    perf script

(Line lengths wrapped):

sshd-794 [000] 2572.863440: context-switches: ffffffff810355de \
    perf_event_task_sched_out ([kernel.kallsyms])
sshd-794 [000] 2572.863440: context-switches: ffffffff81382b01 \
    schedule ([kernel.kallsyms])
sshd-794 [000] 2572.863440: context-switches: ffffffff8138380a \
    schedule_hrtimeout_range_clock ([kernel.kallsyms])
sshd-794 [000] 2572.863440: context-switches: ffffffff813838e6 \
    schedule_hrtimeout_range ([kernel.kallsyms])
sshd-794 [000] 2572.863440: context-switches: ffffffff8110c55d \
    poll_schedule_timeout ([kernel.kallsyms])
sshd-794 [000] 2572.863440: context-switches: ffffffff8110cd84 \
    do_select ([kernel.kallsyms])

or 'perf script -G'

    swapper-0   [001] 2572.863188: context-switches: ffffffff810355de ...
       sshd-794 [000] 2572.863440: context-switches: ffffffff810355de ...
kworker/0:1-10  [000] 2572.863451: context-switches: ffffffff810355de ...

Signed-off-by: David Ahern <[email protected]>
---
 tools/perf/Documentation/perf-script.txt |   19 +++++
 tools/perf/builtin-script.c              |   32 +++++++++
 tools/perf/util/session.c                |  113 ++++++++++++++++++++++++++++++
 tools/perf/util/session.h                |    6 ++
 4 files changed, 170 insertions(+), 0 deletions(-)

diff --git a/tools/perf/Documentation/perf-script.txt 
b/tools/perf/Documentation/perf-script.txt
index 29ad942..99db652 100644
--- a/tools/perf/Documentation/perf-script.txt
+++ b/tools/perf/Documentation/perf-script.txt
@@ -112,6 +112,25 @@ OPTIONS
 --debug-mode::
         Do various checks like samples ordering and lost events.
 
+-k::
+--vmlinux=<file>::
+        vmlinux pathname
+
+--kallsyms=<file>::
+        kallsyms pathname
+
+--symfs=<directory>::
+        Look for files with symbols relative to this directory.
+
+-U::
+--show-unresolved::
+        Display all addresses including unresolved to a symbol.
+
+-G::
+--hide-call-graph::
+        Do not display call chain.
+
+--
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index f59d482..f1cad74b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -19,6 +19,8 @@ static bool                   debug_mode;
 static u64                     last_timestamp;
 static u64                     nr_unordered;
 extern const struct option     record_options[];
+static bool                    show_unresolved;
+static bool                    no_callchain;
 
 static void process_event(union perf_event *event,
                          struct perf_sample *sample,
@@ -57,6 +59,11 @@ static void process_event(union perf_event *event,
                print_tracepoint_event(sample->cpu, sample->raw_data,
                                       sample->raw_size, sample->time,
                                       thread->comm);
+       } else if ((attr->type == PERF_TYPE_SOFTWARE) ||
+                       ((attr->type == PERF_TYPE_HARDWARE) && 
+                        (attr->config == PERF_COUNT_HW_CPU_CYCLES))) {
+               perf_session__print_sample(event, sample, session, attr,
+                                          show_unresolved);
        } else {
                evname = __event_name(attr->type, attr->config);
                if (verbose)
@@ -130,7 +137,10 @@ static int process_sample_event(union perf_event *event,
 
 static struct perf_event_ops event_ops = {
        .sample          = process_sample_event,
+       .mmap            = perf_event__process_mmap,
        .comm            = perf_event__process_comm,
+       .exit            = perf_event__process_task,
+       .fork            = perf_event__process_task,
        .attr            = perf_event__process_attr,
        .event_type      = perf_event__process_event_type,
        .tracing_data    = perf_event__process_tracing_data,
@@ -620,6 +630,16 @@ static const struct option options[] = {
                    "input file name"),
        OPT_BOOLEAN('d', "debug-mode", &debug_mode,
                   "do various checks like samples ordering and lost events"),
+       OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
+                  "file", "vmlinux pathname"),
+       OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
+                  "file", "kallsyms pathname"),
+       OPT_BOOLEAN('G', "hide-call-graph", &no_callchain,
+                   "Do not display call chain"),
+       OPT_BOOLEAN('U', "show-unresolved", &show_unresolved,
+                   "Display all entries including unresolved to a symbol"),
+       OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
+                   "Look for files with symbols relative to this directory"),
 
        OPT_END()
 };
@@ -763,6 +783,18 @@ int cmd_script(int argc, const char **argv, const char 
*prefix __used)
                exit(-1);
        }
 
+       if (no_callchain)
+               symbol_conf.use_callchain = false;
+
+       else {
+               symbol_conf.use_callchain = true;
+               if (callchain_register_param(&callchain_param) < 0) {
+                       error("Can't register callchain params\n");
+                       err = -EINVAL;
+                       goto out;
+               }
+       }
+
        if (rec_script_path)
                script_path = rec_script_path;
        if (rep_script_path)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index a3a871f..a6c3a56 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -10,6 +10,7 @@
 #include "session.h"
 #include "sort.h"
 #include "util.h"
+#include "trace-event.h"
 
 static int perf_session__open(struct perf_session *self, bool force)
 {
@@ -1137,3 +1138,115 @@ size_t perf_session__fprintf_dsos_buildid(struct 
perf_session *self, FILE *fp,
        size_t ret = machine__fprintf_dsos_buildid(&self->host_machine, fp, 
with_hits);
        return ret + machines__fprintf_dsos_buildid(&self->machines, fp, 
with_hits);
 }
+
+static inline void print_one_symbol(const char *comm, pid_t pid, 
+                       u32 cpu, u64 secs, u64 usecs, const char *evname,
+                       u64 addr, const char *symname, const char *dsoname)
+{
+       printf("%16s-%-5d ", comm, pid);
+
+       if (cpu != (u32) -1)
+               printf("[%03d]", cpu);
+
+       printf(" %5lu.%06lu: %s: ", secs, usecs, evname);
+
+       printf("%16" PRIx64 " %s (%s)\n",
+              addr, symname, dsoname);
+
+       return;
+}
+
+void perf_session__print_sample(union perf_event *event,
+                               struct perf_sample *sample,
+                               struct perf_session *session,
+                               struct perf_event_attr *attr,
+                               bool show_unresolved)
+{
+       struct callchain_cursor_node *node, *prev;
+       struct addr_location al;
+       const char *evname = NULL;
+       const char *comm;
+       const char *symname, *dsoname;
+       u32 cpu = -1;
+       u64 secs = 0, usecs = 0;
+
+       if (perf_event__preprocess_sample(event, session, &al, sample,
+                                         NULL) < 0) {
+               error("problem processing %d event, skipping it.\n",
+                       event->header.type);
+               return;
+       }
+
+       if (session->sample_type & PERF_SAMPLE_TIME) {
+               u64 nsecs = sample->time;
+               secs = nsecs / NSECS_PER_SEC;
+               nsecs -= secs * NSECS_PER_SEC;
+               usecs = nsecs / NSECS_PER_USEC;
+       }
+
+       evname = __event_name(attr->type, attr->config);
+       if  (!evname)
+               evname = "(unknown)";
+
+       comm = al.thread->comm_set ? al.thread->comm : "-";
+
+       if (attr->sample_type & PERF_SAMPLE_CPU)
+               cpu = sample->cpu;
+
+       if (symbol_conf.use_callchain && sample->callchain) {
+
+               if (perf_session__resolve_callchain(session, al.thread,
+                                               sample->callchain, NULL) != 0) {
+                       if (verbose)
+                               error("Failed to resolve callchain. 
Skipping\n");
+                       return;
+               }
+
+               node = session->callchain_cursor.first;
+               if (!node)
+                       return;
+
+               while (node) {
+                       if (node->sym && node->sym->name)
+                               symname = node->sym->name;
+                       else if (show_unresolved)
+                               symname = "";
+                       else
+                               goto next;
+
+                       if (node->map && node->map->dso && node->map->dso->name)
+                               dsoname = node->map->dso->name;
+                       else if (show_unresolved)
+                               dsoname = "";
+                       else
+                               goto next;
+
+                       print_one_symbol(comm, al.thread->pid, cpu, secs, usecs,
+                                    evname, node->ip, symname, dsoname);
+
+next:
+                       prev = node;
+                       node = node->next;
+               }
+               /* put a spacer between samples when callchains are dumped */
+               printf("\n");
+
+       } else {
+               if (al.sym && al.sym->name)
+                       symname = al.sym->name;
+               else if (show_unresolved)
+                       symname = "";
+               else
+                       return;
+
+               if (al.map && al.map->dso && al.map->dso->name)
+                       dsoname = al.map->dso->name;
+               else if (show_unresolved)
+                       dsoname = "";
+               else
+                       return;
+
+               print_one_symbol(comm, al.thread->pid, cpu, secs, usecs,
+                            evname, al.addr, symname, dsoname);
+       }
+}
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 977b3a1..3827048 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -165,4 +165,10 @@ static inline int perf_session__parse_sample(struct 
perf_session *session,
                                        session->sample_id_all, sample);
 }
 
+void perf_session__print_sample(union perf_event *event,
+                               struct perf_sample *sample,
+                               struct perf_session *session,
+                               struct perf_event_attr *attr,
+                               bool show_unresolved);
+
 #endif /* __PERF_SESSION_H */
-- 
1.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-perf-users" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to