aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2009-08-11 15:22:00 -0400
committerIngo Molnar <mingo@elte.hu>2009-08-12 08:10:48 -0400
commit2a8083f063472f27c253545dd64e1a7bbbb1ab61 (patch)
tree78c20465589a102a4c28357c8207ea3366cfff69
parentf64ccccb8afa43abdd63fcbd230f818d6ea0883f (diff)
perf record: Fix .tid and .pid fill-in 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". Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Mike Galbraith <efault@gmx.de> LKML-Reference: <20090811192200.GF18061@ghostprotocols.net> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--tools/perf/builtin-record.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 0345aad8eba5..30b83def03d4 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -203,46 +203,48 @@ static void sig_atexit(void)
203 kill(getpid(), signr); 203 kill(getpid(), signr);
204} 204}
205 205
206static void pid_synthesize_comm_event(pid_t pid, int full) 206static pid_t pid_synthesize_comm_event(pid_t pid, int full)
207{ 207{
208 struct comm_event comm_ev; 208 struct comm_event comm_ev;
209 char filename[PATH_MAX]; 209 char filename[PATH_MAX];
210 char bf[BUFSIZ]; 210 char bf[BUFSIZ];
211 int fd; 211 FILE *fp;
212 size_t size; 212 size_t size = 0;
213 char *field, *sep;
214 DIR *tasks; 213 DIR *tasks;
215 struct dirent dirent, *next; 214 struct dirent dirent, *next;
215 pid_t tgid = 0;
216 216
217 snprintf(filename, sizeof(filename), "/proc/%d/stat", pid); 217 snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
218 218
219 fd = open(filename, O_RDONLY); 219 fp = fopen(filename, "r");
220 if (fd < 0) { 220 if (fd == NULL) {
221 /* 221 /*
222 * We raced with a task exiting - just return: 222 * We raced with a task exiting - just return:
223 */ 223 */
224 if (verbose) 224 if (verbose)
225 fprintf(stderr, "couldn't open %s\n", filename); 225 fprintf(stderr, "couldn't open %s\n", filename);
226 return; 226 return 0;
227 } 227 }
228 if (read(fd, bf, sizeof(bf)) < 0) {
229 fprintf(stderr, "couldn't read %s\n", filename);
230 exit(EXIT_FAILURE);
231 }
232 close(fd);
233 228
234 /* 9027 (cat) R 6747 9027 6747 34816 9027 ... */
235 memset(&comm_ev, 0, sizeof(comm_ev)); 229 memset(&comm_ev, 0, sizeof(comm_ev));
236 field = strchr(bf, '('); 230 while (!comm_ev.comm[0] || !comm_ev.pid) {
237 if (field == NULL) 231 if (fgets(bf, sizeof(bf), fp) == NULL)
238 goto out_failure; 232 goto out_failure;
239 sep = strchr(++field, ')'); 233
240 if (sep == NULL) 234 if (memcmp(bf, "Name:", 5) == 0) {
241 goto out_failure; 235 char *name = bf + 5;
242 size = sep - field; 236 while (*name && isspace(*name))
243 memcpy(comm_ev.comm, field, size++); 237 ++name;
244 238 size = strlen(name) - 1;
245 comm_ev.pid = pid; 239 memcpy(comm_ev.comm, name, size++);
240 } else if (memcmp(bf, "Tgid:", 5) == 0) {
241 char *tgids = bf + 5;
242 while (*tgids && isspace(*tgids))
243 ++tgids;
244 tgid = comm_ev.pid = atoi(tgids);
245 }
246 }
247
246 comm_ev.header.type = PERF_EVENT_COMM; 248 comm_ev.header.type = PERF_EVENT_COMM;
247 size = ALIGN(size, sizeof(u64)); 249 size = ALIGN(size, sizeof(u64));
248 comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size); 250 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)
251 comm_ev.tid = pid; 253 comm_ev.tid = pid;
252 254
253 write_output(&comm_ev, comm_ev.header.size); 255 write_output(&comm_ev, comm_ev.header.size);
254 return; 256 goto out_fclose;
255 } 257 }
256 258
257 snprintf(filename, sizeof(filename), "/proc/%d/task", pid); 259 snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
@@ -268,7 +270,10 @@ static void pid_synthesize_comm_event(pid_t pid, int full)
268 write_output(&comm_ev, comm_ev.header.size); 270 write_output(&comm_ev, comm_ev.header.size);
269 } 271 }
270 closedir(tasks); 272 closedir(tasks);
271 return; 273
274out_fclose:
275 fclose(fp);
276 return tgid;
272 277
273out_failure: 278out_failure:
274 fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n", 279 fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
@@ -276,7 +281,7 @@ out_failure:
276 exit(EXIT_FAILURE); 281 exit(EXIT_FAILURE);
277} 282}
278 283
279static void pid_synthesize_mmap_samples(pid_t pid) 284static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
280{ 285{
281 char filename[PATH_MAX]; 286 char filename[PATH_MAX];
282 FILE *fp; 287 FILE *fp;
@@ -328,7 +333,7 @@ static void pid_synthesize_mmap_samples(pid_t pid)
328 mmap_ev.len -= mmap_ev.start; 333 mmap_ev.len -= mmap_ev.start;
329 mmap_ev.header.size = (sizeof(mmap_ev) - 334 mmap_ev.header.size = (sizeof(mmap_ev) -
330 (sizeof(mmap_ev.filename) - size)); 335 (sizeof(mmap_ev.filename) - size));
331 mmap_ev.pid = pid; 336 mmap_ev.pid = tgid;
332 mmap_ev.tid = pid; 337 mmap_ev.tid = pid;
333 338
334 write_output(&mmap_ev, mmap_ev.header.size); 339 write_output(&mmap_ev, mmap_ev.header.size);
@@ -347,14 +352,14 @@ static void synthesize_all(void)
347 352
348 while (!readdir_r(proc, &dirent, &next) && next) { 353 while (!readdir_r(proc, &dirent, &next) && next) {
349 char *end; 354 char *end;
350 pid_t pid; 355 pid_t pid, tgid;
351 356
352 pid = strtol(dirent.d_name, &end, 10); 357 pid = strtol(dirent.d_name, &end, 10);
353 if (*end) /* only interested in proper numerical dirents */ 358 if (*end) /* only interested in proper numerical dirents */
354 continue; 359 continue;
355 360
356 pid_synthesize_comm_event(pid, 1); 361 tgid = pid_synthesize_comm_event(pid, 1);
357 pid_synthesize_mmap_samples(pid); 362 pid_synthesize_mmap_samples(pid, tgid);
358 } 363 }
359 364
360 closedir(proc); 365 closedir(proc);
@@ -567,8 +572,8 @@ static int __cmd_record(int argc, const char **argv)
567 perf_header__write(header, output); 572 perf_header__write(header, output);
568 573
569 if (!system_wide) { 574 if (!system_wide) {
570 pid_synthesize_comm_event(pid, 0); 575 pid_t tgid = pid_synthesize_comm_event(pid, 0);
571 pid_synthesize_mmap_samples(pid); 576 pid_synthesize_mmap_samples(pid, tgid);
572 } else 577 } else
573 synthesize_all(); 578 synthesize_all();
574 579