diff options
Diffstat (limited to 'tools/perf/util/trace-event-parse.c')
-rw-r--r-- | tools/perf/util/trace-event-parse.c | 573 |
1 files changed, 442 insertions, 131 deletions
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index 55c9659a56e2..0302405aa2ca 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
@@ -40,12 +40,19 @@ 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; |
46 | 48 | ||
47 | static int cpus; | 49 | static int cpus; |
48 | static int long_size; | 50 | static int long_size; |
51 | static int is_flag_field; | ||
52 | static int is_symbolic_field; | ||
53 | |||
54 | static struct format_field * | ||
55 | find_any_field(struct event *event, const char *name); | ||
49 | 56 | ||
50 | static void init_input_buf(char *buf, unsigned long long size) | 57 | static void init_input_buf(char *buf, unsigned long long size) |
51 | { | 58 | { |
@@ -284,18 +291,19 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
284 | char *line; | 291 | char *line; |
285 | char *next = NULL; | 292 | char *next = NULL; |
286 | char *addr_str; | 293 | char *addr_str; |
287 | int ret; | ||
288 | int i; | 294 | int i; |
289 | 295 | ||
290 | line = strtok_r(file, "\n", &next); | 296 | line = strtok_r(file, "\n", &next); |
291 | while (line) { | 297 | while (line) { |
298 | addr_str = strsep(&line, ":"); | ||
299 | if (!line) { | ||
300 | warning("error parsing print strings"); | ||
301 | break; | ||
302 | } | ||
292 | item = malloc_or_die(sizeof(*item)); | 303 | 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); | 304 | item->addr = strtoull(addr_str, NULL, 16); |
297 | free(addr_str); | 305 | /* fmt still has a space, skip it */ |
298 | 306 | item->printk = strdup(line+1); | |
299 | item->next = list; | 307 | item->next = list; |
300 | list = item; | 308 | list = item; |
301 | line = strtok_r(NULL, "\n", &next); | 309 | line = strtok_r(NULL, "\n", &next); |
@@ -522,7 +530,10 @@ static enum event_type __read_token(char **tok) | |||
522 | last_ch = ch; | 530 | last_ch = ch; |
523 | ch = __read_char(); | 531 | ch = __read_char(); |
524 | buf[i++] = ch; | 532 | buf[i++] = ch; |
525 | } while (ch != quote_ch && last_ch != '\\'); | 533 | /* the '\' '\' will cancel itself */ |
534 | if (ch == '\\' && last_ch == '\\') | ||
535 | last_ch = 0; | ||
536 | } while (ch != quote_ch || last_ch == '\\'); | ||
526 | /* remove the last quote */ | 537 | /* remove the last quote */ |
527 | i--; | 538 | i--; |
528 | goto out; | 539 | goto out; |
@@ -610,7 +621,7 @@ static enum event_type read_token_item(char **tok) | |||
610 | static int test_type(enum event_type type, enum event_type expect) | 621 | static int test_type(enum event_type type, enum event_type expect) |
611 | { | 622 | { |
612 | if (type != expect) { | 623 | if (type != expect) { |
613 | die("Error: expected type %d but read %d", | 624 | warning("Error: expected type %d but read %d", |
614 | expect, type); | 625 | expect, type); |
615 | return -1; | 626 | return -1; |
616 | } | 627 | } |
@@ -621,13 +632,13 @@ static int test_type_token(enum event_type type, char *token, | |||
621 | enum event_type expect, const char *expect_tok) | 632 | enum event_type expect, const char *expect_tok) |
622 | { | 633 | { |
623 | if (type != expect) { | 634 | if (type != expect) { |
624 | die("Error: expected type %d but read %d", | 635 | warning("Error: expected type %d but read %d", |
625 | expect, type); | 636 | expect, type); |
626 | return -1; | 637 | return -1; |
627 | } | 638 | } |
628 | 639 | ||
629 | if (strcmp(token, expect_tok) != 0) { | 640 | if (strcmp(token, expect_tok) != 0) { |
630 | die("Error: expected '%s' but read '%s'", | 641 | warning("Error: expected '%s' but read '%s'", |
631 | expect_tok, token); | 642 | expect_tok, token); |
632 | return -1; | 643 | return -1; |
633 | } | 644 | } |
@@ -665,7 +676,7 @@ static int __read_expected(enum event_type expect, const char *str, int newline_ | |||
665 | 676 | ||
666 | free_token(token); | 677 | free_token(token); |
667 | 678 | ||
668 | return 0; | 679 | return ret; |
669 | } | 680 | } |
670 | 681 | ||
671 | static int read_expected(enum event_type expect, const char *str) | 682 | static int read_expected(enum event_type expect, const char *str) |
@@ -682,10 +693,10 @@ static char *event_read_name(void) | |||
682 | { | 693 | { |
683 | char *token; | 694 | char *token; |
684 | 695 | ||
685 | if (read_expected(EVENT_ITEM, (char *)"name") < 0) | 696 | if (read_expected(EVENT_ITEM, "name") < 0) |
686 | return NULL; | 697 | return NULL; |
687 | 698 | ||
688 | if (read_expected(EVENT_OP, (char *)":") < 0) | 699 | if (read_expected(EVENT_OP, ":") < 0) |
689 | return NULL; | 700 | return NULL; |
690 | 701 | ||
691 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 702 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -703,10 +714,10 @@ static int event_read_id(void) | |||
703 | char *token; | 714 | char *token; |
704 | int id; | 715 | int id; |
705 | 716 | ||
706 | if (read_expected_item(EVENT_ITEM, (char *)"ID") < 0) | 717 | if (read_expected_item(EVENT_ITEM, "ID") < 0) |
707 | return -1; | 718 | return -1; |
708 | 719 | ||
709 | if (read_expected(EVENT_OP, (char *)":") < 0) | 720 | if (read_expected(EVENT_OP, ":") < 0) |
710 | return -1; | 721 | return -1; |
711 | 722 | ||
712 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 723 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -721,6 +732,24 @@ static int event_read_id(void) | |||
721 | return -1; | 732 | return -1; |
722 | } | 733 | } |
723 | 734 | ||
735 | static int field_is_string(struct format_field *field) | ||
736 | { | ||
737 | if ((field->flags & FIELD_IS_ARRAY) && | ||
738 | (!strstr(field->type, "char") || !strstr(field->type, "u8") || | ||
739 | !strstr(field->type, "s8"))) | ||
740 | return 1; | ||
741 | |||
742 | return 0; | ||
743 | } | ||
744 | |||
745 | static int field_is_dynamic(struct format_field *field) | ||
746 | { | ||
747 | if (!strcmp(field->type, "__data_loc")) | ||
748 | return 1; | ||
749 | |||
750 | return 0; | ||
751 | } | ||
752 | |||
724 | static int event_read_fields(struct event *event, struct format_field **fields) | 753 | static int event_read_fields(struct event *event, struct format_field **fields) |
725 | { | 754 | { |
726 | struct format_field *field = NULL; | 755 | struct format_field *field = NULL; |
@@ -738,7 +767,7 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
738 | 767 | ||
739 | count++; | 768 | count++; |
740 | 769 | ||
741 | if (test_type_token(type, token, EVENT_ITEM, (char *)"field")) | 770 | if (test_type_token(type, token, EVENT_ITEM, "field")) |
742 | goto fail; | 771 | goto fail; |
743 | free_token(token); | 772 | free_token(token); |
744 | 773 | ||
@@ -753,7 +782,7 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
753 | type = read_token(&token); | 782 | type = read_token(&token); |
754 | } | 783 | } |
755 | 784 | ||
756 | if (test_type_token(type, token, EVENT_OP, (char *)":") < 0) | 785 | if (test_type_token(type, token, EVENT_OP, ":") < 0) |
757 | return -1; | 786 | return -1; |
758 | 787 | ||
759 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 788 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -865,14 +894,20 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
865 | free(brackets); | 894 | free(brackets); |
866 | } | 895 | } |
867 | 896 | ||
868 | if (test_type_token(type, token, EVENT_OP, (char *)";")) | 897 | if (field_is_string(field)) { |
898 | field->flags |= FIELD_IS_STRING; | ||
899 | if (field_is_dynamic(field)) | ||
900 | field->flags |= FIELD_IS_DYNAMIC; | ||
901 | } | ||
902 | |||
903 | if (test_type_token(type, token, EVENT_OP, ";")) | ||
869 | goto fail; | 904 | goto fail; |
870 | free_token(token); | 905 | free_token(token); |
871 | 906 | ||
872 | if (read_expected(EVENT_ITEM, (char *)"offset") < 0) | 907 | if (read_expected(EVENT_ITEM, "offset") < 0) |
873 | goto fail_expect; | 908 | goto fail_expect; |
874 | 909 | ||
875 | if (read_expected(EVENT_OP, (char *)":") < 0) | 910 | if (read_expected(EVENT_OP, ":") < 0) |
876 | goto fail_expect; | 911 | goto fail_expect; |
877 | 912 | ||
878 | if (read_expect_type(EVENT_ITEM, &token)) | 913 | if (read_expect_type(EVENT_ITEM, &token)) |
@@ -880,13 +915,13 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
880 | field->offset = strtoul(token, NULL, 0); | 915 | field->offset = strtoul(token, NULL, 0); |
881 | free_token(token); | 916 | free_token(token); |
882 | 917 | ||
883 | if (read_expected(EVENT_OP, (char *)";") < 0) | 918 | if (read_expected(EVENT_OP, ";") < 0) |
884 | goto fail_expect; | 919 | goto fail_expect; |
885 | 920 | ||
886 | if (read_expected(EVENT_ITEM, (char *)"size") < 0) | 921 | if (read_expected(EVENT_ITEM, "size") < 0) |
887 | goto fail_expect; | 922 | goto fail_expect; |
888 | 923 | ||
889 | if (read_expected(EVENT_OP, (char *)":") < 0) | 924 | if (read_expected(EVENT_OP, ":") < 0) |
890 | goto fail_expect; | 925 | goto fail_expect; |
891 | 926 | ||
892 | if (read_expect_type(EVENT_ITEM, &token)) | 927 | if (read_expect_type(EVENT_ITEM, &token)) |
@@ -894,11 +929,34 @@ static int event_read_fields(struct event *event, struct format_field **fields) | |||
894 | field->size = strtoul(token, NULL, 0); | 929 | field->size = strtoul(token, NULL, 0); |
895 | free_token(token); | 930 | free_token(token); |
896 | 931 | ||
897 | if (read_expected(EVENT_OP, (char *)";") < 0) | 932 | if (read_expected(EVENT_OP, ";") < 0) |
898 | goto fail_expect; | 933 | goto fail_expect; |
899 | 934 | ||
900 | if (read_expect_type(EVENT_NEWLINE, &token) < 0) | 935 | type = read_token(&token); |
901 | goto fail; | 936 | if (type != EVENT_NEWLINE) { |
937 | /* newer versions of the kernel have a "signed" type */ | ||
938 | if (test_type_token(type, token, EVENT_ITEM, "signed")) | ||
939 | goto fail; | ||
940 | |||
941 | free_token(token); | ||
942 | |||
943 | if (read_expected(EVENT_OP, ":") < 0) | ||
944 | goto fail_expect; | ||
945 | |||
946 | if (read_expect_type(EVENT_ITEM, &token)) | ||
947 | goto fail; | ||
948 | |||
949 | if (strtoul(token, NULL, 0)) | ||
950 | field->flags |= FIELD_IS_SIGNED; | ||
951 | |||
952 | free_token(token); | ||
953 | if (read_expected(EVENT_OP, ";") < 0) | ||
954 | goto fail_expect; | ||
955 | |||
956 | if (read_expect_type(EVENT_NEWLINE, &token)) | ||
957 | goto fail; | ||
958 | } | ||
959 | |||
902 | free_token(token); | 960 | free_token(token); |
903 | 961 | ||
904 | *fields = field; | 962 | *fields = field; |
@@ -921,10 +979,10 @@ static int event_read_format(struct event *event) | |||
921 | char *token; | 979 | char *token; |
922 | int ret; | 980 | int ret; |
923 | 981 | ||
924 | if (read_expected_item(EVENT_ITEM, (char *)"format") < 0) | 982 | if (read_expected_item(EVENT_ITEM, "format") < 0) |
925 | return -1; | 983 | return -1; |
926 | 984 | ||
927 | if (read_expected(EVENT_OP, (char *)":") < 0) | 985 | if (read_expected(EVENT_OP, ":") < 0) |
928 | return -1; | 986 | return -1; |
929 | 987 | ||
930 | if (read_expect_type(EVENT_NEWLINE, &token)) | 988 | if (read_expect_type(EVENT_NEWLINE, &token)) |
@@ -984,7 +1042,7 @@ process_cond(struct event *event, struct print_arg *top, char **tok) | |||
984 | 1042 | ||
985 | *tok = NULL; | 1043 | *tok = NULL; |
986 | type = process_arg(event, left, &token); | 1044 | type = process_arg(event, left, &token); |
987 | if (test_type_token(type, token, EVENT_OP, (char *)":")) | 1045 | if (test_type_token(type, token, EVENT_OP, ":")) |
988 | goto out_free; | 1046 | goto out_free; |
989 | 1047 | ||
990 | arg->op.op = token; | 1048 | arg->op.op = token; |
@@ -1004,6 +1062,35 @@ out_free: | |||
1004 | return EVENT_ERROR; | 1062 | return EVENT_ERROR; |
1005 | } | 1063 | } |
1006 | 1064 | ||
1065 | static enum event_type | ||
1066 | process_array(struct event *event, struct print_arg *top, char **tok) | ||
1067 | { | ||
1068 | struct print_arg *arg; | ||
1069 | enum event_type type; | ||
1070 | char *token = NULL; | ||
1071 | |||
1072 | arg = malloc_or_die(sizeof(*arg)); | ||
1073 | memset(arg, 0, sizeof(*arg)); | ||
1074 | |||
1075 | *tok = NULL; | ||
1076 | type = process_arg(event, arg, &token); | ||
1077 | if (test_type_token(type, token, EVENT_OP, "]")) | ||
1078 | goto out_free; | ||
1079 | |||
1080 | top->op.right = arg; | ||
1081 | |||
1082 | free_token(token); | ||
1083 | type = read_token_item(&token); | ||
1084 | *tok = token; | ||
1085 | |||
1086 | return type; | ||
1087 | |||
1088 | out_free: | ||
1089 | free_token(*tok); | ||
1090 | free_arg(arg); | ||
1091 | return EVENT_ERROR; | ||
1092 | } | ||
1093 | |||
1007 | static int get_op_prio(char *op) | 1094 | static int get_op_prio(char *op) |
1008 | { | 1095 | { |
1009 | if (!op[1]) { | 1096 | if (!op[1]) { |
@@ -1128,6 +1215,8 @@ process_op(struct event *event, struct print_arg *arg, char **tok) | |||
1128 | strcmp(token, "*") == 0 || | 1215 | strcmp(token, "*") == 0 || |
1129 | strcmp(token, "^") == 0 || | 1216 | strcmp(token, "^") == 0 || |
1130 | strcmp(token, "/") == 0 || | 1217 | strcmp(token, "/") == 0 || |
1218 | strcmp(token, "<") == 0 || | ||
1219 | strcmp(token, ">") == 0 || | ||
1131 | strcmp(token, "==") == 0 || | 1220 | strcmp(token, "==") == 0 || |
1132 | strcmp(token, "!=") == 0) { | 1221 | strcmp(token, "!=") == 0) { |
1133 | 1222 | ||
@@ -1144,17 +1233,46 @@ process_op(struct event *event, struct print_arg *arg, char **tok) | |||
1144 | 1233 | ||
1145 | right = malloc_or_die(sizeof(*right)); | 1234 | right = malloc_or_die(sizeof(*right)); |
1146 | 1235 | ||
1147 | type = process_arg(event, right, tok); | 1236 | type = read_token_item(&token); |
1237 | *tok = token; | ||
1238 | |||
1239 | /* could just be a type pointer */ | ||
1240 | if ((strcmp(arg->op.op, "*") == 0) && | ||
1241 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { | ||
1242 | if (left->type != PRINT_ATOM) | ||
1243 | die("bad pointer type"); | ||
1244 | left->atom.atom = realloc(left->atom.atom, | ||
1245 | sizeof(left->atom.atom) + 3); | ||
1246 | strcat(left->atom.atom, " *"); | ||
1247 | *arg = *left; | ||
1248 | free(arg); | ||
1249 | |||
1250 | return type; | ||
1251 | } | ||
1252 | |||
1253 | type = process_arg_token(event, right, tok, type); | ||
1148 | 1254 | ||
1149 | arg->op.right = right; | 1255 | arg->op.right = right; |
1150 | 1256 | ||
1257 | } else if (strcmp(token, "[") == 0) { | ||
1258 | |||
1259 | left = malloc_or_die(sizeof(*left)); | ||
1260 | *left = *arg; | ||
1261 | |||
1262 | arg->type = PRINT_OP; | ||
1263 | arg->op.op = token; | ||
1264 | arg->op.left = left; | ||
1265 | |||
1266 | arg->op.prio = 0; | ||
1267 | type = process_array(event, arg, tok); | ||
1268 | |||
1151 | } else { | 1269 | } else { |
1152 | die("unknown op '%s'", token); | 1270 | warning("unknown op '%s'", token); |
1271 | event->flags |= EVENT_FL_FAILED; | ||
1153 | /* the arg is now the left side */ | 1272 | /* the arg is now the left side */ |
1154 | return EVENT_NONE; | 1273 | return EVENT_NONE; |
1155 | } | 1274 | } |
1156 | 1275 | ||
1157 | |||
1158 | if (type == EVENT_OP) { | 1276 | if (type == EVENT_OP) { |
1159 | int prio; | 1277 | int prio; |
1160 | 1278 | ||
@@ -1178,7 +1296,7 @@ process_entry(struct event *event __unused, struct print_arg *arg, | |||
1178 | char *field; | 1296 | char *field; |
1179 | char *token; | 1297 | char *token; |
1180 | 1298 | ||
1181 | if (read_expected(EVENT_OP, (char *)"->") < 0) | 1299 | if (read_expected(EVENT_OP, "->") < 0) |
1182 | return EVENT_ERROR; | 1300 | return EVENT_ERROR; |
1183 | 1301 | ||
1184 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 1302 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -1188,6 +1306,16 @@ process_entry(struct event *event __unused, struct print_arg *arg, | |||
1188 | arg->type = PRINT_FIELD; | 1306 | arg->type = PRINT_FIELD; |
1189 | arg->field.name = field; | 1307 | arg->field.name = field; |
1190 | 1308 | ||
1309 | if (is_flag_field) { | ||
1310 | arg->field.field = find_any_field(event, arg->field.name); | ||
1311 | arg->field.field->flags |= FIELD_IS_FLAG; | ||
1312 | is_flag_field = 0; | ||
1313 | } else if (is_symbolic_field) { | ||
1314 | arg->field.field = find_any_field(event, arg->field.name); | ||
1315 | arg->field.field->flags |= FIELD_IS_SYMBOLIC; | ||
1316 | is_symbolic_field = 0; | ||
1317 | } | ||
1318 | |||
1191 | type = read_token(&token); | 1319 | type = read_token(&token); |
1192 | *tok = token; | 1320 | *tok = token; |
1193 | 1321 | ||
@@ -1338,14 +1466,14 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok) | |||
1338 | do { | 1466 | do { |
1339 | free_token(token); | 1467 | free_token(token); |
1340 | type = read_token_item(&token); | 1468 | type = read_token_item(&token); |
1341 | if (test_type_token(type, token, EVENT_OP, (char *)"{")) | 1469 | if (test_type_token(type, token, EVENT_OP, "{")) |
1342 | break; | 1470 | break; |
1343 | 1471 | ||
1344 | arg = malloc_or_die(sizeof(*arg)); | 1472 | arg = malloc_or_die(sizeof(*arg)); |
1345 | 1473 | ||
1346 | free_token(token); | 1474 | free_token(token); |
1347 | type = process_arg(event, arg, &token); | 1475 | type = process_arg(event, arg, &token); |
1348 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1476 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1349 | goto out_free; | 1477 | goto out_free; |
1350 | 1478 | ||
1351 | field = malloc_or_die(sizeof(*field)); | 1479 | field = malloc_or_die(sizeof(*field)); |
@@ -1356,7 +1484,7 @@ process_fields(struct event *event, struct print_flag_sym **list, char **tok) | |||
1356 | 1484 | ||
1357 | free_token(token); | 1485 | free_token(token); |
1358 | type = process_arg(event, arg, &token); | 1486 | type = process_arg(event, arg, &token); |
1359 | if (test_type_token(type, token, EVENT_OP, (char *)"}")) | 1487 | if (test_type_token(type, token, EVENT_OP, "}")) |
1360 | goto out_free; | 1488 | goto out_free; |
1361 | 1489 | ||
1362 | value = arg_eval(arg); | 1490 | value = arg_eval(arg); |
@@ -1391,13 +1519,13 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) | |||
1391 | memset(arg, 0, sizeof(*arg)); | 1519 | memset(arg, 0, sizeof(*arg)); |
1392 | arg->type = PRINT_FLAGS; | 1520 | arg->type = PRINT_FLAGS; |
1393 | 1521 | ||
1394 | if (read_expected_item(EVENT_DELIM, (char *)"(") < 0) | 1522 | if (read_expected_item(EVENT_DELIM, "(") < 0) |
1395 | return EVENT_ERROR; | 1523 | return EVENT_ERROR; |
1396 | 1524 | ||
1397 | field = malloc_or_die(sizeof(*field)); | 1525 | field = malloc_or_die(sizeof(*field)); |
1398 | 1526 | ||
1399 | type = process_arg(event, field, &token); | 1527 | type = process_arg(event, field, &token); |
1400 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1528 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1401 | goto out_free; | 1529 | goto out_free; |
1402 | 1530 | ||
1403 | arg->flags.field = field; | 1531 | arg->flags.field = field; |
@@ -1408,11 +1536,11 @@ process_flags(struct event *event, struct print_arg *arg, char **tok) | |||
1408 | type = read_token_item(&token); | 1536 | type = read_token_item(&token); |
1409 | } | 1537 | } |
1410 | 1538 | ||
1411 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1539 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1412 | goto out_free; | 1540 | goto out_free; |
1413 | 1541 | ||
1414 | type = process_fields(event, &arg->flags.flags, &token); | 1542 | type = process_fields(event, &arg->flags.flags, &token); |
1415 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) | 1543 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
1416 | goto out_free; | 1544 | goto out_free; |
1417 | 1545 | ||
1418 | free_token(token); | 1546 | free_token(token); |
@@ -1434,19 +1562,19 @@ process_symbols(struct event *event, struct print_arg *arg, char **tok) | |||
1434 | memset(arg, 0, sizeof(*arg)); | 1562 | memset(arg, 0, sizeof(*arg)); |
1435 | arg->type = PRINT_SYMBOL; | 1563 | arg->type = PRINT_SYMBOL; |
1436 | 1564 | ||
1437 | if (read_expected_item(EVENT_DELIM, (char *)"(") < 0) | 1565 | if (read_expected_item(EVENT_DELIM, "(") < 0) |
1438 | return EVENT_ERROR; | 1566 | return EVENT_ERROR; |
1439 | 1567 | ||
1440 | field = malloc_or_die(sizeof(*field)); | 1568 | field = malloc_or_die(sizeof(*field)); |
1441 | 1569 | ||
1442 | type = process_arg(event, field, &token); | 1570 | type = process_arg(event, field, &token); |
1443 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1571 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
1444 | goto out_free; | 1572 | goto out_free; |
1445 | 1573 | ||
1446 | arg->symbol.field = field; | 1574 | arg->symbol.field = field; |
1447 | 1575 | ||
1448 | type = process_fields(event, &arg->symbol.symbols, &token); | 1576 | type = process_fields(event, &arg->symbol.symbols, &token); |
1449 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) | 1577 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
1450 | goto out_free; | 1578 | goto out_free; |
1451 | 1579 | ||
1452 | free_token(token); | 1580 | free_token(token); |
@@ -1463,7 +1591,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1463 | { | 1591 | { |
1464 | struct print_arg *item_arg; | 1592 | struct print_arg *item_arg; |
1465 | enum event_type type; | 1593 | enum event_type type; |
1466 | int ptr_cast = 0; | ||
1467 | char *token; | 1594 | char *token; |
1468 | 1595 | ||
1469 | type = process_arg(event, arg, &token); | 1596 | type = process_arg(event, arg, &token); |
@@ -1471,28 +1598,13 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1471 | if (type == EVENT_ERROR) | 1598 | if (type == EVENT_ERROR) |
1472 | return EVENT_ERROR; | 1599 | return EVENT_ERROR; |
1473 | 1600 | ||
1474 | if (type == EVENT_OP) { | 1601 | if (type == EVENT_OP) |
1475 | /* handle the ptr casts */ | 1602 | 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 | 1603 | ||
1490 | if (type == EVENT_ERROR) | 1604 | if (type == EVENT_ERROR) |
1491 | return EVENT_ERROR; | 1605 | return EVENT_ERROR; |
1492 | } | ||
1493 | } | ||
1494 | 1606 | ||
1495 | if (test_type_token(type, token, EVENT_DELIM, (char *)")")) { | 1607 | if (test_type_token(type, token, EVENT_DELIM, ")")) { |
1496 | free_token(token); | 1608 | free_token(token); |
1497 | return EVENT_ERROR; | 1609 | return EVENT_ERROR; |
1498 | } | 1610 | } |
@@ -1516,13 +1628,6 @@ process_paren(struct event *event, struct print_arg *arg, char **tok) | |||
1516 | item_arg = malloc_or_die(sizeof(*item_arg)); | 1628 | item_arg = malloc_or_die(sizeof(*item_arg)); |
1517 | 1629 | ||
1518 | arg->type = PRINT_TYPE; | 1630 | 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; | 1631 | arg->typecast.type = arg->atom.atom; |
1527 | arg->typecast.item = item_arg; | 1632 | arg->typecast.item = item_arg; |
1528 | type = process_arg_token(event, item_arg, &token, type); | 1633 | type = process_arg_token(event, item_arg, &token, type); |
@@ -1540,7 +1645,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok) | |||
1540 | enum event_type type; | 1645 | enum event_type type; |
1541 | char *token; | 1646 | char *token; |
1542 | 1647 | ||
1543 | if (read_expected(EVENT_DELIM, (char *)"(") < 0) | 1648 | if (read_expected(EVENT_DELIM, "(") < 0) |
1544 | return EVENT_ERROR; | 1649 | return EVENT_ERROR; |
1545 | 1650 | ||
1546 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 1651 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
@@ -1550,7 +1655,7 @@ process_str(struct event *event __unused, struct print_arg *arg, char **tok) | |||
1550 | arg->string.string = token; | 1655 | arg->string.string = token; |
1551 | arg->string.offset = -1; | 1656 | arg->string.offset = -1; |
1552 | 1657 | ||
1553 | if (read_expected(EVENT_DELIM, (char *)")") < 0) | 1658 | if (read_expected(EVENT_DELIM, ")") < 0) |
1554 | return EVENT_ERROR; | 1659 | return EVENT_ERROR; |
1555 | 1660 | ||
1556 | type = read_token(&token); | 1661 | type = read_token(&token); |
@@ -1578,9 +1683,11 @@ process_arg_token(struct event *event, struct print_arg *arg, | |||
1578 | type = process_entry(event, arg, &token); | 1683 | type = process_entry(event, arg, &token); |
1579 | } else if (strcmp(token, "__print_flags") == 0) { | 1684 | } else if (strcmp(token, "__print_flags") == 0) { |
1580 | free_token(token); | 1685 | free_token(token); |
1686 | is_flag_field = 1; | ||
1581 | type = process_flags(event, arg, &token); | 1687 | type = process_flags(event, arg, &token); |
1582 | } else if (strcmp(token, "__print_symbolic") == 0) { | 1688 | } else if (strcmp(token, "__print_symbolic") == 0) { |
1583 | free_token(token); | 1689 | free_token(token); |
1690 | is_symbolic_field = 1; | ||
1584 | type = process_symbols(event, arg, &token); | 1691 | type = process_symbols(event, arg, &token); |
1585 | } else if (strcmp(token, "__get_str") == 0) { | 1692 | } else if (strcmp(token, "__get_str") == 0) { |
1586 | free_token(token); | 1693 | free_token(token); |
@@ -1637,12 +1744,18 @@ process_arg_token(struct event *event, struct print_arg *arg, | |||
1637 | 1744 | ||
1638 | static int event_read_print_args(struct event *event, struct print_arg **list) | 1745 | static int event_read_print_args(struct event *event, struct print_arg **list) |
1639 | { | 1746 | { |
1640 | enum event_type type; | 1747 | enum event_type type = EVENT_ERROR; |
1641 | struct print_arg *arg; | 1748 | struct print_arg *arg; |
1642 | char *token; | 1749 | char *token; |
1643 | int args = 0; | 1750 | int args = 0; |
1644 | 1751 | ||
1645 | do { | 1752 | do { |
1753 | if (type == EVENT_NEWLINE) { | ||
1754 | free_token(token); | ||
1755 | type = read_token_item(&token); | ||
1756 | continue; | ||
1757 | } | ||
1758 | |||
1646 | arg = malloc_or_die(sizeof(*arg)); | 1759 | arg = malloc_or_die(sizeof(*arg)); |
1647 | memset(arg, 0, sizeof(*arg)); | 1760 | memset(arg, 0, sizeof(*arg)); |
1648 | 1761 | ||
@@ -1683,18 +1796,19 @@ static int event_read_print(struct event *event) | |||
1683 | char *token; | 1796 | char *token; |
1684 | int ret; | 1797 | int ret; |
1685 | 1798 | ||
1686 | if (read_expected_item(EVENT_ITEM, (char *)"print") < 0) | 1799 | if (read_expected_item(EVENT_ITEM, "print") < 0) |
1687 | return -1; | 1800 | return -1; |
1688 | 1801 | ||
1689 | if (read_expected(EVENT_ITEM, (char *)"fmt") < 0) | 1802 | if (read_expected(EVENT_ITEM, "fmt") < 0) |
1690 | return -1; | 1803 | return -1; |
1691 | 1804 | ||
1692 | if (read_expected(EVENT_OP, (char *)":") < 0) | 1805 | if (read_expected(EVENT_OP, ":") < 0) |
1693 | return -1; | 1806 | return -1; |
1694 | 1807 | ||
1695 | if (read_expect_type(EVENT_DQUOTE, &token) < 0) | 1808 | if (read_expect_type(EVENT_DQUOTE, &token) < 0) |
1696 | goto fail; | 1809 | goto fail; |
1697 | 1810 | ||
1811 | concat: | ||
1698 | event->print_fmt.format = token; | 1812 | event->print_fmt.format = token; |
1699 | event->print_fmt.args = NULL; | 1813 | event->print_fmt.args = NULL; |
1700 | 1814 | ||
@@ -1704,7 +1818,22 @@ static int event_read_print(struct event *event) | |||
1704 | if (type == EVENT_NONE) | 1818 | if (type == EVENT_NONE) |
1705 | return 0; | 1819 | return 0; |
1706 | 1820 | ||
1707 | if (test_type_token(type, token, EVENT_DELIM, (char *)",")) | 1821 | /* Handle concatination of print lines */ |
1822 | if (type == EVENT_DQUOTE) { | ||
1823 | char *cat; | ||
1824 | |||
1825 | cat = malloc_or_die(strlen(event->print_fmt.format) + | ||
1826 | strlen(token) + 1); | ||
1827 | strcpy(cat, event->print_fmt.format); | ||
1828 | strcat(cat, token); | ||
1829 | free_token(token); | ||
1830 | free_token(event->print_fmt.format); | ||
1831 | event->print_fmt.format = NULL; | ||
1832 | token = cat; | ||
1833 | goto concat; | ||
1834 | } | ||
1835 | |||
1836 | if (test_type_token(type, token, EVENT_DELIM, ",")) | ||
1708 | goto fail; | 1837 | goto fail; |
1709 | 1838 | ||
1710 | free_token(token); | 1839 | free_token(token); |
@@ -1713,7 +1842,7 @@ static int event_read_print(struct event *event) | |||
1713 | if (ret < 0) | 1842 | if (ret < 0) |
1714 | return -1; | 1843 | return -1; |
1715 | 1844 | ||
1716 | return 0; | 1845 | return ret; |
1717 | 1846 | ||
1718 | fail: | 1847 | fail: |
1719 | free_token(token); | 1848 | free_token(token); |
@@ -1759,7 +1888,7 @@ find_any_field(struct event *event, const char *name) | |||
1759 | return find_field(event, name); | 1888 | return find_field(event, name); |
1760 | } | 1889 | } |
1761 | 1890 | ||
1762 | static unsigned long long read_size(void *ptr, int size) | 1891 | unsigned long long read_size(void *ptr, int size) |
1763 | { | 1892 | { |
1764 | switch (size) { | 1893 | switch (size) { |
1765 | case 1: | 1894 | case 1: |
@@ -1822,37 +1951,67 @@ static int get_common_info(const char *type, int *offset, int *size) | |||
1822 | return 0; | 1951 | return 0; |
1823 | } | 1952 | } |
1824 | 1953 | ||
1825 | int trace_parse_common_type(void *data) | 1954 | static int __parse_common(void *data, int *size, int *offset, |
1955 | const char *name) | ||
1826 | { | 1956 | { |
1827 | static int type_offset; | ||
1828 | static int type_size; | ||
1829 | int ret; | 1957 | int ret; |
1830 | 1958 | ||
1831 | if (!type_size) { | 1959 | if (!*size) { |
1832 | ret = get_common_info("common_type", | 1960 | ret = get_common_info(name, offset, size); |
1833 | &type_offset, | ||
1834 | &type_size); | ||
1835 | if (ret < 0) | 1961 | if (ret < 0) |
1836 | return ret; | 1962 | return ret; |
1837 | } | 1963 | } |
1838 | return read_size(data + type_offset, type_size); | 1964 | return read_size(data + *offset, *size); |
1965 | } | ||
1966 | |||
1967 | int trace_parse_common_type(void *data) | ||
1968 | { | ||
1969 | static int type_offset; | ||
1970 | static int type_size; | ||
1971 | |||
1972 | return __parse_common(data, &type_size, &type_offset, | ||
1973 | "common_type"); | ||
1839 | } | 1974 | } |
1840 | 1975 | ||
1841 | static int parse_common_pid(void *data) | 1976 | int trace_parse_common_pid(void *data) |
1842 | { | 1977 | { |
1843 | static int pid_offset; | 1978 | static int pid_offset; |
1844 | static int pid_size; | 1979 | static int pid_size; |
1980 | |||
1981 | return __parse_common(data, &pid_size, &pid_offset, | ||
1982 | "common_pid"); | ||
1983 | } | ||
1984 | |||
1985 | int parse_common_pc(void *data) | ||
1986 | { | ||
1987 | static int pc_offset; | ||
1988 | static int pc_size; | ||
1989 | |||
1990 | return __parse_common(data, &pc_size, &pc_offset, | ||
1991 | "common_preempt_count"); | ||
1992 | } | ||
1993 | |||
1994 | int parse_common_flags(void *data) | ||
1995 | { | ||
1996 | static int flags_offset; | ||
1997 | static int flags_size; | ||
1998 | |||
1999 | return __parse_common(data, &flags_size, &flags_offset, | ||
2000 | "common_flags"); | ||
2001 | } | ||
2002 | |||
2003 | int parse_common_lock_depth(void *data) | ||
2004 | { | ||
2005 | static int ld_offset; | ||
2006 | static int ld_size; | ||
1845 | int ret; | 2007 | int ret; |
1846 | 2008 | ||
1847 | if (!pid_size) { | 2009 | ret = __parse_common(data, &ld_size, &ld_offset, |
1848 | ret = get_common_info("common_pid", | 2010 | "common_lock_depth"); |
1849 | &pid_offset, | 2011 | if (ret < 0) |
1850 | &pid_size); | 2012 | return -1; |
1851 | if (ret < 0) | ||
1852 | return ret; | ||
1853 | } | ||
1854 | 2013 | ||
1855 | return read_size(data + pid_offset, pid_size); | 2014 | return ret; |
1856 | } | 2015 | } |
1857 | 2016 | ||
1858 | struct event *trace_find_event(int id) | 2017 | struct event *trace_find_event(int id) |
@@ -1866,11 +2025,20 @@ struct event *trace_find_event(int id) | |||
1866 | return event; | 2025 | return event; |
1867 | } | 2026 | } |
1868 | 2027 | ||
2028 | struct event *trace_find_next_event(struct event *event) | ||
2029 | { | ||
2030 | if (!event) | ||
2031 | return event_list; | ||
2032 | |||
2033 | return event->next; | ||
2034 | } | ||
2035 | |||
1869 | static unsigned long long eval_num_arg(void *data, int size, | 2036 | static unsigned long long eval_num_arg(void *data, int size, |
1870 | struct event *event, struct print_arg *arg) | 2037 | struct event *event, struct print_arg *arg) |
1871 | { | 2038 | { |
1872 | unsigned long long val = 0; | 2039 | unsigned long long val = 0; |
1873 | unsigned long long left, right; | 2040 | unsigned long long left, right; |
2041 | struct print_arg *larg; | ||
1874 | 2042 | ||
1875 | switch (arg->type) { | 2043 | switch (arg->type) { |
1876 | case PRINT_NULL: | 2044 | case PRINT_NULL: |
@@ -1897,6 +2065,26 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1897 | return 0; | 2065 | return 0; |
1898 | break; | 2066 | break; |
1899 | case PRINT_OP: | 2067 | case PRINT_OP: |
2068 | if (strcmp(arg->op.op, "[") == 0) { | ||
2069 | /* | ||
2070 | * Arrays are special, since we don't want | ||
2071 | * to read the arg as is. | ||
2072 | */ | ||
2073 | if (arg->op.left->type != PRINT_FIELD) | ||
2074 | goto default_op; /* oops, all bets off */ | ||
2075 | larg = arg->op.left; | ||
2076 | if (!larg->field.field) { | ||
2077 | larg->field.field = | ||
2078 | find_any_field(event, larg->field.name); | ||
2079 | if (!larg->field.field) | ||
2080 | die("field %s not found", larg->field.name); | ||
2081 | } | ||
2082 | right = eval_num_arg(data, size, event, arg->op.right); | ||
2083 | val = read_size(data + larg->field.field->offset + | ||
2084 | right * long_size, long_size); | ||
2085 | break; | ||
2086 | } | ||
2087 | default_op: | ||
1900 | left = eval_num_arg(data, size, event, arg->op.left); | 2088 | left = eval_num_arg(data, size, event, arg->op.left); |
1901 | right = eval_num_arg(data, size, event, arg->op.right); | 2089 | right = eval_num_arg(data, size, event, arg->op.right); |
1902 | switch (arg->op.op[0]) { | 2090 | switch (arg->op.op[0]) { |
@@ -1947,6 +2135,12 @@ static unsigned long long eval_num_arg(void *data, int size, | |||
1947 | die("unknown op '%s'", arg->op.op); | 2135 | die("unknown op '%s'", arg->op.op); |
1948 | val = left == right; | 2136 | val = left == right; |
1949 | break; | 2137 | break; |
2138 | case '-': | ||
2139 | val = left - right; | ||
2140 | break; | ||
2141 | case '+': | ||
2142 | val = left + right; | ||
2143 | break; | ||
1950 | default: | 2144 | default: |
1951 | die("unknown op '%s'", arg->op.op); | 2145 | die("unknown op '%s'", arg->op.op); |
1952 | } | 2146 | } |
@@ -1978,7 +2172,7 @@ static const struct flag flags[] = { | |||
1978 | { "HRTIMER_RESTART", 1 }, | 2172 | { "HRTIMER_RESTART", 1 }, |
1979 | }; | 2173 | }; |
1980 | 2174 | ||
1981 | static unsigned long long eval_flag(const char *flag) | 2175 | unsigned long long eval_flag(const char *flag) |
1982 | { | 2176 | { |
1983 | int i; | 2177 | int i; |
1984 | 2178 | ||
@@ -2145,8 +2339,9 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
2145 | case 'u': | 2339 | case 'u': |
2146 | case 'x': | 2340 | case 'x': |
2147 | case 'i': | 2341 | case 'i': |
2148 | bptr = (void *)(((unsigned long)bptr + (long_size - 1)) & | 2342 | /* the pointers are always 4 bytes aligned */ |
2149 | ~(long_size - 1)); | 2343 | bptr = (void *)(((unsigned long)bptr + 3) & |
2344 | ~3); | ||
2150 | switch (ls) { | 2345 | switch (ls) { |
2151 | case 0: | 2346 | case 0: |
2152 | case 1: | 2347 | case 1: |
@@ -2270,7 +2465,27 @@ static void pretty_print(void *data, int size, struct event *event) | |||
2270 | 2465 | ||
2271 | for (; *ptr; ptr++) { | 2466 | for (; *ptr; ptr++) { |
2272 | ls = 0; | 2467 | ls = 0; |
2273 | if (*ptr == '%') { | 2468 | if (*ptr == '\\') { |
2469 | ptr++; | ||
2470 | switch (*ptr) { | ||
2471 | case 'n': | ||
2472 | printf("\n"); | ||
2473 | break; | ||
2474 | case 't': | ||
2475 | printf("\t"); | ||
2476 | break; | ||
2477 | case 'r': | ||
2478 | printf("\r"); | ||
2479 | break; | ||
2480 | case '\\': | ||
2481 | printf("\\"); | ||
2482 | break; | ||
2483 | default: | ||
2484 | printf("%c", *ptr); | ||
2485 | break; | ||
2486 | } | ||
2487 | |||
2488 | } else if (*ptr == '%') { | ||
2274 | saveptr = ptr; | 2489 | saveptr = ptr; |
2275 | show_func = 0; | 2490 | show_func = 0; |
2276 | cont_process: | 2491 | cont_process: |
@@ -2377,6 +2592,41 @@ static inline int log10_cpu(int nb) | |||
2377 | return 1; | 2592 | return 1; |
2378 | } | 2593 | } |
2379 | 2594 | ||
2595 | static void print_lat_fmt(void *data, int size __unused) | ||
2596 | { | ||
2597 | unsigned int lat_flags; | ||
2598 | unsigned int pc; | ||
2599 | int lock_depth; | ||
2600 | int hardirq; | ||
2601 | int softirq; | ||
2602 | |||
2603 | lat_flags = parse_common_flags(data); | ||
2604 | pc = parse_common_pc(data); | ||
2605 | lock_depth = parse_common_lock_depth(data); | ||
2606 | |||
2607 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | ||
2608 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | ||
2609 | |||
2610 | printf("%c%c%c", | ||
2611 | (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' : | ||
2612 | (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ? | ||
2613 | 'X' : '.', | ||
2614 | (lat_flags & TRACE_FLAG_NEED_RESCHED) ? | ||
2615 | 'N' : '.', | ||
2616 | (hardirq && softirq) ? 'H' : | ||
2617 | hardirq ? 'h' : softirq ? 's' : '.'); | ||
2618 | |||
2619 | if (pc) | ||
2620 | printf("%x", pc); | ||
2621 | else | ||
2622 | printf("."); | ||
2623 | |||
2624 | if (lock_depth < 0) | ||
2625 | printf("."); | ||
2626 | else | ||
2627 | printf("%d", lock_depth); | ||
2628 | } | ||
2629 | |||
2380 | /* taken from Linux, written by Frederic Weisbecker */ | 2630 | /* taken from Linux, written by Frederic Weisbecker */ |
2381 | static void print_graph_cpu(int cpu) | 2631 | static void print_graph_cpu(int cpu) |
2382 | { | 2632 | { |
@@ -2452,7 +2702,7 @@ get_return_for_leaf(int cpu, int cur_pid, unsigned long long cur_func, | |||
2452 | if (!(event->flags & EVENT_FL_ISFUNCRET)) | 2702 | if (!(event->flags & EVENT_FL_ISFUNCRET)) |
2453 | return NULL; | 2703 | return NULL; |
2454 | 2704 | ||
2455 | pid = parse_common_pid(next->data); | 2705 | pid = trace_parse_common_pid(next->data); |
2456 | field = find_field(event, "func"); | 2706 | field = find_field(event, "func"); |
2457 | if (!field) | 2707 | if (!field) |
2458 | die("function return does not have field func"); | 2708 | die("function return does not have field func"); |
@@ -2620,6 +2870,11 @@ pretty_print_func_ent(void *data, int size, struct event *event, | |||
2620 | 2870 | ||
2621 | printf(" | "); | 2871 | printf(" | "); |
2622 | 2872 | ||
2873 | if (latency_format) { | ||
2874 | print_lat_fmt(data, size); | ||
2875 | printf(" | "); | ||
2876 | } | ||
2877 | |||
2623 | field = find_field(event, "func"); | 2878 | field = find_field(event, "func"); |
2624 | if (!field) | 2879 | if (!field) |
2625 | die("function entry does not have func field"); | 2880 | die("function entry does not have func field"); |
@@ -2663,6 +2918,11 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event, | |||
2663 | 2918 | ||
2664 | printf(" | "); | 2919 | printf(" | "); |
2665 | 2920 | ||
2921 | if (latency_format) { | ||
2922 | print_lat_fmt(data, size); | ||
2923 | printf(" | "); | ||
2924 | } | ||
2925 | |||
2666 | field = find_field(event, "rettime"); | 2926 | field = find_field(event, "rettime"); |
2667 | if (!field) | 2927 | if (!field) |
2668 | die("can't find rettime in return graph"); | 2928 | die("can't find rettime in return graph"); |
@@ -2724,19 +2984,30 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs, | |||
2724 | 2984 | ||
2725 | event = trace_find_event(type); | 2985 | event = trace_find_event(type); |
2726 | if (!event) { | 2986 | if (!event) { |
2727 | printf("ug! no event found for type %d\n", type); | 2987 | warning("ug! no event found for type %d", type); |
2728 | return; | 2988 | return; |
2729 | } | 2989 | } |
2730 | 2990 | ||
2731 | pid = parse_common_pid(data); | 2991 | pid = trace_parse_common_pid(data); |
2732 | 2992 | ||
2733 | if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET)) | 2993 | if (event->flags & (EVENT_FL_ISFUNCENT | EVENT_FL_ISFUNCRET)) |
2734 | return pretty_print_func_graph(data, size, event, cpu, | 2994 | return pretty_print_func_graph(data, size, event, cpu, |
2735 | pid, comm, secs, usecs); | 2995 | pid, comm, secs, usecs); |
2736 | 2996 | ||
2737 | printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ", | 2997 | if (latency_format) { |
2738 | comm, pid, cpu, | 2998 | printf("%8.8s-%-5d %3d", |
2739 | secs, nsecs, event->name); | 2999 | comm, pid, cpu); |
3000 | print_lat_fmt(data, size); | ||
3001 | } else | ||
3002 | printf("%16s-%-5d [%03d]", comm, pid, cpu); | ||
3003 | |||
3004 | printf(" %5lu.%06lu: %s: ", secs, usecs, event->name); | ||
3005 | |||
3006 | if (event->flags & EVENT_FL_FAILED) { | ||
3007 | printf("EVENT '%s' FAILED TO PARSE\n", | ||
3008 | event->name); | ||
3009 | return; | ||
3010 | } | ||
2740 | 3011 | ||
2741 | pretty_print(data, size, event); | 3012 | pretty_print(data, size, event); |
2742 | printf("\n"); | 3013 | printf("\n"); |
@@ -2807,46 +3078,71 @@ static void print_args(struct print_arg *args) | |||
2807 | } | 3078 | } |
2808 | } | 3079 | } |
2809 | 3080 | ||
2810 | static void parse_header_field(char *type, | 3081 | static void parse_header_field(const char *field, |
2811 | int *offset, int *size) | 3082 | int *offset, int *size) |
2812 | { | 3083 | { |
2813 | char *token; | 3084 | char *token; |
3085 | int type; | ||
2814 | 3086 | ||
2815 | if (read_expected(EVENT_ITEM, (char *)"field") < 0) | 3087 | if (read_expected(EVENT_ITEM, "field") < 0) |
2816 | return; | 3088 | return; |
2817 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3089 | if (read_expected(EVENT_OP, ":") < 0) |
2818 | return; | 3090 | return; |
3091 | |||
2819 | /* type */ | 3092 | /* type */ |
2820 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3093 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2821 | return; | 3094 | goto fail; |
2822 | free_token(token); | 3095 | free_token(token); |
2823 | 3096 | ||
2824 | if (read_expected(EVENT_ITEM, type) < 0) | 3097 | if (read_expected(EVENT_ITEM, field) < 0) |
2825 | return; | 3098 | return; |
2826 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3099 | if (read_expected(EVENT_OP, ";") < 0) |
2827 | return; | 3100 | return; |
2828 | if (read_expected(EVENT_ITEM, (char *)"offset") < 0) | 3101 | if (read_expected(EVENT_ITEM, "offset") < 0) |
2829 | return; | 3102 | return; |
2830 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3103 | if (read_expected(EVENT_OP, ":") < 0) |
2831 | return; | 3104 | return; |
2832 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3105 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2833 | return; | 3106 | goto fail; |
2834 | *offset = atoi(token); | 3107 | *offset = atoi(token); |
2835 | free_token(token); | 3108 | free_token(token); |
2836 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3109 | if (read_expected(EVENT_OP, ";") < 0) |
2837 | return; | 3110 | return; |
2838 | if (read_expected(EVENT_ITEM, (char *)"size") < 0) | 3111 | if (read_expected(EVENT_ITEM, "size") < 0) |
2839 | return; | 3112 | return; |
2840 | if (read_expected(EVENT_OP, (char *)":") < 0) | 3113 | if (read_expected(EVENT_OP, ":") < 0) |
2841 | return; | 3114 | return; |
2842 | if (read_expect_type(EVENT_ITEM, &token) < 0) | 3115 | if (read_expect_type(EVENT_ITEM, &token) < 0) |
2843 | return; | 3116 | goto fail; |
2844 | *size = atoi(token); | 3117 | *size = atoi(token); |
2845 | free_token(token); | 3118 | free_token(token); |
2846 | if (read_expected(EVENT_OP, (char *)";") < 0) | 3119 | if (read_expected(EVENT_OP, ";") < 0) |
2847 | return; | ||
2848 | if (read_expect_type(EVENT_NEWLINE, &token) < 0) | ||
2849 | return; | 3120 | return; |
3121 | type = read_token(&token); | ||
3122 | if (type != EVENT_NEWLINE) { | ||
3123 | /* newer versions of the kernel have a "signed" type */ | ||
3124 | if (type != EVENT_ITEM) | ||
3125 | goto fail; | ||
3126 | |||
3127 | if (strcmp(token, "signed") != 0) | ||
3128 | goto fail; | ||
3129 | |||
3130 | free_token(token); | ||
3131 | |||
3132 | if (read_expected(EVENT_OP, ":") < 0) | ||
3133 | return; | ||
3134 | |||
3135 | if (read_expect_type(EVENT_ITEM, &token)) | ||
3136 | goto fail; | ||
3137 | |||
3138 | free_token(token); | ||
3139 | if (read_expected(EVENT_OP, ";") < 0) | ||
3140 | return; | ||
3141 | |||
3142 | if (read_expect_type(EVENT_NEWLINE, &token)) | ||
3143 | goto fail; | ||
3144 | } | ||
3145 | fail: | ||
2850 | free_token(token); | 3146 | free_token(token); |
2851 | } | 3147 | } |
2852 | 3148 | ||
@@ -2854,11 +3150,11 @@ int parse_header_page(char *buf, unsigned long size) | |||
2854 | { | 3150 | { |
2855 | init_input_buf(buf, size); | 3151 | init_input_buf(buf, size); |
2856 | 3152 | ||
2857 | parse_header_field((char *)"timestamp", &header_page_ts_offset, | 3153 | parse_header_field("timestamp", &header_page_ts_offset, |
2858 | &header_page_ts_size); | 3154 | &header_page_ts_size); |
2859 | parse_header_field((char *)"commit", &header_page_size_offset, | 3155 | parse_header_field("commit", &header_page_size_offset, |
2860 | &header_page_size_size); | 3156 | &header_page_size_size); |
2861 | parse_header_field((char *)"data", &header_page_data_offset, | 3157 | parse_header_field("data", &header_page_data_offset, |
2862 | &header_page_data_size); | 3158 | &header_page_data_size); |
2863 | 3159 | ||
2864 | return 0; | 3160 | return 0; |
@@ -2909,6 +3205,9 @@ int parse_ftrace_file(char *buf, unsigned long size) | |||
2909 | if (ret < 0) | 3205 | if (ret < 0) |
2910 | die("failed to read ftrace event print fmt"); | 3206 | die("failed to read ftrace event print fmt"); |
2911 | 3207 | ||
3208 | /* New ftrace handles args */ | ||
3209 | if (ret > 0) | ||
3210 | return 0; | ||
2912 | /* | 3211 | /* |
2913 | * The arguments for ftrace files are parsed by the fields. | 3212 | * The arguments for ftrace files are parsed by the fields. |
2914 | * Set up the fields as their arguments. | 3213 | * Set up the fields as their arguments. |
@@ -2926,7 +3225,7 @@ int parse_ftrace_file(char *buf, unsigned long size) | |||
2926 | return 0; | 3225 | return 0; |
2927 | } | 3226 | } |
2928 | 3227 | ||
2929 | int parse_event_file(char *buf, unsigned long size, char *system__unused __unused) | 3228 | int parse_event_file(char *buf, unsigned long size, char *sys) |
2930 | { | 3229 | { |
2931 | struct event *event; | 3230 | struct event *event; |
2932 | int ret; | 3231 | int ret; |
@@ -2946,12 +3245,18 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse | |||
2946 | die("failed to read event id"); | 3245 | die("failed to read event id"); |
2947 | 3246 | ||
2948 | ret = event_read_format(event); | 3247 | ret = event_read_format(event); |
2949 | if (ret < 0) | 3248 | if (ret < 0) { |
2950 | die("failed to read event format"); | 3249 | warning("failed to read event format for %s", event->name); |
3250 | goto event_failed; | ||
3251 | } | ||
2951 | 3252 | ||
2952 | ret = event_read_print(event); | 3253 | ret = event_read_print(event); |
2953 | if (ret < 0) | 3254 | if (ret < 0) { |
2954 | die("failed to read event print fmt"); | 3255 | warning("failed to read event print fmt for %s", event->name); |
3256 | goto event_failed; | ||
3257 | } | ||
3258 | |||
3259 | event->system = strdup(sys); | ||
2955 | 3260 | ||
2956 | #define PRINT_ARGS 0 | 3261 | #define PRINT_ARGS 0 |
2957 | if (PRINT_ARGS && event->print_fmt.args) | 3262 | if (PRINT_ARGS && event->print_fmt.args) |
@@ -2959,6 +3264,12 @@ int parse_event_file(char *buf, unsigned long size, char *system__unused __unuse | |||
2959 | 3264 | ||
2960 | add_event(event); | 3265 | add_event(event); |
2961 | return 0; | 3266 | return 0; |
3267 | |||
3268 | event_failed: | ||
3269 | event->flags |= EVENT_FL_FAILED; | ||
3270 | /* still add it even if it failed */ | ||
3271 | add_event(event); | ||
3272 | return -1; | ||
2962 | } | 3273 | } |
2963 | 3274 | ||
2964 | void parse_set_info(int nr_cpus, int long_sz) | 3275 | void parse_set_info(int nr_cpus, int long_sz) |