perf record: Fill .tid and .pid correctly when synthesizing events
PATCH 2/3 perf record: Fill .tid and .pid correctly when synthesizing events
Noticed when trying to record events for a firefox thread. We were synthesizing both .tid and .pid with the pid passed via --pid. Fix it by reading /proc/PID/status and getting the tgid to use in .pid, .tid gets the specified "pid".
Cc "H. Peter Anvin" <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Frédéric Weisbecker <[email protected]>
Cc Thomas Gleixner <[email protected]>
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>
--- tools/perf/builtin-record.c | 71 +++++++++++++++++++++++-------------------- 1 files changed, 38 insertions(+), 33 deletions(-)
tools/perf/builtin-record.c +38 -33
@@ -203,46 +203,48 @@ static void sig_atexit(void)kill (getpid (), signr); } -static void pid_synthesize_comm_event (pid_t pid,int full) +static pid_t pid_synthesize_comm_event (pid_t pid,int full) {struct comm_event comm_ev;char filename[PATH_MAX ];char bf[BUFSIZ ]; -int fd; -size_t size; -char *field, *sep; +FILE *fp; +size_t size =0 ;DIR *tasks;struct dirent dirent, *next; +pid_t tgid =0 ; -snprintf (filename,sizeof (filename),"/proc/%d/stat" , pid); +snprintf (filename,sizeof (filename),"/proc/%d/status" , pid); - fd =open (filename,O_RDONLY ); -if (fd <0 ) { + fp =fopen (filename,"r" ); +if (fd ==NULL ) {/* * We raced with a task exiting - just return: */ if (verbose)fprintf (stderr,"couldn't open %s\n" , filename); -return ; +return 0 ; } -if (read (fd, bf,sizeof (bf)) <0 ) { -fprintf (stderr,"couldn't read %s\n" , filename); -exit (EXIT_FAILURE ); - } -close (fd); -/* 9027 (cat) R 6747 9027 6747 34816 9027 ... */ memset (&comm_ev,0 ,sizeof (comm_ev)); - field =strchr (bf,'(' ); -if (field ==NULL ) - goto out_failure; - sep =strchr (++field,')' ); -if (sep ==NULL ) - goto out_failure; - size = sep - field; -memcpy (comm_ev.comm, field, size++); - - comm_ev.pid = pid; +while (!comm_ev.comm[0 ] || !comm_ev.pid) { +if (fgets (bf,sizeof (bf), fp) ==NULL ) + goto out_failure; + +if (memcmp (bf,"Name:" ,5 ) ==0 ) { +char *name = bf +5 ; +while (*name &&isspace (*name)) + ++name; + size =strlen (name) -1 ; +memcpy (comm_ev.comm, name, size++); + }else if (memcmp (bf,"Tgid:" ,5 ) ==0 ) { +char *tgids = bf +5 ; +while (*tgids &&isspace (*tgids)) + ++tgids; + tgid = comm_ev.pid =atoi (tgids); + } + } + comm_ev.header.type =PERF_EVENT_COMM ; size =ALIGN (size,sizeof (u64)); comm_ev.header.size =sizeof (comm_ev) - (sizeof (comm_ev.comm) - size);
@@ -251,7 +253,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full) comm_ev.tid = pid;write_output (&comm_ev, comm_ev.header.size); -return ; + goto out_fclose; }snprintf (filename,sizeof (filename),"/proc/%d/task" , pid);
@@ -268,7 +270,10 @@ static void pid_synthesize_comm_event(pid_t pid, int full)write_output (&comm_ev, comm_ev.header.size); }closedir (tasks); -return ; + +out_fclose: +fclose (fp); +return tgid; out_failure: fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
@@ -276,7 +281,7 @@ out_failure:exit (EXIT_FAILURE ); } -static void pid_synthesize_mmap_samples (pid_t pid) +static void pid_synthesize_mmap_samples (pid_t pid,pid_t tgid) {char filename[PATH_MAX ];FILE *fp;
@@ -328,7 +333,7 @@ static void pid_synthesize_mmap_samples(pid_t pid) mmap_ev.len -= mmap_ev.start; mmap_ev.header.size = (sizeof (mmap_ev) - (sizeof (mmap_ev.filename) - size)); - mmap_ev.pid = pid; + mmap_ev.pid = tgid; mmap_ev.tid = pid;write_output (&mmap_ev, mmap_ev.header.size);
@@ -347,14 +352,14 @@ static void synthesize_all(void)while (!readdir_r (proc, &dirent, &next) && next) {char *end; -pid_t pid; +pid_t pid, tgid; pid =strtol (dirent.d_name, &end,10 );if (*end)/* only interested in proper numerical dirents */ continue ; -pid_synthesize_comm_event (pid,1 ); -pid_synthesize_mmap_samples (pid); + tgid =pid_synthesize_comm_event (pid,1 ); +pid_synthesize_mmap_samples (pid, tgid); }closedir (proc);
@@ -567,8 +572,8 @@ static int __cmd_record(int argc, const char **argv)perf_header__write (header, output);if (!system_wide) { -pid_synthesize_comm_event (pid,0 ); -pid_synthesize_mmap_samples (pid); +pid_t tgid =pid_synthesize_comm_event (pid,0 ); +pid_synthesize_mmap_samples (pid, tgid); }else synthesize_all ();
Signature · 1 line
1.6.2.5