aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung.kim@lge.com>2013-12-12 02:36:17 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-12-18 12:47:58 -0500
commitbf19b82e7cf033319525a9eab12216b59c41c519 (patch)
tree9bd8cd68ac548688e4291340110e3433a66aae34
parentf1cbf78d175e6202a29f53a7f915520e40a37baf (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>
-rw-r--r--tools/lib/traceevent/event-parse.c17
-rw-r--r--tools/lib/traceevent/event-parse.h7
-rw-r--r--tools/lib/traceevent/parse-filter.c98
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
854struct event_filter { 856struct 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
860struct event_filter *pevent_filter_alloc(struct pevent *pevent); 863struct event_filter *pevent_filter_alloc(struct pevent *pevent);
@@ -874,10 +877,12 @@ enum filter_trivial_type {
874enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, 877enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter,
875 const char *filter_str); 878 const char *filter_str);
876 879
877
878enum pevent_errno pevent_filter_match(struct event_filter *filter, 880enum pevent_errno pevent_filter_match(struct event_filter *filter,
879 struct pevent_record *record); 881 struct pevent_record *record);
880 882
883int pevent_filter_strerror(struct event_filter *filter, enum pevent_errno err,
884 char *buf, size_t buflen);
885
881int pevent_event_filtered(struct event_filter *filter, 886int 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 41static void show_error(char *error_buf, const char *fmt, ...)
42
43static 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
92static void free_token(char *token) 68static void free_token(char *token)
@@ -370,7 +346,7 @@ static void free_events(struct event_list *events)
370 346
371static enum pevent_errno 347static enum pevent_errno
372create_arg_item(struct event_format *event, const char *token, 348create_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
476static enum pevent_errno 452static enum pevent_errno
477add_right(struct filter_arg *op, struct filter_arg *arg, char **error_str) 453add_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
787static enum pevent_errno 763static enum pevent_errno
788reparent_op_arg(struct filter_arg *parent, struct filter_arg *old_child, 764reparent_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) */
840static int test_arg(struct filter_arg *parent, struct filter_arg *arg, 816static 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 */
940static int collapse_tree(struct filter_arg *arg, 916static 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
974static enum pevent_errno 950static enum pevent_errno
975process_filter(struct event_format *event, struct filter_arg **parg, 951process_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
1212static enum pevent_errno 1188static enum pevent_errno
1213process_event(struct event_format *event, const char *filter_str, 1189process_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
1237static enum pevent_errno 1213static enum pevent_errno
1238filter_event(struct event_filter *filter, struct event_format *event, 1214filter_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
1247static 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 */
1279enum pevent_errno pevent_filter_add_filter_str(struct event_filter *filter, 1263enum 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 */
1375int 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