aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/traceevent/event-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
-rw-r--r--tools/lib/traceevent/event-parse.c104
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 */
4689int pevent_parse_event(struct pevent *pevent, 4689enum 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
4800static const char * const pevent_error_str[] = {
4801 PEVENT_ERRORS
4802};
4803#undef _PE
4804
4805int 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
4788int get_field_val(struct trace_seq *s, struct format_field *field, 4846int get_field_val(struct trace_seq *s, struct format_field *field,