diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2013-12-12 02:36:17 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-12-18 12:47:58 -0500 |
commit | bf19b82e7cf033319525a9eab12216b59c41c519 (patch) | |
tree | 9bd8cd68ac548688e4291340110e3433a66aae34 /tools/lib | |
parent | f1cbf78d175e6202a29f53a7f915520e40a37baf (diff) |
tools lib traceevent: Introduce pevent_filter_strerror()
The pevent_filter_strerror() function is for receiving actual error
message from pevent_errno value. To do that, add a static buffer to
event_filter for saving internal error message
If a failed function saved other information in the static buffer
returns the information, otherwise returns generic error message.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1386833777-3790-15-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 17 | ||||
-rw-r--r-- | tools/lib/traceevent/event-parse.h | 7 | ||||
-rw-r--r-- | tools/lib/traceevent/parse-filter.c | 98 |
3 files changed, 61 insertions, 61 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 22566c271275..2ce565a73dd5 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -5230,22 +5230,7 @@ int pevent_strerror(struct pevent *pevent __maybe_unused, | |||
5230 | 5230 | ||
5231 | idx = errnum - __PEVENT_ERRNO__START - 1; | 5231 | idx = errnum - __PEVENT_ERRNO__START - 1; |
5232 | msg = pevent_error_str[idx]; | 5232 | msg = pevent_error_str[idx]; |
5233 | 5233 | snprintf(buf, buflen, "%s", msg); | |
5234 | switch (errnum) { | ||
5235 | case PEVENT_ERRNO__MEM_ALLOC_FAILED: | ||
5236 | case PEVENT_ERRNO__PARSE_EVENT_FAILED: | ||
5237 | case PEVENT_ERRNO__READ_ID_FAILED: | ||
5238 | case PEVENT_ERRNO__READ_FORMAT_FAILED: | ||
5239 | case PEVENT_ERRNO__READ_PRINT_FAILED: | ||
5240 | case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: | ||
5241 | case PEVENT_ERRNO__INVALID_ARG_TYPE: | ||
5242 | snprintf(buf, buflen, "%s", msg); | ||
5243 | break; | ||
5244 | |||
5245 | default: | ||
5246 | /* cannot reach here */ | ||
5247 | break; | ||
5248 | } | ||
5249 | 5234 | ||
5250 | return 0; | 5235 | return 0; |
5251 | } | 5236 | } |
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 3ad784f5f647..cf5db9013f2c 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h | |||
@@ -851,10 +851,13 @@ struct filter_type { | |||
851 | struct filter_arg *filter; | 851 | struct filter_arg *filter; |
852 | }; | 852 | }; |
853 | 853 | ||
854 | #define PEVENT_FILTER_ERROR_BUFSZ 1024 | ||
855 | |||
854 | struct event_filter { | 856 | struct event_filter { |
855 | struct pevent *pevent; | 857 | struct pevent *pevent; |
856 | int filters; | 858 | int filters; |
857 | struct filter_type *event_filters; | 859 | struct filter_type *event_filters; |
860 | char error_buffer[PEVENT_FILTER_ERROR_BUFSZ]; | ||
858 | }; | 861 | }; |
859 | 862 | ||
860 | struct event_filter *pevent_filter_alloc(struct pevent *pevent); | 863 | struct event_filter *pevent_filter_alloc(struct pevent *pevent); |
@@ -874,10 +877,12 @@ enum filter_trivial_type { | |||
874 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | 877 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, |
875 | const char *filter_str); | 878 | const char *filter_str); |
876 | 879 | ||
877 | |||
878 | enum pevent_errno pevent_filter_match(struct event_filter *filter, | 880 | enum pevent_errno pevent_filter_match(struct event_filter *filter, |
879 | struct pevent_record *record); | 881 | struct pevent_record *record); |
880 | 882 | ||
883 | int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, | ||
884 | char *buf, size_t buflen); | ||
885 | |||
881 | int pevent_event_filtered(struct event_filter *filter, | 886 | int pevent_event_filtered(struct event_filter *filter, |
882 | int event_id); | 887 | int event_id); |
883 | 888 | ||
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index e2842b926759..b50234402fc2 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c | |||
@@ -38,55 +38,31 @@ struct event_list { | |||
38 | struct event_format *event; | 38 | struct event_format *event; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | #define MAX_ERR_STR_SIZE 256 | 41 | static void show_error(char *error_buf, const char *fmt, ...) |
42 | |||
43 | static void show_error(char **error_str, const char *fmt, ...) | ||
44 | { | 42 | { |
45 | unsigned long long index; | 43 | unsigned long long index; |
46 | const char *input; | 44 | const char *input; |
47 | char *error; | ||
48 | va_list ap; | 45 | va_list ap; |
49 | int len; | 46 | int len; |
50 | int i; | 47 | int i; |
51 | 48 | ||
52 | if (!error_str) | ||
53 | return; | ||
54 | |||
55 | input = pevent_get_input_buf(); | 49 | input = pevent_get_input_buf(); |
56 | index = pevent_get_input_buf_ptr(); | 50 | index = pevent_get_input_buf_ptr(); |
57 | len = input ? strlen(input) : 0; | 51 | len = input ? strlen(input) : 0; |
58 | 52 | ||
59 | error = malloc(MAX_ERR_STR_SIZE + (len*2) + 3); | ||
60 | if (error == NULL) { | ||
61 | /* | ||
62 | * Maybe it's due to len is too long. | ||
63 | * Retry without the input buffer part. | ||
64 | */ | ||
65 | len = 0; | ||
66 | |||
67 | error = malloc(MAX_ERR_STR_SIZE); | ||
68 | if (error == NULL) { | ||
69 | /* no memory */ | ||
70 | *error_str = NULL; | ||
71 | return; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | if (len) { | 53 | if (len) { |
76 | strcpy(error, input); | 54 | strcpy(error_buf, input); |
77 | error[len] = '\n'; | 55 | error_buf[len] = '\n'; |
78 | for (i = 1; i < len && i < index; i++) | 56 | for (i = 1; i < len && i < index; i++) |
79 | error[len+i] = ' '; | 57 | error_buf[len+i] = ' '; |
80 | error[len + i] = '^'; | 58 | error_buf[len + i] = '^'; |
81 | error[len + i + 1] = '\n'; | 59 | error_buf[len + i + 1] = '\n'; |
82 | len += i+2; | 60 | len += i+2; |
83 | } | 61 | } |
84 | 62 | ||
85 | va_start(ap, fmt); | 63 | va_start(ap, fmt); |
86 | vsnprintf(error + len, MAX_ERR_STR_SIZE, fmt, ap); | 64 | vsnprintf(error_buf + len, PEVENT_FILTER_ERROR_BUFSZ - len, fmt, ap); |
87 | va_end(ap); | 65 | va_end(ap); |
88 | |||
89 | *error_str = error; | ||
90 | } | 66 | } |
91 | 67 | ||
92 | static void free_token(char *token) | 68 | static void free_token(char *token) |
@@ -370,7 +346,7 @@ static void free_events(struct event_list *events) | |||
370 | 346 | ||
371 | static enum pevent_errno | 347 | static enum pevent_errno |
372 | create_arg_item(struct event_format *event, const char *token, | 348 | create_arg_item(struct event_format *event, const char *token, |
373 | enum event_type type, struct filter_arg **parg, char **error_str) | 349 | enum event_type type, struct filter_arg **parg, char *error_str) |
374 | { | 350 | { |
375 | struct format_field *field; | 351 | struct format_field *field; |
376 | struct filter_arg *arg; | 352 | struct filter_arg *arg; |
@@ -474,7 +450,7 @@ create_arg_cmp(enum filter_exp_type etype) | |||
474 | } | 450 | } |
475 | 451 | ||
476 | static enum pevent_errno | 452 | static enum pevent_errno |
477 | add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str) | 453 | add_right(struct filter_arg *op, struct filter_arg *arg, char *error_str) |
478 | { | 454 | { |
479 | struct filter_arg *left; | 455 | struct filter_arg *left; |
480 | char *str; | 456 | char *str; |
@@ -786,7 +762,7 @@ enum filter_vals { | |||
786 | 762 | ||
787 | static enum pevent_errno | 763 | static enum pevent_errno |
788 | reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, | 764 | reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, |
789 | struct filter_arg *arg, char **error_str) | 765 | struct filter_arg *arg, char *error_str) |
790 | { | 766 | { |
791 | struct filter_arg *other_child; | 767 | struct filter_arg *other_child; |
792 | struct filter_arg **ptr; | 768 | struct filter_arg **ptr; |
@@ -838,7 +814,7 @@ reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, | |||
838 | 814 | ||
839 | /* Returns either filter_vals (success) or pevent_errno (failfure) */ | 815 | /* Returns either filter_vals (success) or pevent_errno (failfure) */ |
840 | static int test_arg(struct filter_arg *parent, struct filter_arg *arg, | 816 | static int test_arg(struct filter_arg *parent, struct filter_arg *arg, |
841 | char **error_str) | 817 | char *error_str) |
842 | { | 818 | { |
843 | int lval, rval; | 819 | int lval, rval; |
844 | 820 | ||
@@ -938,7 +914,7 @@ static int test_arg(struct filter_arg *parent, struct filter_arg *arg, | |||
938 | 914 | ||
939 | /* Remove any unknown event fields */ | 915 | /* Remove any unknown event fields */ |
940 | static int collapse_tree(struct filter_arg *arg, | 916 | static int collapse_tree(struct filter_arg *arg, |
941 | struct filter_arg **arg_collapsed, char **error_str) | 917 | struct filter_arg **arg_collapsed, char *error_str) |
942 | { | 918 | { |
943 | int ret; | 919 | int ret; |
944 | 920 | ||
@@ -973,7 +949,7 @@ static int collapse_tree(struct filter_arg *arg, | |||
973 | 949 | ||
974 | static enum pevent_errno | 950 | static enum pevent_errno |
975 | process_filter(struct event_format *event, struct filter_arg **parg, | 951 | process_filter(struct event_format *event, struct filter_arg **parg, |
976 | char **error_str, int not) | 952 | char *error_str, int not) |
977 | { | 953 | { |
978 | enum event_type type; | 954 | enum event_type type; |
979 | char *token = NULL; | 955 | char *token = NULL; |
@@ -1211,7 +1187,7 @@ process_filter(struct event_format *event, struct filter_arg **parg, | |||
1211 | 1187 | ||
1212 | static enum pevent_errno | 1188 | static enum pevent_errno |
1213 | process_event(struct event_format *event, const char *filter_str, | 1189 | process_event(struct event_format *event, const char *filter_str, |
1214 | struct filter_arg **parg, char **error_str) | 1190 | struct filter_arg **parg, char *error_str) |
1215 | { | 1191 | { |
1216 | int ret; | 1192 | int ret; |
1217 | 1193 | ||
@@ -1236,7 +1212,7 @@ process_event(struct event_format *event, const char *filter_str, | |||
1236 | 1212 | ||
1237 | static enum pevent_errno | 1213 | static enum pevent_errno |
1238 | filter_event(struct event_filter *filter, struct event_format *event, | 1214 | filter_event(struct event_filter *filter, struct event_format *event, |
1239 | const char *filter_str, char **error_str) | 1215 | const char *filter_str, char *error_str) |
1240 | { | 1216 | { |
1241 | struct filter_type *filter_type; | 1217 | struct filter_type *filter_type; |
1242 | struct filter_arg *arg; | 1218 | struct filter_arg *arg; |
@@ -1268,13 +1244,21 @@ filter_event(struct event_filter *filter, struct event_format *event, | |||
1268 | return 0; | 1244 | return 0; |
1269 | } | 1245 | } |
1270 | 1246 | ||
1247 | static void filter_init_error_buf(struct event_filter *filter) | ||
1248 | { | ||
1249 | /* clear buffer to reset show error */ | ||
1250 | pevent_buffer_init("", 0); | ||
1251 | filter->error_buffer[0] = '\0'; | ||
1252 | } | ||
1253 | |||
1271 | /** | 1254 | /** |
1272 | * pevent_filter_add_filter_str - add a new filter | 1255 | * pevent_filter_add_filter_str - add a new filter |
1273 | * @filter: the event filter to add to | 1256 | * @filter: the event filter to add to |
1274 | * @filter_str: the filter string that contains the filter | 1257 | * @filter_str: the filter string that contains the filter |
1275 | * | 1258 | * |
1276 | * Returns 0 if the filter was successfully added or a | 1259 | * Returns 0 if the filter was successfully added or a |
1277 | * negative error code. | 1260 | * negative error code. Use pevent_filter_strerror() to see |
1261 | * actual error message in case of error. | ||
1278 | */ | 1262 | */ |
1279 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | 1263 | enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, |
1280 | const char *filter_str) | 1264 | const char *filter_str) |
@@ -1291,10 +1275,8 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | |||
1291 | enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ | 1275 | enum pevent_errno rtn = 0; /* PEVENT_ERRNO__SUCCESS */ |
1292 | int len; | 1276 | int len; |
1293 | int ret; | 1277 | int ret; |
1294 | char *error_str = NULL; | ||
1295 | 1278 | ||
1296 | /* clear buffer to reset show error */ | 1279 | filter_init_error_buf(filter); |
1297 | pevent_buffer_init("", 0); | ||
1298 | 1280 | ||
1299 | filter_start = strchr(filter_str, ':'); | 1281 | filter_start = strchr(filter_str, ':'); |
1300 | if (filter_start) | 1282 | if (filter_start) |
@@ -1353,7 +1335,7 @@ enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, | |||
1353 | /* filter starts here */ | 1335 | /* filter starts here */ |
1354 | for (event = events; event; event = event->next) { | 1336 | for (event = events; event; event = event->next) { |
1355 | ret = filter_event(filter, event->event, filter_start, | 1337 | ret = filter_event(filter, event->event, filter_start, |
1356 | &error_str); | 1338 | filter->error_buffer); |
1357 | /* Failures are returned if a parse error happened */ | 1339 | /* Failures are returned if a parse error happened */ |
1358 | if (ret < 0) | 1340 | if (ret < 0) |
1359 | rtn = ret; | 1341 | rtn = ret; |
@@ -1382,6 +1364,32 @@ static void free_filter_type(struct filter_type *filter_type) | |||
1382 | } | 1364 | } |
1383 | 1365 | ||
1384 | /** | 1366 | /** |
1367 | * pevent_filter_strerror - fill error message in a buffer | ||
1368 | * @filter: the event filter contains error | ||
1369 | * @err: the error code | ||
1370 | * @buf: the buffer to be filled in | ||
1371 | * @buflen: the size of the buffer | ||
1372 | * | ||
1373 | * Returns 0 if message was filled successfully, -1 if error | ||
1374 | */ | ||
1375 | int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err, | ||
1376 | char *buf, size_t buflen) | ||
1377 | { | ||
1378 | if (err <= __PEVENT_ERRNO__START || err >= __PEVENT_ERRNO__END) | ||
1379 | return -1; | ||
1380 | |||
1381 | if (strlen(filter->error_buffer) > 0) { | ||
1382 | size_t len = snprintf(buf, buflen, "%s", filter->error_buffer); | ||
1383 | |||
1384 | if (len > buflen) | ||
1385 | return -1; | ||
1386 | return 0; | ||
1387 | } | ||
1388 | |||
1389 | return pevent_strerror(filter->pevent, err, buf, buflen); | ||
1390 | } | ||
1391 | |||
1392 | /** | ||
1385 | * pevent_filter_remove_event - remove a filter for an event | 1393 | * pevent_filter_remove_event - remove a filter for an event |
1386 | * @filter: the event filter to remove from | 1394 | * @filter: the event filter to remove from |
1387 | * @event_id: the event to remove a filter for | 1395 | * @event_id: the event to remove a filter for |
@@ -2027,6 +2035,8 @@ enum pevent_errno pevent_filter_match(struct event_filter *filter, | |||
2027 | int ret; | 2035 | int ret; |
2028 | enum pevent_errno err = 0; | 2036 | enum pevent_errno err = 0; |
2029 | 2037 | ||
2038 | filter_init_error_buf(filter); | ||
2039 | |||
2030 | if (!filter->filters) | 2040 | if (!filter->filters) |
2031 | return PEVENT_ERRNO__NO_FILTER; | 2041 | return PEVENT_ERRNO__NO_FILTER; |
2032 | 2042 | ||