]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
perf util: Save pid-cmdline mapping into tracing header
authorNamhyung Kim <namhyung.kim@lge.com>
Thu, 11 Apr 2013 08:25:04 +0000 (17:25 +0900)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Thu, 26 Jan 2017 14:42:59 +0000 (11:42 -0300)
Current trace info data lacks the saved cmdline mapping which is needed
for pevent to find out the comm of a task.  Add this and bump up the
version number so that perf can determine its presence when reading.

This is mostly corresponding to trace.dat file version 6, but still
lacks 4 byte of number of cpus, and 10 bytes of type string - and I
think we don't need those anyway.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jeremy Eder <jeder@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>,
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
[ Change version test from == to >= ]
Link: http://lkml.kernel.org/n/tip-vaooqpxsikxbb3359p0corcb@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event-read.c
tools/perf/util/trace-event.h

index d995743cb673e77524f0cd539d0cf0042b3fc363..ceb0e27202237568c1c41725af71cc2e1b202dc0 100644 (file)
@@ -42,7 +42,7 @@
 #include "evsel.h"
 #include "debug.h"
 
-#define VERSION "0.5"
+#define VERSION "0.6"
 
 static int output_fd;
 
@@ -379,6 +379,34 @@ static int record_ftrace_printk(void)
        return err;
 }
 
+static int record_saved_cmdline(void)
+{
+       unsigned int size;
+       char *path;
+       struct stat st;
+       int ret, err = 0;
+
+       path = get_tracing_file("saved_cmdlines");
+       if (!path) {
+               pr_debug("can't get tracing/saved_cmdline");
+               return -ENOMEM;
+       }
+
+       ret = stat(path, &st);
+       if (ret < 0) {
+               /* not found */
+               size = 0;
+               if (write(output_fd, &size, 8) != 8)
+                       err = -EIO;
+               goto out;
+       }
+       err = record_file(path, 8);
+
+out:
+       put_tracing_file(path);
+       return err;
+}
+
 static void
 put_tracepoints_path(struct tracepoint_path *tps)
 {
@@ -539,6 +567,9 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
        if (err)
                goto out;
        err = record_ftrace_printk();
+       if (err)
+               goto out;
+       err = record_saved_cmdline();
 
 out:
        /*
index 33b52eaa39db293b0de4d41c7312f88b39a2c4e2..de0078e21408149fcf1105e357a3d829343233ff 100644 (file)
@@ -160,6 +160,23 @@ void parse_ftrace_printk(struct pevent *pevent,
        }
 }
 
+void parse_saved_cmdline(struct pevent *pevent,
+                        char *file, unsigned int size __maybe_unused)
+{
+       char *comm;
+       char *line;
+       char *next = NULL;
+       int pid;
+
+       line = strtok_r(file, "\n", &next);
+       while (line) {
+               sscanf(line, "%d %ms", &pid, &comm);
+               pevent_register_comm(pevent, comm, pid);
+               free(comm);
+               line = strtok_r(NULL, "\n", &next);
+       }
+}
+
 int parse_ftrace_file(struct pevent *pevent, char *buf, unsigned long size)
 {
        return pevent_parse_event(pevent, buf, size, "ftrace");
index b67a0ccf5ab94991653f6666dd4766864d282b3b..61c7162c31c7431106ea9b00d37083c206eca4c4 100644 (file)
@@ -341,6 +341,31 @@ static int read_event_files(struct pevent *pevent)
        return 0;
 }
 
+static int read_saved_cmdline(struct pevent *pevent)
+{
+       unsigned long long size;
+       char *buf;
+
+       /* it can have 0 size */
+       size = read8(pevent);
+       if (!size)
+               return 0;
+
+       buf = malloc(size + 1);
+       if (buf == NULL)
+               return -1;
+
+       if (do_read(buf, size) < 0) {
+               free(buf);
+               return -1;
+       }
+
+       parse_saved_cmdline(pevent, buf, size);
+
+       free(buf);
+       return 0;
+}
+
 ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
 {
        char buf[BUFSIZ];
@@ -379,10 +404,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
                return -1;
        if (show_version)
                printf("version = %s\n", version);
-       free(version);
 
-       if (do_read(buf, 1) < 0)
+       if (do_read(buf, 1) < 0) {
+               free(version);
                return -1;
+       }
        file_bigendian = buf[0];
        host_bigendian = bigendian();
 
@@ -423,6 +449,11 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
        err = read_ftrace_printk(pevent);
        if (err)
                goto out;
+       if (atof(version) >= 0.6) {
+               err = read_saved_cmdline(pevent);
+               if (err)
+                       goto out;
+       }
 
        size = trace_data_size;
        repipe = false;
@@ -438,5 +469,6 @@ ssize_t trace_report(int fd, struct trace_event *tevent, bool __repipe)
 out:
        if (pevent)
                trace_event__cleanup(tevent);
+       free(version);
        return size;
 }
index b0af9c81bb0df292ff798b9012971ee347b2dc1f..1fbc044f9eb039c84d5fe76416575c2f7753a43b 100644 (file)
@@ -42,6 +42,7 @@ raw_field_value(struct event_format *event, const char *name, void *data);
 
 void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size);
 void parse_ftrace_printk(struct pevent *pevent, char *file, unsigned int size);
+void parse_saved_cmdline(struct pevent *pevent, char *file, unsigned int size);
 
 ssize_t trace_report(int fd, struct trace_event *tevent, bool repipe);