diff options
Diffstat (limited to 'tools/perf/util/trace-event-info.c')
-rw-r--r-- | tools/perf/util/trace-event-info.c | 90 |
1 files changed, 39 insertions, 51 deletions
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index af4b0573b37f..5ea8973ad331 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | #define _GNU_SOURCE | 21 | #define _GNU_SOURCE |
22 | #include <dirent.h> | 22 | #include <dirent.h> |
23 | #include <mntent.h> | ||
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | #include <stdlib.h> | 25 | #include <stdlib.h> |
25 | #include <string.h> | 26 | #include <string.h> |
@@ -33,10 +34,11 @@ | |||
33 | #include <ctype.h> | 34 | #include <ctype.h> |
34 | #include <errno.h> | 35 | #include <errno.h> |
35 | #include <stdbool.h> | 36 | #include <stdbool.h> |
37 | #include <linux/kernel.h> | ||
36 | 38 | ||
37 | #include "../perf.h" | 39 | #include "../perf.h" |
38 | #include "trace-event.h" | 40 | #include "trace-event.h" |
39 | 41 | #include "debugfs.h" | |
40 | 42 | ||
41 | #define VERSION "0.5" | 43 | #define VERSION "0.5" |
42 | 44 | ||
@@ -101,32 +103,12 @@ void *malloc_or_die(unsigned int size) | |||
101 | 103 | ||
102 | static const char *find_debugfs(void) | 104 | static const char *find_debugfs(void) |
103 | { | 105 | { |
104 | static char debugfs[MAX_PATH+1]; | 106 | const char *path = debugfs_mount(NULL); |
105 | static int debugfs_found; | ||
106 | char type[100]; | ||
107 | FILE *fp; | ||
108 | |||
109 | if (debugfs_found) | ||
110 | return debugfs; | ||
111 | |||
112 | if ((fp = fopen("/proc/mounts","r")) == NULL) | ||
113 | die("Can't open /proc/mounts for read"); | ||
114 | |||
115 | while (fscanf(fp, "%*s %" | ||
116 | STR(MAX_PATH) | ||
117 | "s %99s %*s %*d %*d\n", | ||
118 | debugfs, type) == 2) { | ||
119 | if (strcmp(type, "debugfs") == 0) | ||
120 | break; | ||
121 | } | ||
122 | fclose(fp); | ||
123 | |||
124 | if (strcmp(type, "debugfs") != 0) | ||
125 | die("debugfs not mounted, please mount"); | ||
126 | 107 | ||
127 | debugfs_found = 1; | 108 | if (!path) |
109 | die("Your kernel not support debugfs filesystem"); | ||
128 | 110 | ||
129 | return debugfs; | 111 | return path; |
130 | } | 112 | } |
131 | 113 | ||
132 | /* | 114 | /* |
@@ -271,6 +253,8 @@ static void read_header_files(void) | |||
271 | write_or_die("header_page", 12); | 253 | write_or_die("header_page", 12); |
272 | write_or_die(&size, 8); | 254 | write_or_die(&size, 8); |
273 | check_size = copy_file_fd(fd); | 255 | check_size = copy_file_fd(fd); |
256 | close(fd); | ||
257 | |||
274 | if (size != check_size) | 258 | if (size != check_size) |
275 | die("wrong size for '%s' size=%lld read=%lld", | 259 | die("wrong size for '%s' size=%lld read=%lld", |
276 | path, size, check_size); | 260 | path, size, check_size); |
@@ -289,6 +273,7 @@ static void read_header_files(void) | |||
289 | if (size != check_size) | 273 | if (size != check_size) |
290 | die("wrong size for '%s'", path); | 274 | die("wrong size for '%s'", path); |
291 | put_tracing_file(path); | 275 | put_tracing_file(path); |
276 | close(fd); | ||
292 | } | 277 | } |
293 | 278 | ||
294 | static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) | 279 | static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) |
@@ -317,7 +302,8 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
317 | die("can't read directory '%s'", sys); | 302 | die("can't read directory '%s'", sys); |
318 | 303 | ||
319 | while ((dent = readdir(dir))) { | 304 | while ((dent = readdir(dir))) { |
320 | if (strcmp(dent->d_name, ".") == 0 || | 305 | if (dent->d_type != DT_DIR || |
306 | strcmp(dent->d_name, ".") == 0 || | ||
321 | strcmp(dent->d_name, "..") == 0 || | 307 | strcmp(dent->d_name, "..") == 0 || |
322 | !name_in_tp_list(dent->d_name, tps)) | 308 | !name_in_tp_list(dent->d_name, tps)) |
323 | continue; | 309 | continue; |
@@ -334,7 +320,8 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
334 | 320 | ||
335 | rewinddir(dir); | 321 | rewinddir(dir); |
336 | while ((dent = readdir(dir))) { | 322 | while ((dent = readdir(dir))) { |
337 | if (strcmp(dent->d_name, ".") == 0 || | 323 | if (dent->d_type != DT_DIR || |
324 | strcmp(dent->d_name, ".") == 0 || | ||
338 | strcmp(dent->d_name, "..") == 0 || | 325 | strcmp(dent->d_name, "..") == 0 || |
339 | !name_in_tp_list(dent->d_name, tps)) | 326 | !name_in_tp_list(dent->d_name, tps)) |
340 | continue; | 327 | continue; |
@@ -353,6 +340,7 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
353 | 340 | ||
354 | free(format); | 341 | free(format); |
355 | } | 342 | } |
343 | closedir(dir); | ||
356 | } | 344 | } |
357 | 345 | ||
358 | static void read_ftrace_files(struct tracepoint_path *tps) | 346 | static void read_ftrace_files(struct tracepoint_path *tps) |
@@ -394,26 +382,21 @@ static void read_event_files(struct tracepoint_path *tps) | |||
394 | die("can't read directory '%s'", path); | 382 | die("can't read directory '%s'", path); |
395 | 383 | ||
396 | while ((dent = readdir(dir))) { | 384 | while ((dent = readdir(dir))) { |
397 | if (strcmp(dent->d_name, ".") == 0 || | 385 | if (dent->d_type != DT_DIR || |
386 | strcmp(dent->d_name, ".") == 0 || | ||
398 | strcmp(dent->d_name, "..") == 0 || | 387 | strcmp(dent->d_name, "..") == 0 || |
399 | strcmp(dent->d_name, "ftrace") == 0 || | 388 | strcmp(dent->d_name, "ftrace") == 0 || |
400 | !system_in_tp_list(dent->d_name, tps)) | 389 | !system_in_tp_list(dent->d_name, tps)) |
401 | continue; | 390 | continue; |
402 | sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2); | 391 | count++; |
403 | sprintf(sys, "%s/%s", path, dent->d_name); | ||
404 | ret = stat(sys, &st); | ||
405 | free(sys); | ||
406 | if (ret < 0) | ||
407 | continue; | ||
408 | if (S_ISDIR(st.st_mode)) | ||
409 | count++; | ||
410 | } | 392 | } |
411 | 393 | ||
412 | write_or_die(&count, 4); | 394 | write_or_die(&count, 4); |
413 | 395 | ||
414 | rewinddir(dir); | 396 | rewinddir(dir); |
415 | while ((dent = readdir(dir))) { | 397 | while ((dent = readdir(dir))) { |
416 | if (strcmp(dent->d_name, ".") == 0 || | 398 | if (dent->d_type != DT_DIR || |
399 | strcmp(dent->d_name, ".") == 0 || | ||
417 | strcmp(dent->d_name, "..") == 0 || | 400 | strcmp(dent->d_name, "..") == 0 || |
418 | strcmp(dent->d_name, "ftrace") == 0 || | 401 | strcmp(dent->d_name, "ftrace") == 0 || |
419 | !system_in_tp_list(dent->d_name, tps)) | 402 | !system_in_tp_list(dent->d_name, tps)) |
@@ -422,14 +405,13 @@ static void read_event_files(struct tracepoint_path *tps) | |||
422 | sprintf(sys, "%s/%s", path, dent->d_name); | 405 | sprintf(sys, "%s/%s", path, dent->d_name); |
423 | ret = stat(sys, &st); | 406 | ret = stat(sys, &st); |
424 | if (ret >= 0) { | 407 | if (ret >= 0) { |
425 | if (S_ISDIR(st.st_mode)) { | 408 | write_or_die(dent->d_name, strlen(dent->d_name) + 1); |
426 | write_or_die(dent->d_name, strlen(dent->d_name) + 1); | 409 | copy_event_system(sys, tps); |
427 | copy_event_system(sys, tps); | ||
428 | } | ||
429 | } | 410 | } |
430 | free(sys); | 411 | free(sys); |
431 | } | 412 | } |
432 | 413 | ||
414 | closedir(dir); | ||
433 | put_tracing_file(path); | 415 | put_tracing_file(path); |
434 | } | 416 | } |
435 | 417 | ||
@@ -483,27 +465,33 @@ static struct tracepoint_path * | |||
483 | get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events) | 465 | get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events) |
484 | { | 466 | { |
485 | struct tracepoint_path path, *ppath = &path; | 467 | struct tracepoint_path path, *ppath = &path; |
486 | int i; | 468 | int i, nr_tracepoints = 0; |
487 | 469 | ||
488 | for (i = 0; i < nb_events; i++) { | 470 | for (i = 0; i < nb_events; i++) { |
489 | if (pattrs[i].type != PERF_TYPE_TRACEPOINT) | 471 | if (pattrs[i].type != PERF_TYPE_TRACEPOINT) |
490 | continue; | 472 | continue; |
473 | ++nr_tracepoints; | ||
491 | ppath->next = tracepoint_id_to_path(pattrs[i].config); | 474 | ppath->next = tracepoint_id_to_path(pattrs[i].config); |
492 | if (!ppath->next) | 475 | if (!ppath->next) |
493 | die("%s\n", "No memory to alloc tracepoints list"); | 476 | die("%s\n", "No memory to alloc tracepoints list"); |
494 | ppath = ppath->next; | 477 | ppath = ppath->next; |
495 | } | 478 | } |
496 | 479 | ||
497 | return path.next; | 480 | return nr_tracepoints > 0 ? path.next : NULL; |
498 | } | 481 | } |
499 | void read_tracing_data(struct perf_event_attr *pattrs, int nb_events) | 482 | |
483 | int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events) | ||
500 | { | 484 | { |
501 | char buf[BUFSIZ]; | 485 | char buf[BUFSIZ]; |
502 | struct tracepoint_path *tps; | 486 | struct tracepoint_path *tps = get_tracepoints_path(pattrs, nb_events); |
487 | |||
488 | /* | ||
489 | * What? No tracepoints? No sense writing anything here, bail out. | ||
490 | */ | ||
491 | if (tps == NULL) | ||
492 | return -1; | ||
503 | 493 | ||
504 | output_fd = open(output_file, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0644); | 494 | output_fd = fd; |
505 | if (output_fd < 0) | ||
506 | die("creating file '%s'", output_file); | ||
507 | 495 | ||
508 | buf[0] = 23; | 496 | buf[0] = 23; |
509 | buf[1] = 8; | 497 | buf[1] = 8; |
@@ -527,14 +515,14 @@ void read_tracing_data(struct perf_event_attr *pattrs, int nb_events) | |||
527 | write_or_die(buf, 1); | 515 | write_or_die(buf, 1); |
528 | 516 | ||
529 | /* save page_size */ | 517 | /* save page_size */ |
530 | page_size = getpagesize(); | 518 | page_size = sysconf(_SC_PAGESIZE); |
531 | write_or_die(&page_size, 4); | 519 | write_or_die(&page_size, 4); |
532 | 520 | ||
533 | tps = get_tracepoints_path(pattrs, nb_events); | ||
534 | |||
535 | read_header_files(); | 521 | read_header_files(); |
536 | read_ftrace_files(tps); | 522 | read_ftrace_files(tps); |
537 | read_event_files(tps); | 523 | read_event_files(tps); |
538 | read_proc_kallsyms(); | 524 | read_proc_kallsyms(); |
539 | read_ftrace_printk(); | 525 | read_ftrace_printk(); |
526 | |||
527 | return 0; | ||
540 | } | 528 | } |