diff options
| -rw-r--r-- | parse-events.h | 2 | ||||
| -rw-r--r-- | trace-cmd.c | 25 | ||||
| -rw-r--r-- | trace-usage.c | 5 | ||||
| -rw-r--r-- | trace-util.c | 36 |
4 files changed, 58 insertions, 10 deletions
diff --git a/parse-events.h b/parse-events.h index c32d715..f5cab15 100644 --- a/parse-events.h +++ b/parse-events.h | |||
| @@ -402,6 +402,8 @@ struct pevent { | |||
| 402 | struct event_handler *handlers; | 402 | struct event_handler *handlers; |
| 403 | struct pevent_function_handler *func_handlers; | 403 | struct pevent_function_handler *func_handlers; |
| 404 | 404 | ||
| 405 | int parsing_failures; | ||
| 406 | |||
| 405 | /* cache */ | 407 | /* cache */ |
| 406 | struct event_format *last_event; | 408 | struct event_format *last_event; |
| 407 | }; | 409 | }; |
diff --git a/trace-cmd.c b/trace-cmd.c index bff5bbf..5cfd97f 100644 --- a/trace-cmd.c +++ b/trace-cmd.c | |||
| @@ -158,6 +158,31 @@ int main (int argc, char **argv) | |||
| 158 | } else if (strcmp(argv[1], "stack") == 0) { | 158 | } else if (strcmp(argv[1], "stack") == 0) { |
| 159 | trace_stack(argc, argv); | 159 | trace_stack(argc, argv); |
| 160 | exit(0); | 160 | exit(0); |
| 161 | } else if (strcmp(argv[1], "check-events") == 0) { | ||
| 162 | char *tracing; | ||
| 163 | int ret; | ||
| 164 | struct pevent *pevent = NULL; | ||
| 165 | |||
| 166 | tracing = tracecmd_find_tracing_dir(); | ||
| 167 | |||
| 168 | if (!tracing) { | ||
| 169 | printf("Can not find or mount tracing directory!\n" | ||
| 170 | "Either tracing is not configured for this " | ||
| 171 | "kernel\n" | ||
| 172 | "or you do not have the proper permissions to " | ||
| 173 | "mount the directory"); | ||
| 174 | exit(EINVAL); | ||
| 175 | } | ||
| 176 | |||
| 177 | ret = 0; | ||
| 178 | pevent = tracecmd_local_events(tracing); | ||
| 179 | if (!pevent) | ||
| 180 | exit(EINVAL); | ||
| 181 | if (pevent->parsing_failures) | ||
| 182 | ret = EINVAL; | ||
| 183 | pevent_free(pevent); | ||
| 184 | exit(ret); | ||
| 185 | |||
| 161 | } else if (strcmp(argv[1], "record") == 0 || | 186 | } else if (strcmp(argv[1], "record") == 0 || |
| 162 | strcmp(argv[1], "start") == 0 || | 187 | strcmp(argv[1], "start") == 0 || |
| 163 | strcmp(argv[1], "extract") == 0 || | 188 | strcmp(argv[1], "extract") == 0 || |
diff --git a/trace-usage.c b/trace-usage.c index 39c8fc1..58ef167 100644 --- a/trace-usage.c +++ b/trace-usage.c | |||
| @@ -150,6 +150,11 @@ static struct usage_help usage_help[] = { | |||
| 150 | " --reset reset the maximum stack found\n" | 150 | " --reset reset the maximum stack found\n" |
| 151 | }, | 151 | }, |
| 152 | { | 152 | { |
| 153 | "check-events", | ||
| 154 | "parse trace event formats", | ||
| 155 | " %s check-format\n" | ||
| 156 | }, | ||
| 157 | { | ||
| 153 | NULL, NULL, NULL | 158 | NULL, NULL, NULL |
| 154 | } | 159 | } |
| 155 | }; | 160 | }; |
diff --git a/trace-util.c b/trace-util.c index 674f37e..01894f8 100644 --- a/trace-util.c +++ b/trace-util.c | |||
| @@ -621,22 +621,22 @@ static int read_file(const char *file, char **buffer) | |||
| 621 | return len; | 621 | return len; |
| 622 | } | 622 | } |
| 623 | 623 | ||
| 624 | static void load_events(struct pevent *pevent, const char *system, | 624 | static int load_events(struct pevent *pevent, const char *system, |
| 625 | const char *sys_dir) | 625 | const char *sys_dir) |
| 626 | { | 626 | { |
| 627 | struct dirent *dent; | 627 | struct dirent *dent; |
| 628 | struct stat st; | 628 | struct stat st; |
| 629 | DIR *dir; | 629 | DIR *dir; |
| 630 | int len = 0; | 630 | int len = 0; |
| 631 | int ret; | 631 | int ret = 0, failure = 0; |
| 632 | 632 | ||
| 633 | ret = stat(sys_dir, &st); | 633 | ret = stat(sys_dir, &st); |
| 634 | if (ret < 0 || !S_ISDIR(st.st_mode)) | 634 | if (ret < 0 || !S_ISDIR(st.st_mode)) |
| 635 | return; | 635 | return EINVAL; |
| 636 | 636 | ||
| 637 | dir = opendir(sys_dir); | 637 | dir = opendir(sys_dir); |
| 638 | if (!dir) | 638 | if (!dir) |
| 639 | return; | 639 | return errno; |
| 640 | 640 | ||
| 641 | while ((dent = readdir(dir))) { | 641 | while ((dent = readdir(dir))) { |
| 642 | const char *name = dent->d_name; | 642 | const char *name = dent->d_name; |
| @@ -662,15 +662,18 @@ static void load_events(struct pevent *pevent, const char *system, | |||
| 662 | if (len < 0) | 662 | if (len < 0) |
| 663 | goto free_format; | 663 | goto free_format; |
| 664 | 664 | ||
| 665 | pevent_parse_event(pevent, buf, len, system); | 665 | ret = pevent_parse_event(pevent, buf, len, system); |
| 666 | free(buf); | 666 | free(buf); |
| 667 | free_format: | 667 | free_format: |
| 668 | free(format); | 668 | free(format); |
| 669 | free_event: | 669 | free_event: |
| 670 | free(event); | 670 | free(event); |
| 671 | if (ret) | ||
| 672 | failure = ret; | ||
| 671 | } | 673 | } |
| 672 | 674 | ||
| 673 | closedir(dir); | 675 | closedir(dir); |
| 676 | return failure; | ||
| 674 | } | 677 | } |
| 675 | 678 | ||
| 676 | static int read_header(struct pevent *pevent, const char *events_dir) | 679 | static int read_header(struct pevent *pevent, const char *events_dir) |
| @@ -715,7 +718,7 @@ struct pevent *tracecmd_local_events(const char *tracing_dir) | |||
| 715 | char *events_dir; | 718 | char *events_dir; |
| 716 | struct stat st; | 719 | struct stat st; |
| 717 | DIR *dir; | 720 | DIR *dir; |
| 718 | int ret; | 721 | int ret, failure = 0; |
| 719 | 722 | ||
| 720 | if (!tracing_dir) | 723 | if (!tracing_dir) |
| 721 | return NULL; | 724 | return NULL; |
| @@ -725,21 +728,28 @@ struct pevent *tracecmd_local_events(const char *tracing_dir) | |||
| 725 | return NULL; | 728 | return NULL; |
| 726 | 729 | ||
| 727 | ret = stat(events_dir, &st); | 730 | ret = stat(events_dir, &st); |
| 728 | if (ret < 0 || !S_ISDIR(st.st_mode)) | 731 | if (ret < 0 || !S_ISDIR(st.st_mode)) { |
| 732 | failure = 1; | ||
| 729 | goto out_free; | 733 | goto out_free; |
| 734 | } | ||
| 730 | 735 | ||
| 731 | dir = opendir(events_dir); | 736 | dir = opendir(events_dir); |
| 732 | if (!dir) | 737 | if (!dir) { |
| 738 | failure = 1; | ||
| 733 | goto out_free; | 739 | goto out_free; |
| 740 | } | ||
| 734 | 741 | ||
| 735 | pevent = pevent_alloc(); | 742 | pevent = pevent_alloc(); |
| 736 | if (!pevent) | 743 | if (!pevent) { |
| 744 | failure = 1; | ||
| 737 | goto out_free; | 745 | goto out_free; |
| 746 | } | ||
| 738 | 747 | ||
| 739 | ret = read_header(pevent, events_dir); | 748 | ret = read_header(pevent, events_dir); |
| 740 | if (ret < 0) { | 749 | if (ret < 0) { |
| 741 | pevent_free(pevent); | 750 | pevent_free(pevent); |
| 742 | pevent = NULL; | 751 | pevent = NULL; |
| 752 | failure = 1; | ||
| 743 | goto out_free; | 753 | goto out_free; |
| 744 | } | 754 | } |
| 745 | 755 | ||
| @@ -758,9 +768,12 @@ struct pevent *tracecmd_local_events(const char *tracing_dir) | |||
| 758 | continue; | 768 | continue; |
| 759 | } | 769 | } |
| 760 | 770 | ||
| 761 | load_events(pevent, name, sys); | 771 | ret = load_events(pevent, name, sys); |
| 762 | 772 | ||
| 763 | free(sys); | 773 | free(sys); |
| 774 | |||
| 775 | if (ret) | ||
| 776 | failure = 1; | ||
| 764 | } | 777 | } |
| 765 | 778 | ||
| 766 | closedir(dir); | 779 | closedir(dir); |
| @@ -768,6 +781,9 @@ struct pevent *tracecmd_local_events(const char *tracing_dir) | |||
| 768 | out_free: | 781 | out_free: |
| 769 | free(events_dir); | 782 | free(events_dir); |
| 770 | 783 | ||
| 784 | if (pevent) | ||
| 785 | pevent->parsing_failures = failure; | ||
| 786 | |||
| 771 | return pevent; | 787 | return pevent; |
| 772 | } | 788 | } |
| 773 | 789 | ||
