diff options
Diffstat (limited to 'tools/perf/util/trace-event-parse.c')
-rw-r--r-- | tools/perf/util/trace-event-parse.c | 537 |
1 files changed, 411 insertions, 126 deletions
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 55c9659a56e2..eae560503086 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -40,6 +40,8 @@ int header_page_size_size; | |||
40 | int header_page_data_offset; | 40 | int header_page_data_offset; |
41 | int header_page_data_size; | 41 | int header_page_data_size; |
42 | 42 | ||
43 | int latency_format; | ||
44 | |||
43 | static char *input_buf; | 45 | static char *input_buf; |
44 | static unsigned long long input_buf_ptr; | 46 | static unsigned long long input_buf_ptr; |
45 | static unsigned long long input_buf_siz; | 47 | static unsigned long long input_buf_siz; |
@@ -284,18 +286,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
284 | char *line; | 286 | char *line; |
285 | char *next = NULL; | 287 | char *next = NULL; |
286 | char *addr_str; | 288 | char *addr_str; |
287 | int ret; | ||
288 | int i; | 289 | int i; |
289 | 290 | ||
290 | line = strtok_r(file, "\n", &next); | 291 | line = strtok_r(file, "\n", &next); |
291 | while (line) { | 292 | while (line) { |
293 | addr_str = strsep(&line, ":"); | ||
294 | if (!line) { | ||
295 | warning("error parsing print strings"); | ||
296 | break; | ||
297 | } | ||
292 | item = malloc_or_die(sizeof(*item)); | 298 | item = malloc_or_die(sizeof(*item)); |
293 | ret = sscanf(line, "%as : %as", | ||
294 | (float *)(void *)&addr_str, /* workaround gcc warning */ | ||
295 | (float *)(void *)&item->printk); | ||
296 | item->addr = strtoull(addr_str, NULL, 16); | 299 | item->addr = strtoull(addr_str, NULL, 16); |
297 | free(addr_str); | 300 | /* fmt still has a space, skip it */ |
298 | 301 | item->printk = strdup(line+1); | |
299 | item->next = list; | 302 | item->next = list; |
300 | list = item; | 303 | list = item; |
301 | line = strtok_r(NULL, "\n", &next); | 304 | line = strtok_r(NULL, "\n", &next); |
@@ -522,7 +525,10 @@ static enum event_type __read_token(char **tok) | |||
522 | last_ch = ch; | 525 | last_ch = ch; |
523 | ch = __read_char(); | 526 | ch = __read_char(); |
524 | buf[i++] = ch; | 527 | buf[i++] = ch; |
525 | } while (ch != quote_ch && last_ch != '\\'); | 528 | /* the '\' '\' will cancel itself */ |
529 | if (ch == '\\' && last_ch == '\\') | ||
530 | last_ch = 0; | ||
531 | } while (ch != quote_ch || last_ch == '\\'); | ||
526 | /* remove the last quote */ | 532 | /* remove the last quote */ |
527 | i--; | 533 | i--; |
528 | goto out; | 534 | goto out; |
@@ -610,7 +616,7 @@ static enum event_type read_token_item(char **tok) | |||
610 | static int test_type(enum event_type type, enum event_type expect) | 616 | static int test_type(enum event_type type, enum event_type expect) |
611 | { | 617 | { |
612 | if (type != expect) { | 618 | if (type != expect) { |
613 | die("Error: expected type %d but read %d", | 619 | warning("Error: expected type %d but read %d", |
614 | expect, type); | 620 | expect, type); |
615 | return -1; | 621 | return -1; |
616 | } | 622 | } |
@@ -621,13 +627,13 @@ static int test_type_token(enum event_type type, char *token, | |||
621 | enum event_type expect, const char *expect_tok) | 627 | enum event_type expect, const char *expect_tok) |
622 | { | 628 | { |
623 | if (type != expect) { | 629 | if (type != expect) { |
624 | die("Error: expected type %d but read %d", | 630 | warning("Error: expected type %d but read %d", |
625 | expect, type); | 631 | expect, type); |
626 | return -1; | 632 | return -1; |
627 | } | 633 | } |
628 | 634 | ||
629 | if (strcmp(token, expect_tok) != 0) { | 635 | if (strcmp(token, expect_tok) != 0) { |
630 | die("Error: expected '%s' but read '%s'", | 636 | warning("Error: expected '%s' but read '%s'", |
631 | expect_tok, token); | 637 | expect_tok, token); |
632 | return -1; | 638 | return -1; |
633 | } | 639 | } |
@@ -665,7 +671,7 @@ static int __read_expected(enum event_type expect, const char *str, int newline_ | |||
665 | 671 | ||
666 | free_token(token); | 672 | free_token(token); |
667 | 673 | ||
668 | return 0; | 674 | return ret; |
669 | } | 675 | } |
670 | 676 | ||
671 | static int read_expected(enum event_type expect, const char *str) | 677 | static int read_expected(enum event_type expect, const char *str) |
@@ -682,10 +688,10 @@ static char *event_read_name(void) | |||
682 | { | 688 | { |
683 | char *token; | 689 | char *token; |
684 | 690 | ||
685 | if (read_expected(EVENT_ITEM, (char *)"name") < 0) | 691 | if (read_expected(EVENT_ITEM, "name") < 0) |
686 | return NULL; | 692 | return NULL; |
687 | 693 | ||
688 | if (read_expected(EVENT_OP, (char *)":") < 0) | 694 | if (read_expected(EVENT_OP, ":") < 0) |
689 | return NULL; | 695 | return NULL; |
690 | 696 | ||
691 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 697 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -703,10 +709,10 @@ static int event_read_id(void) | |||
703 | char *token; | 709 | char *token; |
704 | int id; | 710 | int id; |
705 | 711 | ||
706 | if (read_expected_item(EVENT_ITEM, (char *)"ID") < 0) | 712 | if (read_expected_item(EVENT_ITEM, "ID") < 0) |
707 | return -1; | 713 | return -1; |
708 | 714 | ||
709 | if (read_expected(EVENT_OP, (char *)":") < 0) | 715 | if (read_expected(EVENT_OP, ":") < 0) |
710 | return -1; | 716 | return -1; |
711 | 717 | ||
712 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 718 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -721,6 +727,24 @@ static int event_read_id(void) | |||
721 | return -1; | 727 | return -1; |
722 | } | 728 | } |
723 | 729 | ||
730 | static int field_is_string(struct format_field *field) | ||
731 | { | ||
732 | if ((field->flags & FIELD_IS_ARRAY) && | ||
733 | (!strstr(field->type, "char") || !strstr(field->type, "u8") || | ||
734 | !strstr(field->type, "s8"))) | ||
735 | return 1; | ||
736 | |||
737 | return 0; | ||
738 | } | ||
739 | |||
740 | static int field_is_dynamic(struct format_field *field) | ||
741 | { | ||
742 | if (!strcmp(field->type, "__data_loc")) | ||
743 | return 1; | ||
744 | |||
745 | return 0; | ||
746 | } | ||
747 | |||
724 | static int event_read_fields(struct event *event, struct format_field **fields) | 748 | static int event_read_fields(struct event *event, struct format_field **fields) |
725 | { | 749 | { |
726 | struct format_field *field = NULL; | 750 | struct format_field *field = NULL; |
@@ -738,7 +762,7 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
738 | 762 | ||
739 | count++; | 763 | count++; |
740 | 764 | ||
741 | if (test_type_token(type, token, EVENT_ITEM, (char *)"field")) | 765 | if (test_type_token(type, token, EVENT_ITEM, "field")) |
742 | goto fail; | 766 | goto fail; |
743 | free_token(token); | 767 | free_token(token); |
744 | 768 | ||
@@ -753,7 +777,7 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
753 | type = read_token(&token); | 777 | type = read_token(&token); |
754 | } | 778 | } |
755 | 779 | ||
756 | if (test_type_token(type, token, EVENT_OP, (char *)":") < 0) | 780 | if (test_type_token(type, token, EVENT_OP, ":") < 0) |
757 | return -1; | 781 | return -1; |
758 | 782 | ||
759 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 783 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -865,14 +889,20 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
865 | free(brackets); | 889 | free(brackets); |
866 | } | 890 | } |
867 | 891 | ||
868 | if (test_type_token(type, token, EVENT_OP, (char *)";")) | 892 | if (field_is_string(field)) { |
893 | field->flags |= FIELD_IS_STRING; | ||
894 | if (field_is_dynamic(field)) | ||
895 | field->flags |= FIELD_IS_DYNAMIC; | ||
896 | } | ||
897 | |||
898 | if (test_type_token(type, token, EVENT_OP, ";")) | ||
869 | goto fail; | 899 | goto fail; |
870 | free_token(token); | 900 | free_token(token); |
871 | 901 | ||
872 | if (read_expected(EVENT_ITEM, (char *)"offset") < 0) | 902 | if (read_expected(EVENT_ITEM, "offset") < 0) |
873 | goto fail_expect; | 903 | goto fail_expect; |
874 | 904 | ||
875 | if (read_expected(EVENT_OP, (char *)":") < 0) | 905 | if (read_expected(EVENT_OP, ":") < 0) |
876 | goto fail_expect; | 906 | goto fail_expect; |
877 | 907 | ||
878 | if (read_expect_type(EVENT_ITEM, &token)) | 908 | if (read_expect_type(EVENT_ITEM, &token)) |
@@ -880,13 +910,13 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
880 | field->offset = strtoul(token, NULL, 0); | 910 | field->offset = strtoul(token, NULL, 0); |
881 | free_token(token); | 911 | free_token(token); |
882 | 912 | ||
883 | if (read_expected(EVENT_OP, (char *)";") < 0) | 913 | if (read_expected(EVENT_OP, ";") < 0) |
884 | goto fail_expect; | 914 | goto fail_expect; |
885 | 915 | ||
886 | if (read_expected(EVENT_ITEM, (char *)"size") < 0) | 916 | if (read_expected(EVENT_ITEM, "size") < 0) |
887 | goto fail_expect; | 917 | goto fail_expect; |
888 | 918 | ||
889 | if (read_expected(EVENT_OP, (char *)":") < 0) | 919 | if (read_expected(EVENT_OP, ":") < 0) |
890 | goto fail_expect; | 920 | goto fail_expect; |
891 | 921 | ||
892 | if (read_expect_type(EVENT_ITEM, &token)) | 922 | if (read_expect_type(EVENT_ITEM, &token)) |
@@ -894,11 +924,33 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
894 | field->size = strtoul(token, NULL, 0); | 924 | field->size = strtoul(token, NULL, 0); |
895 | free_token(token); | 925 | free_token(token); |
896 | 926 | ||
897 | if (read_expected(EVENT_OP, (char *)";") < 0) | 927 | if (read_expected(EVENT_OP, ";") < 0) |
898 | goto fail_expect; | 928 | goto fail_expect; |
899 | 929 | ||
900 | if (read_expect_type(EVENT_NEWLINE, &token) < 0) | 930 | type = read_token(&token); |
901 | goto fail; | 931 | if (type != EVENT_NEWLINE) { |
932 | /* newer versions of the kernel have a "signed" type */ | ||
933 | if (test_type_token(type, token, EVENT_ITEM, "signed")) | ||
934 | goto fail; | ||
935 | |||
936 | free_token(token); | ||
937 | |||
938 | if (read_expected(EVENT_OP, ":") < 0) | ||
939 | goto fail_expect; | ||
940 | |||
941 | if (read_expect_type(EVENT_ITEM, &token)) | ||
942 | goto fail; | ||
943 | |||
944 | /* add signed type */ | ||
945 | |||
946 | free_token(token); | ||
947 | if (read_expected(EVENT_OP, ";") < 0) | ||
948 | goto fail_expect; | ||
949 | |||
950 | if (read_expect_type(EVENT_NEWLINE, &token)) | ||
951 | goto fail; | ||
952 | } | ||
953 | |||
902 | free_token(token); | 954 | free_token(token); |
903 | 955 | ||
904 | *fields = field; | 956 | *fields = field; |
@@ -921,10 +973,10 @@ static int event_read_format(struct event *event) | |||
921 | char *token; | 973 | char *token; |
922 | int ret; | 974 | int ret; |
923 | 975 | ||
924 | if (read_expected_item(EVENT_ITEM, (char *)"format") < 0) | 976 | if (read_expected_item(EVENT_ITEM, "format") < 0) |
925 | return -1; | 977 | return -1; |
926 | 978 | ||
927 | if (read_expected(EVENT_OP, (char *)":") < 0) | 979 | if (read_expected(EVENT_OP, ":") < 0) |
928 | return -1; | 980 | return -1; |
929 | 981 | ||
930 | if (read_expect_type(EVENT_NEWLINE, &token)) | 982 | if (read_expect_type(EVENT_NEWLINE, &token)) |
@@ -984,7 +1036,7 @@ process_cond(struct event *event, struct print_arg *top, char **tok) | |||
984 | 1036 | ||
985 | *tok = NULL; | 1037 | *tok = NULL; |
986 | type = process_arg(event, left, &token); | 1038 | type = process_arg(event, left, &token); |
987 | if (test_type_token(type, token, EVENT_OP, (char *)":")) | 1039 | if (test_type_token(type, token, EVENT_OP, ":")) |
988 | goto out_free; | 1040 | goto out_free; |
989 | 1041 | ||
990 | arg->op.op = token; | 1042 | arg->op.op = token; |
@@ -1004,6 +1056,35 @@ out_free: | |||
1004 | return EVENT_ERROR; | 1056 | return EVENT_ERROR; |
1005 | } | 1057 | } |
1006 | 1058 | ||
1059 | static enum event_type | ||
1060 | process_array(struct event *event, struct print_arg *top, char **tok) | ||
1061 | { | ||
1062 | struct print_arg *arg; | ||
1063 | enum event_type type; | ||
1064 | char *token = NULL; | ||
1065 | |||
1066 | arg = malloc_or_die(sizeof(*arg)); | ||
1067 | memset(arg, 0, sizeof(*arg)); | ||
1068 | |||
1069 | *tok = NULL; | ||
1070 | type = process_arg(event, arg, &token); | ||
1071 | if (test_type_token(type, token, EVENT_OP, "]")) | ||
1072 | goto out_free; | ||
1073 | |||
1074 | top->op.right = arg; | ||
1075 | |||
1076 | free_token(token); | ||
1077 | type = read_token_item(&token); | ||
1078 | *tok = token; | ||
1079 | |||
1080 | return type; | ||
1081 | |||
1082 | out_free: | ||
1083 | free_token(*tok); | ||
1084 | free_arg(arg); | ||
1085 | return EVENT_ERROR; | ||
1086 | } | ||
1087 | |||
1007 | static int get_op_prio(char *op) | 1088 | static int get_op_prio(char *op) |
1008 | { | 1089 | { |
1009 | if (!op[1]) { | 1090 | if (!op[1]) { |
@@ -1128,6 +1209,8 @@ process_op(struct event *event, struct print_arg *arg, char **tok) | |||
1128 | strcmp(token, "*") == 0 || | 1209 | strcmp(token, "*") == 0 || |
1129 | strcmp(token, "^") == 0 || | 1210 | strcmp(token, "^") == 0 || |
1130 | strcmp(token, "/") == 0 || | 1211 | strcmp(token, "/") == 0 || |
1212 | strcmp(token, "<") == 0 || | ||
1213 | strcmp(token, ">") == 0 || | ||
1131 | strcmp(token, "==") == 0 || | 1214 | strcmp(token, "==") == 0 || |
1132 | strcmp(token, "!=") == 0) { | 1215 | strcmp(token, "!=") == 0) { |
1133 | 1216 | ||
@@ -1144,17 +1227,46 @@ process_op(struct event *event, struct print_arg *arg, char **tok) | |||
1144 | 1227 | ||
1145 | right = malloc_or_die(sizeof(*right)); | 1228 | right = malloc_or_die(sizeof(*right)); |
1146 | 1229 | ||
1147 | type = process_arg(event, right, tok); | 1230 | type = read_token_item(&token); |
1231 | *tok = token; | ||
1232 | |||
1233 | /* could just be a type pointer */ | ||
1234 | if ((strcmp(arg->op.op, "*") == 0) && | ||
1235 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { | ||
1236 | if (left->type != PRINT_ATOM) | ||
1237 | die("bad pointer type"); | ||
1238 | left->atom.atom = realloc(left->atom.atom, | ||
1239 | sizeof(left->atom.atom) + 3); | ||
1240 | strcat(left->atom.atom, " *"); | ||
1241 | *arg = *left; | ||
1242 | free(arg); | ||
1243 | |||
1244 | return type; | ||
1245 | } | ||
1246 | |||
1247 | type = process_arg_token(event, right, tok, type); | ||
1148 | 1248 | ||
1149 | arg->op.right = right; | 1249 | arg->op.right = right; |
1150 | 1250 | ||
1251 | } else if (strcmp(token, "[") == 0) { | ||
1252 | |||
1253 | left = malloc_or_die(sizeof(*left)); | ||
1254 | *left = *arg; | ||
1255 | |||
1256 | arg->type = PRINT_OP; | ||
1257 | arg->op.op = token; | ||
1258 | arg->op.left = left; | ||
1259 | |||
1260 | arg->op.prio = 0; | ||
1261 | type = process_array(event, arg, tok); | ||
1262 | |||
1151 | } else { | 1263 | } else { |
1152 | die("unknown op '%s'", token); | 1264 | warning("unknown op '%s'", token); |
1265 | event->flags |= EVENT_FL_FAILED; | ||
1153 | /* the arg is now the left side */ | 1266 | /* the arg is now the left side */ |
1154 | return EVENT_NONE; | 1267 | return EVENT_NONE; |
1155 | } | 1268 | } |
1156 | 1269 | ||
1157 | |||
1158 | if (type == EVENT_OP) { | 1270 | if (type == EVENT_OP) { |
1159 | int prio; | 1271 | int prio; |
1160 | 1272 | ||
@@ -1178,7 +1290,7 @@ process_entry(struct event *event __unused, struct print_arg *arg, | |||
1178 | char *field; | 1290 | char *field; |
1179 | char *token; | 1291 | char *token; |
1180 | 1292 | ||
1181 | if (read_expected(EVENT_OP, (char *)"->") < 0) | 1293 | if (read_expected(EVENT_OP, "->") < 0) |
1182 | return EVENT_ERROR; | 1294 | return EVENT_ERROR; |
1183 | 1295 | ||
1184 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 1296 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -1338,14 +1450,14 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok) | |||
1338 | do { | 1450 | do { |
1339 | free_token(token); | 1451 | free_token(token); |
1340 | type = read_token_item(&token); | 1452 | type = read_token_item(&token); |
1341 | if (test_type_token(type, token, EVENT_OP, (char *)"{")) | 1453 | if (test_type_token(type, token, EVENT_OP, "{")) |
1342 | break; | 1454 | break; |
1343 | 1455 | ||
1344 | arg = malloc_or_die(sizeof(*arg)); | 1456 | arg = malloc_or_die(sizeof(*arg)); |
1345 | 1457 | ||
1346 | free_token(token); | 1458 | free_token(token); |
1347 | type = process_arg(event, arg, &token); | 1459 | type = process_arg(event, arg, &token); |
1348 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1460 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1349 | goto out_free; | 1461 | goto out_free; |
1350 | 1462 | ||
1351 | field = malloc_or_die(sizeof(*field)); | 1463 | field = malloc_or_die(sizeof(*field)); |
@@ -1356,7 +1468,7 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok) | |||
1356 | 1468 | ||
1357 | free_token(token); | 1469 | free_token(token); |
1358 | type = process_arg(event, arg, &token); | 1470 | type = process_arg(event, arg, &token); |
1359 | if (test_type_token(type, token, EVENT_OP, (char *)"}")) | 1471 | if (test_type_token(type, token, EVENT_OP, "}")) |
1360 | goto out_free; | 1472 | goto out_free; |
1361 | 1473 | ||
1362 | value = arg_eval(arg); | 1474 | value = arg_eval(arg); |
@@ -1391,13 +1503,13 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) | |||
1391 | memset(arg, 0, sizeof(*arg)); | 1503 | memset(arg, 0, sizeof(*arg)); |
1392 | arg->type = PRINT_FLAGS; | 1504 | arg->type = PRINT_FLAGS; |
1393 | 1505 | ||
1394 | if (read_expected_item(EVENT_DELIM, (char *)"(") < 0) | 1506 | if (read_expected_item(EVENT_DELIM, "(") < 0) |
1395 | return EVENT_ERROR; | 1507 | return EVENT_ERROR; |
1396 | 1508 | ||
1397 | field = malloc_or_die(sizeof(*field)); | 1509 | field = malloc_or_die(sizeof(*field)); |
1398 | 1510 | ||
1399 | type = process_arg(event, field, &token); | 1511 | type = process_arg(event, field, &token); |
1400 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1512 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1401 | goto out_free; | 1513 | goto out_free; |
1402 | 1514 | ||
1403 | arg->flags.field = field; | 1515 | arg->flags.field = field; |
@@ -1408,11 +1520,11 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) | |||
1408 | type = read_token_item(&token); | 1520 | type = read_token_item(&token); |
1409 | } | 1521 | } |
1410 | 1522 | ||
1411 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1523 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1412 | goto out_free; | 1524 | goto out_free; |
1413 | 1525 | ||
1414 | type = process_fields(event, &arg->flags.flags, &token); | 1526 | type = process_fields(event, &arg->flags.flags, &token); |
1415 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) | 1527 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
1416 | goto out_free; | 1528 | goto out_free; |
1417 | 1529 | ||
1418 | free_token(token); | 1530 | free_token(token); |
@@ -1434,19 +1546,19 @@ process_symbols(struct event *event, struct print_arg *arg, char **tok) | |||
1434 | memset(arg, 0, sizeof(*arg)); | 1546 | memset(arg, 0, sizeof(*arg)); |
1435 | arg->type = PRINT_SYMBOL; | 1547 | arg->type = PRINT_SYMBOL; |
1436 | 1548 | ||
1437 | if (read_expected_item(EVENT_DELIM, (char *)"(") < 0) | 1549 | if (read_expected_item(EVENT_DELIM, "(") < 0) |
1438 | return EVENT_ERROR; | 1550 | return EVENT_ERROR; |
1439 | 1551 | ||
1440 | field = malloc_or_die(sizeof(*field)); | 1552 | field = malloc_or_die(sizeof(*field)); |
1441 | 1553 | ||
1442 | type = process_arg(event, field, &token); | 1554 | type = process_arg(event, field, &token); |
1443 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1555 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1444 | goto out_free; | 1556 | goto out_free; |
1445 | 1557 | ||
1446 | arg->symbol.field = field; | 1558 | arg->symbol.field = field; |
1447 | 1559 | ||
1448 | type = process_fields(event, &arg->symbol.symbols, &token); | 1560 | type = process_fields(event, &arg->symbol.symbols, &token); |
1449 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) | 1561 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
1450 | goto out_free; | 1562 | goto out_free; |
1451 | 1563 | ||
1452 | free_token(token); | 1564 | free_token(token); |
@@ -1463,7 +1575,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1463 | { | 1575 | { |
1464 | struct print_arg *item_arg; | 1576 | struct print_arg *item_arg; |
1465 | enum event_type type; | 1577 | enum event_type type; |
1466 | int ptr_cast = 0; | ||
1467 | char *token; | 1578 | char *token; |
1468 | 1579 | ||
1469 | type = process_arg(event, arg, &token); | 1580 | type = process_arg(event, arg, &token); |
@@ -1471,28 +1582,13 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1471 | if (type == EVENT_ERROR) | 1582 | if (type == EVENT_ERROR) |
1472 | return EVENT_ERROR; | 1583 | return EVENT_ERROR; |
1473 | 1584 | ||
1474 | if (type == EVENT_OP) { | 1585 | if (type == EVENT_OP) |
1475 | /* handle the ptr casts */ | 1586 | type = process_op(event, arg, &token); |
1476 | if (!strcmp(token, "*")) { | ||
1477 | /* | ||
1478 | * FIXME: should we zapp whitespaces before ')' ? | ||
1479 | * (may require a peek_token_item()) | ||
1480 | */ | ||
1481 | if (__peek_char() == ')') { | ||
1482 | ptr_cast = 1; | ||
1483 | free_token(token); | ||
1484 | type = read_token_item(&token); | ||
1485 | } | ||
1486 | } | ||
1487 | if (!ptr_cast) { | ||
1488 | type = process_op(event, arg, &token); | ||
1489 | 1587 | ||
1490 | if (type == EVENT_ERROR) | 1588 | if (type == EVENT_ERROR) |
1491 | return EVENT_ERROR; | 1589 | return EVENT_ERROR; |
1492 | } | ||
1493 | } | ||
1494 | 1590 | ||
1495 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) { | 1591 | if (test_type_token(type, token, EVENT_DELIM, ")")) { |
1496 | free_token(token); | 1592 | free_token(token); |
1497 | return EVENT_ERROR; | 1593 | return EVENT_ERROR; |
1498 | } | 1594 | } |
@@ -1516,13 +1612,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1516 | item_arg = malloc_or_die(sizeof(*item_arg)); | 1612 | item_arg = malloc_or_die(sizeof(*item_arg)); |
1517 | 1613 | ||
1518 | arg->type = PRINT_TYPE; | 1614 | arg->type = PRINT_TYPE; |
1519 | if (ptr_cast) { | ||
1520 | char *old = arg->atom.atom; | ||
1521 | |||
1522 | arg->atom.atom = malloc_or_die(strlen(old + 3)); | ||
1523 | sprintf(arg->atom.atom, "%s *", old); | ||
1524 | free(old); | ||
1525 | } | ||
1526 | arg->typecast.type = arg->atom.atom; | 1615 | arg->typecast.type = arg->atom.atom; |
1527 | arg->typecast.item = item_arg; | 1616 | arg->typecast.item = item_arg; |
1528 | type = process_arg_token(event, item_arg, &token, type); | 1617 | type = process_arg_token(event, item_arg, &token, type); |
@@ -1540,7 +1629,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok) | |||
1540 | enum event_type type; | 1629 | enum event_type type; |
1541 | char *token; | 1630 | char *token; |
1542 | 1631 | ||
1543 | if (read_expected(EVENT_DELIM, (char *)"(") < 0) | 1632 | if (read_expected(EVENT_DELIM, "(") < 0) |
1544 | return EVENT_ERROR; | 1633 | return EVENT_ERROR; |
1545 | 1634 | ||
1546 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 1635 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -1550,7 +1639,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok) | |||
1550 | arg->string.string = token; | 1639 | arg->string.string = token; |
1551 | arg->string.offset = -1; | 1640 | arg->string.offset = -1; |
1552 | 1641 | ||
1553 | if (read_expected(EVENT_DELIM, (char *)")") < 0) | 1642 | if (read_expected(EVENT_DELIM, ")") < 0) |
1554 | return EVENT_ERROR; | 1643 | return EVENT_ERROR; |
1555 | 1644 | ||
1556 | type = read_token(&token); | 1645 | type = read_token(&token); |
@@ -1637,12 +1726,18 @@ process_arg_token(struct event *event, struct print_arg *arg, | |||
1637 | 1726 | ||
1638 | static int event_read_print_args(struct event *event, struct print_arg **list) | 1727 | static int event_read_print_args(struct event *event, struct print_arg **list) |
1639 | { | 1728 | { |
1640 | enum event_type type; | 1729 | enum event_type type = EVENT_ERROR; |
1641 | struct print_arg *arg; | 1730 | struct print_arg *arg; |
1642 | char *token; | 1731 | char *token; |
1643 | int args = 0; | 1732 | int args = 0; |
1644 | 1733 | ||
1645 | do { | 1734 | do { |
1735 | if (type == EVENT_NEWLINE) { | ||
1736 | free_token(token); | ||
1737 | type = read_token_item(&token); | ||
1738 | continue; | ||
1739 | } | ||
1740 | |||
1646 | arg = malloc_or_die(sizeof(*arg)); | 1741 | arg = malloc_or_die(sizeof(*arg)); |
1647 | memset(arg, 0, sizeof(*arg)); | 1742 | memset(arg, 0, sizeof(*arg)); |
1648 | 1743 | ||
@@ -1683,18 +1778,19 @@ static int event_read_print(struct event *event) | |||
1683 | char *token; | 1778 | char *token; |
1684 | int ret; | 1779 | int ret; |
1685 | 1780 | ||
1686 | if (read_expected_item(EVENT_ITEM, (char *)"print") < 0) | 1781 | if (read_expected_item(EVENT_ITEM, "print") < 0) |
1687 | return -1; | 1782 | return -1; |
1688 | 1783 | ||
1689 | if (read_expected(EVENT_ITEM, (char *)"fmt") < 0) | 1784 | if (read_expected(EVENT_ITEM, "fmt") < 0) |
1690 | return -1; | 1785 | return -1; |
1691 | 1786 | ||
1692 | if (read_expected(EVENT_OP, (char *)":") < 0) | 1787 | if (read_expected(EVENT_OP, ":") < 0) |
1693 | return -1; | 1788 | return -1; |
1694 | 1789 | ||
1695 | if (read_expect_type(EVENT_DQUOTE, &token) < 0) | 1790 | if (read_expect_type(EVENT_DQUOTE, &token) < 0) |
1696 | goto fail; | 1791 | goto fail; |
1697 | 1792 | ||
1793 | concat: | ||
1698 | event->print_fmt.format = token; | 1794 | event->print_fmt.format = token; |
1699 | event->print_fmt.args = NULL; | 1795 | event->print_fmt.args = NULL; |
1700 | 1796 | ||
@@ -1704,7 +1800,22 @@ static int event_read_print(struct event *event) | |||
1704 | if (type == EVENT_NONE) | 1800 | if (type == EVENT_NONE) |
1705 | return 0; | 1801 | return 0; |
1706 | 1802 | ||
1707 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1803 | /* Handle concatination of print lines */ |
1804 | if (type == EVENT_DQUOTE) { | ||
1805 | char *cat; | ||
1806 | |||
1807 | cat = malloc_or_die(strlen(event->print_fmt.format) + | ||
1808 | strlen(token) + 1); | ||
1809 | strcpy(cat, event->print_fmt.format); | ||
1810 | strcat(cat, token); | ||
1811 | free_token(token); | ||
1812 | free_token(event->print_fmt.format); | ||
1813 | event->print_fmt.format = NULL; | ||
1814 | token = cat; | ||
1815 | goto concat; | ||
1816 | } | ||
1817 | |||
1818 | if (test_type_token(type, token, EVENT_DELIM, ",")) | ||
1708 | goto fail; | 1819 | goto fail; |
1709 | 1820 | ||
1710 | free_token(token); | 1821 | free_token(token); |
@@ -1713,7 +1824,7 @@ static int event_read_print(struct event *event) | |||
1713 | if (ret < 0) | 1824 | if (ret < 0) |
1714 | return -1; | 1825 | return -1; |
1715 | 1826 | ||
1716 | return 0; | 1827 | return ret; |
1717 | 1828 | ||
1718 | fail: | 1829 | fail: |
1719 | free_token(token); | 1830 | free_token(token); |
@@ -1822,37 +1933,67 @@ static int get_common_info(const char *type, int *offset, int *size) | |||
1822 | return 0; | 1933 | return 0; |
1823 | } | 1934 | } |
1824 | 1935 | ||
1825 | int trace_parse_common_type(void *data) | 1936 | static int __parse_common(void *data, int *size, int *offset, |
1937 | const char *name) | ||
1826 | { | 1938 | { |
1827 | static int type_offset; | ||
1828 | static int type_size; | ||
1829 | int ret; | 1939 | int ret; |
1830 | 1940 | ||
1831 | if (!type_size) { | 1941 | if (!*size) { |
1832 | ret = get_common_info("common_type", | 1942 | ret = get_common_info(name, offset, size); |
1833 | &type_offset, | ||
1834 | &type_size); | ||
1835 | if (ret < 0) | 1943 | if (ret < 0) |
1836 | return ret; | 1944 | return ret; |
1837 | } | 1945 | } |
1838 | return read_size(data + type_offset, type_size); | 1946 | return read_size(data + *offset, *size); |
1947 | } | ||
1948 | |||
1949 | int trace_parse_common_type(void *data) | ||
1950 | { | ||
1951 | static int type_offset; | ||
1952 | static int type_size; | ||
1953 | |||
1954 | return __parse_common(data, &type_size, &type_offset, | ||
1955 | "common_type"); | ||
1839 | } | 1956 | } |
1840 | 1957 | ||
1841 | static int parse_common_pid(void *data) | 1958 | static int parse_common_pid(void *data) |
1842 | { | 1959 | { |
1843 | static int pid_offset; | 1960 | static int pid_offset; |
1844 | static int pid_size; | 1961 | static int pid_size; |
1962 | |||
1963 | return __parse_common(data, &pid_size, &pid_offset, | ||
1964 | "common_pid"); | ||
1965 | } | ||
1966 | |||
1967 | static int parse_common_pc(void *data) | ||
1968 | { | ||
1969 | static int pc_offset; | ||
1970 | static int pc_size; | ||
1971 | |||
1972 | return __parse_common(data, &pc_size, &pc_offset, | ||
1973 | "common_preempt_count"); | ||
1974 | } | ||
1975 | |||
1976 | static int parse_common_flags(void *data) | ||
1977 | { | ||
1978 | static int flags_offset; | ||
1979 | static int flags_size; | ||
1980 | |||
1981 | return __parse_common(data, &flags_size, &flags_offset, | ||
1982 | "common_flags"); | ||
1983 | } | ||
1984 | |||
1985 | static int parse_common_lock_depth(void *data) | ||
1986 | { | ||
1987 | static int ld_offset; | ||
1988 | static int ld_size; | ||
1845 | int ret; | 1989 | int ret; |
1846 | 1990 | ||
1847 | if (!pid_size) { | 1991 | ret = __parse_common(data, &ld_size, &ld_offset, |
1848 | ret = get_common_info("common_pid", | 1992 | "common_lock_depth"); |
1849 | &pid_offset, | 1993 | if (ret < 0) |
1850 | &pid_size); | 1994 | return -1; |
1851 | if (ret < 0) | ||
1852 | return ret; | ||
1853 | } | ||
1854 | 1995 | ||
1855 | return read_size(data + pid_offset, pid_size); | 1996 | return ret; |
1856 | } | 1997 | } |
1857 | 1998 | ||
1858 | struct event *trace_find_event(int id) | 1999 | struct event *trace_find_event(int id) |
@@ -1871,6 +2012,7 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1871 | { | 2012 | { |
1872 | unsigned long long val = 0; | 2013 | unsigned long long val = 0; |
1873 | unsigned long long left, right; | 2014 | unsigned long long left, right; |
2015 | struct print_arg *larg; | ||
1874 | 2016 | ||
1875 | switch (arg->type) { | 2017 | switch (arg->type) { |
1876 | case PRINT_NULL: | 2018 | case PRINT_NULL: |
@@ -1897,6 +2039,26 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1897 | return 0; | 2039 | return 0; |
1898 | break; | 2040 | break; |
1899 | case PRINT_OP: | 2041 | case PRINT_OP: |
2042 | if (strcmp(arg->op.op, "[") == 0) { | ||
2043 | /* | ||
2044 | * Arrays are special, since we don't want | ||
2045 | * to read the arg as is. | ||
2046 | */ | ||
2047 | if (arg->op.left->type != PRINT_FIELD) | ||
2048 | goto default_op; /* oops, all bets off */ | ||
2049 | larg = arg->op.left; | ||
2050 | if (!larg->field.field) { | ||
2051 | larg->field.field = | ||
2052 | find_any_field(event, larg->field.name); | ||
2053 | if (!larg->field.field) | ||
2054 | die("field %s not found", larg->field.name); | ||
2055 | } | ||
2056 | right = eval_num_arg(data, size, event, arg->op.right); | ||
2057 | val = read_size(data + larg->field.field->offset + | ||
2058 | right * long_size, long_size); | ||
2059 | break; | ||
2060 | } | ||
2061 | default_op: | ||
1900 | left = eval_num_arg(data, size, event, arg->op.left); | 2062 | left = eval_num_arg(data, size, event, arg->op.left); |
1901 | right = eval_num_arg(data, size, event, arg->op.right); | 2063 | right = eval_num_arg(data, size, event, arg->op.right); |
1902 | switch (arg->op.op[0]) { | 2064 | switch (arg->op.op[0]) { |
@@ -1947,6 +2109,12 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1947 | die("unknown op '%s'", arg->op.op); | 2109 | die("unknown op '%s'", arg->op.op); |
1948 | val = left == right; | 2110 | val = left == right; |
1949 | break; | 2111 | break; |
2112 | case '-': | ||
2113 | val = left - right; | ||
2114 | break; | ||
2115 | case '+': | ||
2116 | val = left + right; | ||
2117 | break; | ||
1950 | default: | 2118 | default: |
1951 | die("unknown op '%s'", arg->op.op); | 2119 | die("unknown op '%s'", arg->op.op); |
1952 | } | 2120 | } |
@@ -2145,8 +2313,9 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
2145 | case 'u': | 2313 | case 'u': |
2146 | case 'x': | 2314 | case 'x': |
2147 | case 'i': | 2315 | case 'i': |
2148 | bptr = (void *)(((unsigned long)bptr + (long_size - 1)) & | 2316 | /* the pointers are always 4 bytes aligned */ |
2149 | ~(long_size - 1)); | 2317 | bptr = (void *)(((unsigned long)bptr + 3) & |
2318 | ~3); | ||
2150 | switch (ls) { | 2319 | switch (ls) { |
2151 | case 0: | 2320 | case 0: |
2152 | case 1: | 2321 | case 1: |
@@ -2270,7 +2439,27 @@ static void pretty_print(void *data, int size, struct event *event) | |||
2270 | 2439 | ||
2271 | for (; *ptr; ptr++) { | 2440 | for (; *ptr; ptr++) { |
2272 | ls = 0; | 2441 | ls = 0; |
2273 | if (*ptr == '%') { | 2442 | if (*ptr == '\\') { |
2443 | ptr++; | ||
2444 | switch (*ptr) { | ||
2445 | case 'n': | ||
2446 | printf("\n"); | ||
2447 | break; | ||
2448 | case 't': | ||
2449 | printf("\t"); | ||
2450 | break; | ||
2451 | case 'r': | ||
2452 | printf("\r"); | ||
2453 | break; | ||
2454 | case '\\': | ||
2455 | printf("\\"); | ||
2456 | break; | ||
2457 | default: | ||
2458 | printf("%c", *ptr); | ||
2459 | break; | ||
2460 | } | ||
2461 | |||
2462 | } else if (*ptr == '%') { | ||
2274 | saveptr = ptr; | 2463 | saveptr = ptr; |
2275 | show_func = 0; | 2464 | show_func = 0; |
2276 | cont_process: | 2465 | cont_process: |
@@ -2377,6 +2566,41 @@ static inline int log10_cpu(int nb) | |||
2377 | return 1; | 2566 | return 1; |
2378 | } | 2567 | } |
2379 | 2568 | ||
2569 | static void print_lat_fmt(void *data, int size __unused) | ||
2570 | { | ||
2571 | unsigned int lat_flags; | ||
2572 | unsigned int pc; | ||
2573 | int lock_depth; | ||
2574 | int hardirq; | ||
2575 | int softirq; | ||
2576 | |||
2577 | lat_flags = parse_common_flags(data); | ||
2578 | pc = parse_common_pc(data); | ||
2579 | lock_depth = parse_common_lock_depth(data); | ||
2580 | |||
2581 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | ||
2582 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | ||
2583 | |||
2584 | printf("%c%c%c", | ||
2585 | (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : | ||
2586 | (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? | ||
2587 | 'X' : '.', | ||
2588 | (lat_flags & TRACE_FLAG_NEED_RESCHED) ? | ||
2589 | 'N' : '.', | ||
2590 | (hardirq && softirq) ? 'H' : | ||
2591 | hardirq ? 'h' : softirq ? 's' : '.'); | ||
2592 | |||
2593 | if (pc) | ||
2594 | printf("%x", pc); | ||
2595 | else | ||
2596 | printf("."); | ||
2597 | |||
2598 | if (lock_depth < 0) | ||
2599 | printf("."); | ||
2600 | else | ||
2601 | printf("%d", lock_depth); | ||
2602 | } | ||
2603 | |||
2380 | /* taken from Linux, written by Frederic Weisbecker */ | 2604 | /* taken from Linux, written by Frederic Weisbecker */ |
2381 | static void print_graph_cpu(int cpu) | 2605 | static void print_graph_cpu(int cpu) |
2382 | { | 2606 | { |
@@ -2620,6 +2844,11 @@ pretty_print_func_ent(void *data, int size, struct event *event, | |||
2620 | 2844 | ||
2621 | printf(" | "); | 2845 | printf(" | "); |
2622 | 2846 | ||
2847 | if (latency_format) { | ||
2848 | print_lat_fmt(data, size); | ||
2849 | printf(" | "); | ||
2850 | } | ||
2851 | |||
2623 | field = find_field(event, "func"); | 2852 | field = find_field(event, "func"); |
2624 | if (!field) | 2853 | if (!field) |
2625 | die("function entry does not have func field"); | 2854 | die("function entry does not have func field"); |
@@ -2663,6 +2892,11 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event, | |||
2663 | 2892 | ||
2664 | printf(" | "); | 2893 | printf(" | "); |
2665 | 2894 | ||
2895 | if (latency_format) { | ||
2896 | print_lat_fmt(data, size); | ||
2897 | printf(" | "); | ||
2898 | } | ||
2899 | |||
2666 | field = find_field(event, "rettime"); | 2900 | field = find_field(event, "rettime"); |
2667 | if (!field) | 2901 | if (!field) |
2668 | die("can't find rettime in return graph"); | 2902 | die("can't find rettime in return graph"); |
@@ -2724,7 +2958,7 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, | |||
2724 | 2958 | ||
2725 | event = trace_find_event(type); | 2959 | event = trace_find_event(type); |
2726 | if (!event) { | 2960 | if (!event) { |
2727 | printf("ug! no event found for type %d\n", type); | 2961 | warning("ug! no event found for type %d", type); |
2728 | return; | 2962 | return; |
2729 | } | 2963 | } |
2730 | 2964 | ||
@@ -2734,9 +2968,20 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, | |||
2734 | return pretty_print_func_graph(data, size, event, cpu, | 2968 | return pretty_print_func_graph(data, size, event, cpu, |
2735 | pid, comm, secs, usecs); | 2969 | pid, comm, secs, usecs); |
2736 | 2970 | ||
2737 | printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ", | 2971 | if (latency_format) { |
2738 | comm, pid, cpu, | 2972 | printf("%8.8s-%-5d %3d", |
2739 | secs, nsecs, event->name); | 2973 | comm, pid, cpu); |
2974 | print_lat_fmt(data, size); | ||
2975 | } else | ||
2976 | printf("%16s-%-5d [%03d]", comm, pid, cpu); | ||
2977 | |||
2978 | printf(" %5lu.%06lu: %s: ", secs, usecs, event->name); | ||
2979 | |||
2980 | if (event->flags & EVENT_FL_FAILED) { | ||
2981 | printf("EVENT '%s' FAILED TO PARSE\n", | ||
2982 | event->name); | ||
2983 | return; | ||
2984 | } | ||
2740 | 2985 | ||
2741 | pretty_print(data, size, event); | 2986 | pretty_print(data, size, event); |
2742 | printf("\n"); | 2987 | printf("\n"); |
@@ -2807,46 +3052,71 @@ static void print_args(struct print_arg *args) | |||
2807 | } | 3052 | } |
2808 | } | 3053 | } |
2809 | 3054 | ||
2810 | static void parse_header_field(char *type, | 3055 | static void parse_header_field(const char *field, |
2811 | int *offset, int *size) | 3056 | int *offset, int *size) |
2812 | { | 3057 | { |
2813 | char *token; | 3058 | char *token; |
3059 | int type; | ||
2814 | 3060 | ||
2815 | if (read_expected(EVENT_ITEM, (char *)"field") < 0) | 3061 | if (read_expected(EVENT_ITEM, "field") < 0) |
2816 | return; | 3062 | return; |
2817 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3063 | if (read_expected(EVENT_OP, ":") < 0) |
2818 | return; | 3064 | return; |
3065 | |||
2819 | /* type */ | 3066 | /* type */ |
2820 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3067 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2821 | return; | 3068 | goto fail; |
2822 | free_token(token); | 3069 | free_token(token); |
2823 | 3070 | ||
2824 | if (read_expected(EVENT_ITEM, type) < 0) | 3071 | if (read_expected(EVENT_ITEM, field) < 0) |
2825 | return; | 3072 | return; |
2826 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3073 | if (read_expected(EVENT_OP, ";") < 0) |
2827 | return; | 3074 | return; |
2828 | if (read_expected(EVENT_ITEM, (char *)"offset") < 0) | 3075 | if (read_expected(EVENT_ITEM, "offset") < 0) |
2829 | return; | 3076 | return; |
2830 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3077 | if (read_expected(EVENT_OP, ":") < 0) |
2831 | return; | 3078 | return; |
2832 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3079 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2833 | return; | 3080 | goto fail; |
2834 | *offset = atoi(token); | 3081 | *offset = atoi(token); |
2835 | free_token(token); | 3082 | free_token(token); |
2836 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3083 | if (read_expected(EVENT_OP, ";") < 0) |
2837 | return; | 3084 | return; |
2838 | if (read_expected(EVENT_ITEM, (char *)"size") < 0) | 3085 | if (read_expected(EVENT_ITEM, "size") < 0) |
2839 | return; | 3086 | return; |
2840 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3087 | if (read_expected(EVENT_OP, ":") < 0) |
2841 | return; | 3088 | return; |
2842 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3089 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2843 | return; | 3090 | goto fail; |
2844 | *size = atoi(token); | 3091 | *size = atoi(token); |
2845 | free_token(token); | 3092 | free_token(token); |
2846 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3093 | if (read_expected(EVENT_OP, ";") < 0) |
2847 | return; | ||
2848 | if (read_expect_type(EVENT_NEWLINE, &token) < 0) | ||
2849 | return; | 3094 | return; |
3095 | type = read_token(&token); | ||
3096 | if (type != EVENT_NEWLINE) { | ||
3097 | /* newer versions of the kernel have a "signed" type */ | ||
3098 | if (type != EVENT_ITEM) | ||
3099 | goto fail; | ||
3100 | |||
3101 | if (strcmp(token, "signed") != 0) | ||
3102 | goto fail; | ||
3103 | |||
3104 | free_token(token); | ||
3105 | |||
3106 | if (read_expected(EVENT_OP, ":") < 0) | ||
3107 | return; | ||
3108 | |||
3109 | if (read_expect_type(EVENT_ITEM, &token)) | ||
3110 | goto fail; | ||
3111 | |||
3112 | free_token(token); | ||
3113 | if (read_expected(EVENT_OP, ";") < 0) | ||
3114 | return; | ||
3115 | |||
3116 | if (read_expect_type(EVENT_NEWLINE, &token)) | ||
3117 | goto fail; | ||
3118 | } | ||
3119 | fail: | ||
2850 | free_token(token); | 3120 | free_token(token); |
2851 | } | 3121 | } |
2852 | 3122 | ||
@@ -2854,11 +3124,11 @@ int parse_header_page(char *buf, unsigned long size) | |||
2854 | { | 3124 | { |
2855 | init_input_buf(buf, size); | 3125 | init_input_buf(buf, size); |
2856 | 3126 | ||
2857 | parse_header_field((char *)"timestamp", &header_page_ts_offset, | 3127 | parse_header_field("timestamp", &header_page_ts_offset, |
2858 | &header_page_ts_size); | 3128 | &header_page_ts_size); |
2859 | parse_header_field((char *)"commit", &header_page_size_offset, | 3129 | parse_header_field("commit", &header_page_size_offset, |
2860 | &header_page_size_size); | 3130 | &header_page_size_size); |
2861 | parse_header_field((char *)"data", &header_page_data_offset, | 3131 | parse_header_field("data", &header_page_data_offset, |
2862 | &header_page_data_size); | 3132 | &header_page_data_size); |
2863 | 3133 | ||
2864 | return 0; | 3134 | return 0; |
@@ -2909,6 +3179,9 @@ int parse_ftrace_file(char *buf, unsigned long size) | |||
2909 | if (ret < 0) | 3179 | if (ret < 0) |
2910 | die("failed to read ftrace event print fmt"); | 3180 | die("failed to read ftrace event print fmt"); |
2911 | 3181 | ||
3182 | /* New ftrace handles args */ | ||
3183 | if (ret > 0) | ||
3184 | return 0; | ||
2912 | /* | 3185 | /* |
2913 | * The arguments for ftrace files are parsed by the fields. | 3186 | * The arguments for ftrace files are parsed by the fields. |
2914 | * Set up the fields as their arguments. | 3187 | * Set up the fields as their arguments. |
@@ -2926,7 +3199,7 @@ int parse_ftrace_file(char *buf, unsigned long size) | |||
2926 | return 0; | 3199 | return 0; |
2927 | } | 3200 | } |
2928 | 3201 | ||
2929 | int parse_event_file(char *buf, unsigned long size, char *system__unused __unused) | 3202 | int parse_event_file(char *buf, unsigned long size, char *sys) |
2930 | { | 3203 | { |
2931 | struct event *event; | 3204 | struct event *event; |
2932 | int ret; | 3205 | int ret; |
@@ -2946,12 +3219,18 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse | |||
2946 | die("failed to read event id"); | 3219 | die("failed to read event id"); |
2947 | 3220 | ||
2948 | ret = event_read_format(event); | 3221 | ret = event_read_format(event); |
2949 | if (ret < 0) | 3222 | if (ret < 0) { |
2950 | die("failed to read event format"); | 3223 | warning("failed to read event format for %s", event->name); |
3224 | goto event_failed; | ||
3225 | } | ||
2951 | 3226 | ||
2952 | ret = event_read_print(event); | 3227 | ret = event_read_print(event); |
2953 | if (ret < 0) | 3228 | if (ret < 0) { |
2954 | die("failed to read event print fmt"); | 3229 | warning("failed to read event print fmt for %s", event->name); |
3230 | goto event_failed; | ||
3231 | } | ||
3232 | |||
3233 | event->system = strdup(sys); | ||
2955 | 3234 | ||
2956 | #define PRINT_ARGS 0 | 3235 | #define PRINT_ARGS 0 |
2957 | if (PRINT_ARGS && event->print_fmt.args) | 3236 | if (PRINT_ARGS && event->print_fmt.args) |
@@ -2959,6 +3238,12 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse | |||
2959 | 3238 | ||
2960 | add_event(event); | 3239 | add_event(event); |
2961 | return 0; | 3240 | return 0; |
3241 | |||
3242 | event_failed: | ||
3243 | event->flags |= EVENT_FL_FAILED; | ||
3244 | /* still add it even if it failed */ | ||
3245 | add_event(event); | ||
3246 | return -1; | ||
2962 | } | 3247 | } |
2963 | 3248 | ||
2964 | void parse_set_info(int nr_cpus, int long_sz) | 3249 | void parse_set_info(int nr_cpus, int long_sz) |