diff options
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 104 |
1 files changed, 81 insertions, 23 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b7c2c491f61e..b5b4d806ffa2 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -4686,9 +4686,8 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event) | |||
4686 | * | 4686 | * |
4687 | * /sys/kernel/debug/tracing/events/.../.../format | 4687 | * /sys/kernel/debug/tracing/events/.../.../format |
4688 | */ | 4688 | */ |
4689 | int pevent_parse_event(struct pevent *pevent, | 4689 | enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, |
4690 | const char *buf, unsigned long size, | 4690 | unsigned long size, const char *sys) |
4691 | const char *sys) | ||
4692 | { | 4691 | { |
4693 | struct event_format *event; | 4692 | struct event_format *event; |
4694 | int ret; | 4693 | int ret; |
@@ -4697,17 +4696,16 @@ int pevent_parse_event(struct pevent *pevent, | |||
4697 | 4696 | ||
4698 | event = alloc_event(); | 4697 | event = alloc_event(); |
4699 | if (!event) | 4698 | if (!event) |
4700 | return -ENOMEM; | 4699 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; |
4701 | 4700 | ||
4702 | event->name = event_read_name(); | 4701 | event->name = event_read_name(); |
4703 | if (!event->name) { | 4702 | if (!event->name) { |
4704 | /* Bad event? */ | 4703 | /* Bad event? */ |
4705 | free(event); | 4704 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; |
4706 | return -1; | 4705 | goto event_alloc_failed; |
4707 | } | 4706 | } |
4708 | 4707 | ||
4709 | if (strcmp(sys, "ftrace") == 0) { | 4708 | if (strcmp(sys, "ftrace") == 0) { |
4710 | |||
4711 | event->flags |= EVENT_FL_ISFTRACE; | 4709 | event->flags |= EVENT_FL_ISFTRACE; |
4712 | 4710 | ||
4713 | if (strcmp(event->name, "bprint") == 0) | 4711 | if (strcmp(event->name, "bprint") == 0) |
@@ -4715,20 +4713,28 @@ int pevent_parse_event(struct pevent *pevent, | |||
4715 | } | 4713 | } |
4716 | 4714 | ||
4717 | event->id = event_read_id(); | 4715 | event->id = event_read_id(); |
4718 | if (event->id < 0) | 4716 | if (event->id < 0) { |
4719 | die("failed to read event id"); | 4717 | ret = PEVENT_ERRNO__READ_ID_FAILED; |
4718 | /* | ||
4719 | * This isn't an allocation error actually. | ||
4720 | * But as the ID is critical, just bail out. | ||
4721 | */ | ||
4722 | goto event_alloc_failed; | ||
4723 | } | ||
4720 | 4724 | ||
4721 | event->system = strdup(sys); | 4725 | event->system = strdup(sys); |
4722 | if (!event->system) | 4726 | if (!event->system) { |
4723 | die("failed to allocate system"); | 4727 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; |
4728 | goto event_alloc_failed; | ||
4729 | } | ||
4724 | 4730 | ||
4725 | /* Add pevent to event so that it can be referenced */ | 4731 | /* Add pevent to event so that it can be referenced */ |
4726 | event->pevent = pevent; | 4732 | event->pevent = pevent; |
4727 | 4733 | ||
4728 | ret = event_read_format(event); | 4734 | ret = event_read_format(event); |
4729 | if (ret < 0) { | 4735 | if (ret < 0) { |
4730 | do_warning("failed to read event format for %s", event->name); | 4736 | ret = PEVENT_ERRNO__READ_FORMAT_FAILED; |
4731 | goto event_failed; | 4737 | goto event_parse_failed; |
4732 | } | 4738 | } |
4733 | 4739 | ||
4734 | /* | 4740 | /* |
@@ -4740,10 +4746,9 @@ int pevent_parse_event(struct pevent *pevent, | |||
4740 | 4746 | ||
4741 | ret = event_read_print(event); | 4747 | ret = event_read_print(event); |
4742 | if (ret < 0) { | 4748 | if (ret < 0) { |
4743 | do_warning("failed to read event print fmt for %s", | ||
4744 | event->name); | ||
4745 | show_warning = 1; | 4749 | show_warning = 1; |
4746 | goto event_failed; | 4750 | ret = PEVENT_ERRNO__READ_PRINT_FAILED; |
4751 | goto event_parse_failed; | ||
4747 | } | 4752 | } |
4748 | show_warning = 1; | 4753 | show_warning = 1; |
4749 | 4754 | ||
@@ -4754,20 +4759,19 @@ int pevent_parse_event(struct pevent *pevent, | |||
4754 | struct print_arg *arg, **list; | 4759 | struct print_arg *arg, **list; |
4755 | 4760 | ||
4756 | /* old ftrace had no args */ | 4761 | /* old ftrace had no args */ |
4757 | |||
4758 | list = &event->print_fmt.args; | 4762 | list = &event->print_fmt.args; |
4759 | for (field = event->format.fields; field; field = field->next) { | 4763 | for (field = event->format.fields; field; field = field->next) { |
4760 | arg = alloc_arg(); | 4764 | arg = alloc_arg(); |
4761 | *list = arg; | ||
4762 | list = &arg->next; | ||
4763 | arg->type = PRINT_FIELD; | 4765 | arg->type = PRINT_FIELD; |
4764 | arg->field.name = strdup(field->name); | 4766 | arg->field.name = strdup(field->name); |
4765 | if (!arg->field.name) { | 4767 | if (!arg->field.name) { |
4766 | do_warning("failed to allocate field name"); | ||
4767 | event->flags |= EVENT_FL_FAILED; | 4768 | event->flags |= EVENT_FL_FAILED; |
4768 | return -1; | 4769 | free_arg(arg); |
4770 | return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; | ||
4769 | } | 4771 | } |
4770 | arg->field.field = field; | 4772 | arg->field.field = field; |
4773 | *list = arg; | ||
4774 | list = &arg->next; | ||
4771 | } | 4775 | } |
4772 | return 0; | 4776 | return 0; |
4773 | } | 4777 | } |
@@ -4778,11 +4782,65 @@ int pevent_parse_event(struct pevent *pevent, | |||
4778 | 4782 | ||
4779 | return 0; | 4783 | return 0; |
4780 | 4784 | ||
4781 | event_failed: | 4785 | event_parse_failed: |
4782 | event->flags |= EVENT_FL_FAILED; | 4786 | event->flags |= EVENT_FL_FAILED; |
4783 | /* still add it even if it failed */ | 4787 | /* still add it even if it failed */ |
4784 | add_event(pevent, event); | 4788 | add_event(pevent, event); |
4785 | return -1; | 4789 | return ret; |
4790 | |||
4791 | event_alloc_failed: | ||
4792 | free(event->system); | ||
4793 | free(event->name); | ||
4794 | free(event); | ||
4795 | return ret; | ||
4796 | } | ||
4797 | |||
4798 | #undef _PE | ||
4799 | #define _PE(code, str) str | ||
4800 | static const char * const pevent_error_str[] = { | ||
4801 | PEVENT_ERRORS | ||
4802 | }; | ||
4803 | #undef _PE | ||
4804 | |||
4805 | int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, | ||
4806 | char *buf, size_t buflen) | ||
4807 | { | ||
4808 | int idx; | ||
4809 | const char *msg; | ||
4810 | |||
4811 | if (errnum >= 0) { | ||
4812 | msg = strerror_r(errnum, buf, buflen); | ||
4813 | if (msg != buf) { | ||
4814 | size_t len = strlen(msg); | ||
4815 | char *c = mempcpy(buf, msg, min(buflen-1, len)); | ||
4816 | *c = '\0'; | ||
4817 | } | ||
4818 | return 0; | ||
4819 | } | ||
4820 | |||
4821 | if (errnum <= __PEVENT_ERRNO__START || | ||
4822 | errnum >= __PEVENT_ERRNO__END) | ||
4823 | return -1; | ||
4824 | |||
4825 | idx = errnum - __PEVENT_ERRNO__START - 1; | ||
4826 | msg = pevent_error_str[idx]; | ||
4827 | |||
4828 | switch (errnum) { | ||
4829 | case PEVENT_ERRNO__MEM_ALLOC_FAILED: | ||
4830 | case PEVENT_ERRNO__PARSE_EVENT_FAILED: | ||
4831 | case PEVENT_ERRNO__READ_ID_FAILED: | ||
4832 | case PEVENT_ERRNO__READ_FORMAT_FAILED: | ||
4833 | case PEVENT_ERRNO__READ_PRINT_FAILED: | ||
4834 | case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: | ||
4835 | snprintf(buf, buflen, "%s", msg); | ||
4836 | break; | ||
4837 | |||
4838 | default: | ||
4839 | /* cannot reach here */ | ||
4840 | break; | ||
4841 | } | ||
4842 | |||
4843 | return 0; | ||
4786 | } | 4844 | } |
4787 | 4845 | ||
4788 | int get_field_val(struct trace_seq *s, struct format_field *field, | 4846 | int get_field_val(struct trace_seq *s, struct format_field *field, |