Messages in this thread Patch in this message | | | From | David Ahern <> | Subject | [PATCH] perf tool: Fix ppid for synthesized fork events | Date | Thu, 19 Mar 2015 11:41:15 -0600 |
| |
363b785f38 added synthesized fork events and set a thread's parent id to itself. Since we are already processing /proc/<pid>/status the ppid can be determined properly. Make it so.
Signed-off-by: David Ahern <dsahern@gmail.com> Cc: Don Zickus <dzickus@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> --- tools/perf/util/event.c | 94 ++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 41 deletions(-)
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index d5efa5092ce6..62bf7b71ac7b 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -49,23 +49,26 @@ static struct perf_sample synth_sample = { .period = 1, }; -static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) +static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, + pid_t *tgid, pid_t *ppid) { char filename[PATH_MAX]; char bf[BUFSIZ]; FILE *fp; size_t size = 0; - pid_t tgid = -1; + + *tgid = -1; + *ppid = -1; snprintf(filename, sizeof(filename), "/proc/%d/status", pid); fp = fopen(filename, "r"); if (fp == NULL) { pr_debug("couldn't open %s\n", filename); - return 0; + return -1; } - while (!comm[0] || (tgid < 0)) { + while (!comm[0] || (*tgid < 0) || (*ppid < 0)) { if (fgets(bf, sizeof(bf), fp) == NULL) { pr_warning("couldn't get COMM and pgid, malformed %s\n", filename); @@ -86,33 +89,45 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) char *tgids = bf + 5; while (*tgids && isspace(*tgids)) ++tgids; - tgid = atoi(tgids); + *tgid = atoi(tgids); + + } else if (memcmp(bf, "PPid:", 5) == 0) { + char *ppids = bf + 5; + + while (*ppids && isspace(*ppids)) + ++ppids; + *ppid = atoi(ppids); } } fclose(fp); - return tgid; + return 0; } -static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, - struct machine *machine) +static int perf_event__prepare_comm(union perf_event *event, pid_t pid, + struct machine *machine, + pid_t *tgid, pid_t *ppid) { size_t size; - pid_t tgid; + + *ppid = -1; memset(&event->comm, 0, sizeof(event->comm)); - if (machine__is_host(machine)) - tgid = perf_event__get_comm_tgid(pid, event->comm.comm, - sizeof(event->comm.comm)); - else - tgid = machine->pid; + if (machine__is_host(machine)) { + if (perf_event__get_comm_ids(pid, event->comm.comm, + sizeof(event->comm.comm), + tgid, ppid) != 0) { + return -1; + } + } else + *tgid = machine->pid; - if (tgid < 0) - goto out; + if (*tgid < 0) + return -1; - event->comm.pid = tgid; + event->comm.pid = *tgid; event->comm.header.type = PERF_RECORD_COMM; size = strlen(event->comm.comm) + 1; @@ -122,36 +137,35 @@ static pid_t perf_event__prepare_comm(union perf_event *event, pid_t pid, (sizeof(event->comm.comm) - size) + machine->id_hdr_size); event->comm.tid = pid; -out: - return tgid; + + return 0; } -static pid_t perf_event__synthesize_comm(struct perf_tool *tool, - union perf_event *event, pid_t pid, - perf_event__handler_t process, - struct machine *machine) +static int perf_event__synthesize_comm(struct perf_tool *tool, + union perf_event *event, pid_t pid, + perf_event__handler_t process, + struct machine *machine, + pid_t *tgid, pid_t *ppid) { - pid_t tgid = perf_event__prepare_comm(event, pid, machine); - - if (tgid == -1) - goto out; + if (perf_event__prepare_comm(event, pid, machine, tgid, ppid) != 0) + return -1; if (process(tool, event, &synth_sample, machine) != 0) return -1; -out: - return tgid; + return 0; } static int perf_event__synthesize_fork(struct perf_tool *tool, - union perf_event *event, pid_t pid, - pid_t tgid, perf_event__handler_t process, + union perf_event *event, + pid_t pid, pid_t tgid, pid_t ppid, + perf_event__handler_t process, struct machine *machine) { memset(&event->fork, 0, sizeof(event->fork) + machine->id_hdr_size); - event->fork.ppid = tgid; - event->fork.ptid = tgid; + event->fork.ppid = ppid; + event->fork.ptid = ppid; event->fork.pid = tgid; event->fork.tid = pid; event->fork.header.type = PERF_RECORD_FORK; @@ -343,14 +357,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, char filename[PATH_MAX]; DIR *tasks; struct dirent dirent, *next; - pid_t tgid; + pid_t tgid, ppid; /* special case: only send one comm event using passed in pid */ if (!full) { - tgid = perf_event__synthesize_comm(tool, comm_event, pid, - process, machine); - - if (tgid == -1) + if (perf_event__synthesize_comm(tool, comm_event, pid, + process, machine, &tgid, &ppid) != 0) return -1; return perf_event__synthesize_mmap_events(tool, mmap_event, pid, tgid, @@ -378,12 +390,12 @@ static int __event__synthesize_thread(union perf_event *comm_event, if (*end) continue; - tgid = perf_event__prepare_comm(comm_event, _pid, machine); - if (tgid == -1) + if (perf_event__prepare_comm(comm_event, _pid, machine, + &tgid, &ppid) != 0) return -1; if (perf_event__synthesize_fork(tool, fork_event, _pid, tgid, - process, machine) < 0) + ppid, process, machine) < 0) return -1; /* * Send the prepared comm event -- 2.2.1
| |