Messages in this thread | | | Date | Tue, 31 Mar 2015 12:23:07 -0400 | From | Don Zickus <> | Subject | Re: [PATCH v3 2/2] perf tool: Fix ppid for synthesized fork events |
| |
On Mon, Mar 30, 2015 at 02:35:58PM -0600, David Ahern wrote: > 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.
Acked-by: Don Zickus <dzickus@redhat.com>
> > Signed-off-by: David Ahern <dsahern@gmail.com> > Cc: Don Zickus <dzickus@redhat.com> > Cc: Joe Mario <jmario@redhat.com> > Cc: Jiri Olsa <jolsa@redhat.com> > --- > v3 > - removed isspace and newline checks; added brackets per Arnaldo's comments > > v2: > - removed changes to function signature for perf_event__synthesize_comm as > noted by Jiri > > tools/perf/util/event.c | 83 +++++++++++++++++++++++++++++-------------------- > 1 file changed, 50 insertions(+), 33 deletions(-) > > diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c > index 023dd3548a94..5516236df6ab 100644 > --- a/tools/perf/util/event.c > +++ b/tools/perf/util/event.c > @@ -51,29 +51,32 @@ static struct perf_sample synth_sample = { > > /* > * Assumes that the first 4095 bytes of /proc/pid/stat contains > - * the comm and tgid. > + * the comm, tgid and ppid. > */ > -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[4096]; > int fd; > size_t size = 0, n; > - pid_t tgid = -1; > - char *nl, *name, *tgids; > + char *nl, *name, *tgids, *ppids; > + > + *tgid = -1; > + *ppid = -1; > > snprintf(filename, sizeof(filename), "/proc/%d/status", pid); > > fd = open(filename, O_RDONLY); > if (fd < 0) { > pr_debug("couldn't open %s\n", filename); > - return 0; > + return -1; > } > > n = read(fd, bf, sizeof(bf) - 1); > close(fd); > if (n <= 0) { > - pr_warning("Couldn't get COMM and tgid for pid %d\n", > + pr_warning("Couldn't get COMM, tigd and ppid for pid %d\n", > pid); > return -1; > } > @@ -81,6 +84,7 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > > name = strstr(bf, "Name:"); > tgids = strstr(bf, "Tgid:"); > + ppids = strstr(bf, "PPid:"); > > if (name) { > name += 5; /* strlen("Name:") */ > @@ -103,32 +107,45 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len) > > if (tgids) { > tgids += 5; /* strlen("Tgid:") */ > - tgid = atoi(tgids); > + *tgid = atoi(tgids); > } else { > pr_debug("Tgid: string not found for pid %d\n", pid); > } > > - return tgid; > + if (ppids) { > + ppids += 5; /* strlen("PPid:") */ > + *ppid = atoi(ppids); > + } else { > + pr_debug("PPid: string not found for pid %d\n", pid); > + } > + > + 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; > @@ -138,8 +155,8 @@ 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, > @@ -147,27 +164,27 @@ static pid_t perf_event__synthesize_comm(struct perf_tool *tool, > perf_event__handler_t process, > struct machine *machine) > { > - pid_t tgid = perf_event__prepare_comm(event, pid, machine); > + pid_t tgid, ppid; > > - 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; > } > > 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; > @@ -359,7 +376,7 @@ 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) { > @@ -394,12 +411,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 >
| |