diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-07-05 11:16:32 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-07-05 11:16:32 -0400 |
commit | 81e9b994bb20716d1f6c47e048e4ae4a43de2f83 (patch) | |
tree | 7d9f4ca9fff03a450ab1b33d7a6bf1950873ce70 /tools | |
parent | 1dc12760854a670d0366dcfd8ad179e3574c1712 (diff) | |
parent | f6ced60fb6c0ee115982157457c47e48802d6e1d (diff) |
Merge tag 'libtraceevent-core-for-acme' of git://git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf into perf/core
libtraceevent/core improvements
* Remaining backport of trace-cmd's libparseevent
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 287 | ||||
-rw-r--r-- | tools/lib/traceevent/parse-filter.c | 86 |
2 files changed, 251 insertions, 122 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 83f0a8add177..5f34aa371b56 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -467,8 +467,10 @@ int pevent_register_function(struct pevent *pevent, char *func, | |||
467 | item->mod = NULL; | 467 | item->mod = NULL; |
468 | item->addr = addr; | 468 | item->addr = addr; |
469 | 469 | ||
470 | pevent->funclist = item; | 470 | if (!item->func || (mod && !item->mod)) |
471 | die("malloc func"); | ||
471 | 472 | ||
473 | pevent->funclist = item; | ||
472 | pevent->func_count++; | 474 | pevent->func_count++; |
473 | 475 | ||
474 | return 0; | 476 | return 0; |
@@ -511,12 +513,12 @@ struct printk_list { | |||
511 | 513 | ||
512 | static int printk_cmp(const void *a, const void *b) | 514 | static int printk_cmp(const void *a, const void *b) |
513 | { | 515 | { |
514 | const struct func_map *fa = a; | 516 | const struct printk_map *pa = a; |
515 | const struct func_map *fb = b; | 517 | const struct printk_map *pb = b; |
516 | 518 | ||
517 | if (fa->addr < fb->addr) | 519 | if (pa->addr < pb->addr) |
518 | return -1; | 520 | return -1; |
519 | if (fa->addr > fb->addr) | 521 | if (pa->addr > pb->addr) |
520 | return 1; | 522 | return 1; |
521 | 523 | ||
522 | return 0; | 524 | return 0; |
@@ -583,10 +585,13 @@ int pevent_register_print_string(struct pevent *pevent, char *fmt, | |||
583 | item = malloc_or_die(sizeof(*item)); | 585 | item = malloc_or_die(sizeof(*item)); |
584 | 586 | ||
585 | item->next = pevent->printklist; | 587 | item->next = pevent->printklist; |
586 | pevent->printklist = item; | ||
587 | item->printk = strdup(fmt); | 588 | item->printk = strdup(fmt); |
588 | item->addr = addr; | 589 | item->addr = addr; |
589 | 590 | ||
591 | if (!item->printk) | ||
592 | die("malloc fmt"); | ||
593 | |||
594 | pevent->printklist = item; | ||
590 | pevent->printk_count++; | 595 | pevent->printk_count++; |
591 | 596 | ||
592 | return 0; | 597 | return 0; |
@@ -628,12 +633,8 @@ static void add_event(struct pevent *pevent, struct event_format *event) | |||
628 | { | 633 | { |
629 | int i; | 634 | int i; |
630 | 635 | ||
631 | if (!pevent->events) | 636 | pevent->events = realloc(pevent->events, sizeof(event) * |
632 | pevent->events = malloc_or_die(sizeof(event)); | 637 | (pevent->nr_events + 1)); |
633 | else | ||
634 | pevent->events = | ||
635 | realloc(pevent->events, sizeof(event) * | ||
636 | (pevent->nr_events + 1)); | ||
637 | if (!pevent->events) | 638 | if (!pevent->events) |
638 | die("Can not allocate events"); | 639 | die("Can not allocate events"); |
639 | 640 | ||
@@ -781,6 +782,25 @@ int pevent_peek_char(void) | |||
781 | return __peek_char(); | 782 | return __peek_char(); |
782 | } | 783 | } |
783 | 784 | ||
785 | static int extend_token(char **tok, char *buf, int size) | ||
786 | { | ||
787 | char *newtok = realloc(*tok, size); | ||
788 | |||
789 | if (!newtok) { | ||
790 | free(*tok); | ||
791 | *tok = NULL; | ||
792 | return -1; | ||
793 | } | ||
794 | |||
795 | if (!*tok) | ||
796 | strcpy(newtok, buf); | ||
797 | else | ||
798 | strcat(newtok, buf); | ||
799 | *tok = newtok; | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
784 | static enum event_type force_token(const char *str, char **tok); | 804 | static enum event_type force_token(const char *str, char **tok); |
785 | 805 | ||
786 | static enum event_type __read_token(char **tok) | 806 | static enum event_type __read_token(char **tok) |
@@ -865,17 +885,10 @@ static enum event_type __read_token(char **tok) | |||
865 | do { | 885 | do { |
866 | if (i == (BUFSIZ - 1)) { | 886 | if (i == (BUFSIZ - 1)) { |
867 | buf[i] = 0; | 887 | buf[i] = 0; |
868 | if (*tok) { | 888 | tok_size += BUFSIZ; |
869 | *tok = realloc(*tok, tok_size + BUFSIZ); | ||
870 | if (!*tok) | ||
871 | return EVENT_NONE; | ||
872 | strcat(*tok, buf); | ||
873 | } else | ||
874 | *tok = strdup(buf); | ||
875 | 889 | ||
876 | if (!*tok) | 890 | if (extend_token(tok, buf, tok_size) < 0) |
877 | return EVENT_NONE; | 891 | return EVENT_NONE; |
878 | tok_size += BUFSIZ; | ||
879 | i = 0; | 892 | i = 0; |
880 | } | 893 | } |
881 | last_ch = ch; | 894 | last_ch = ch; |
@@ -914,17 +927,10 @@ static enum event_type __read_token(char **tok) | |||
914 | while (get_type(__peek_char()) == type) { | 927 | while (get_type(__peek_char()) == type) { |
915 | if (i == (BUFSIZ - 1)) { | 928 | if (i == (BUFSIZ - 1)) { |
916 | buf[i] = 0; | 929 | buf[i] = 0; |
917 | if (*tok) { | 930 | tok_size += BUFSIZ; |
918 | *tok = realloc(*tok, tok_size + BUFSIZ); | ||
919 | if (!*tok) | ||
920 | return EVENT_NONE; | ||
921 | strcat(*tok, buf); | ||
922 | } else | ||
923 | *tok = strdup(buf); | ||
924 | 931 | ||
925 | if (!*tok) | 932 | if (extend_token(tok, buf, tok_size) < 0) |
926 | return EVENT_NONE; | 933 | return EVENT_NONE; |
927 | tok_size += BUFSIZ; | ||
928 | i = 0; | 934 | i = 0; |
929 | } | 935 | } |
930 | ch = __read_char(); | 936 | ch = __read_char(); |
@@ -933,14 +939,7 @@ static enum event_type __read_token(char **tok) | |||
933 | 939 | ||
934 | out: | 940 | out: |
935 | buf[i] = 0; | 941 | buf[i] = 0; |
936 | if (*tok) { | 942 | if (extend_token(tok, buf, tok_size + i + 1) < 0) |
937 | *tok = realloc(*tok, tok_size + i); | ||
938 | if (!*tok) | ||
939 | return EVENT_NONE; | ||
940 | strcat(*tok, buf); | ||
941 | } else | ||
942 | *tok = strdup(buf); | ||
943 | if (!*tok) | ||
944 | return EVENT_NONE; | 943 | return EVENT_NONE; |
945 | 944 | ||
946 | if (type == EVENT_ITEM) { | 945 | if (type == EVENT_ITEM) { |
@@ -1261,9 +1260,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1261 | field->flags |= FIELD_IS_POINTER; | 1260 | field->flags |= FIELD_IS_POINTER; |
1262 | 1261 | ||
1263 | if (field->type) { | 1262 | if (field->type) { |
1264 | field->type = realloc(field->type, | 1263 | char *new_type; |
1265 | strlen(field->type) + | 1264 | new_type = realloc(field->type, |
1266 | strlen(last_token) + 2); | 1265 | strlen(field->type) + |
1266 | strlen(last_token) + 2); | ||
1267 | if (!new_type) { | ||
1268 | free(last_token); | ||
1269 | goto fail; | ||
1270 | } | ||
1271 | field->type = new_type; | ||
1267 | strcat(field->type, " "); | 1272 | strcat(field->type, " "); |
1268 | strcat(field->type, last_token); | 1273 | strcat(field->type, last_token); |
1269 | free(last_token); | 1274 | free(last_token); |
@@ -1288,6 +1293,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1288 | if (strcmp(token, "[") == 0) { | 1293 | if (strcmp(token, "[") == 0) { |
1289 | enum event_type last_type = type; | 1294 | enum event_type last_type = type; |
1290 | char *brackets = token; | 1295 | char *brackets = token; |
1296 | char *new_brackets; | ||
1291 | int len; | 1297 | int len; |
1292 | 1298 | ||
1293 | field->flags |= FIELD_IS_ARRAY; | 1299 | field->flags |= FIELD_IS_ARRAY; |
@@ -1307,9 +1313,14 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1307 | len = 1; | 1313 | len = 1; |
1308 | last_type = type; | 1314 | last_type = type; |
1309 | 1315 | ||
1310 | brackets = realloc(brackets, | 1316 | new_brackets = realloc(brackets, |
1311 | strlen(brackets) + | 1317 | strlen(brackets) + |
1312 | strlen(token) + len); | 1318 | strlen(token) + len); |
1319 | if (!new_brackets) { | ||
1320 | free(brackets); | ||
1321 | goto fail; | ||
1322 | } | ||
1323 | brackets = new_brackets; | ||
1313 | if (len == 2) | 1324 | if (len == 2) |
1314 | strcat(brackets, " "); | 1325 | strcat(brackets, " "); |
1315 | strcat(brackets, token); | 1326 | strcat(brackets, token); |
@@ -1325,7 +1336,12 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1325 | 1336 | ||
1326 | free_token(token); | 1337 | free_token(token); |
1327 | 1338 | ||
1328 | brackets = realloc(brackets, strlen(brackets) + 2); | 1339 | new_brackets = realloc(brackets, strlen(brackets) + 2); |
1340 | if (!new_brackets) { | ||
1341 | free(brackets); | ||
1342 | goto fail; | ||
1343 | } | ||
1344 | brackets = new_brackets; | ||
1329 | strcat(brackets, "]"); | 1345 | strcat(brackets, "]"); |
1330 | 1346 | ||
1331 | /* add brackets to type */ | 1347 | /* add brackets to type */ |
@@ -1336,10 +1352,16 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1336 | * the format: type [] item; | 1352 | * the format: type [] item; |
1337 | */ | 1353 | */ |
1338 | if (type == EVENT_ITEM) { | 1354 | if (type == EVENT_ITEM) { |
1339 | field->type = realloc(field->type, | 1355 | char *new_type; |
1340 | strlen(field->type) + | 1356 | new_type = realloc(field->type, |
1341 | strlen(field->name) + | 1357 | strlen(field->type) + |
1342 | strlen(brackets) + 2); | 1358 | strlen(field->name) + |
1359 | strlen(brackets) + 2); | ||
1360 | if (!new_type) { | ||
1361 | free(brackets); | ||
1362 | goto fail; | ||
1363 | } | ||
1364 | field->type = new_type; | ||
1343 | strcat(field->type, " "); | 1365 | strcat(field->type, " "); |
1344 | strcat(field->type, field->name); | 1366 | strcat(field->type, field->name); |
1345 | free_token(field->name); | 1367 | free_token(field->name); |
@@ -1347,9 +1369,15 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
1347 | field->name = token; | 1369 | field->name = token; |
1348 | type = read_token(&token); | 1370 | type = read_token(&token); |
1349 | } else { | 1371 | } else { |
1350 | field->type = realloc(field->type, | 1372 | char *new_type; |
1351 | strlen(field->type) + | 1373 | new_type = realloc(field->type, |
1352 | strlen(brackets) + 1); | 1374 | strlen(field->type) + |
1375 | strlen(brackets) + 1); | ||
1376 | if (!new_type) { | ||
1377 | free(brackets); | ||
1378 | goto fail; | ||
1379 | } | ||
1380 | field->type = new_type; | ||
1353 | strcat(field->type, brackets); | 1381 | strcat(field->type, brackets); |
1354 | } | 1382 | } |
1355 | free(brackets); | 1383 | free(brackets); |
@@ -1732,10 +1760,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1732 | /* could just be a type pointer */ | 1760 | /* could just be a type pointer */ |
1733 | if ((strcmp(arg->op.op, "*") == 0) && | 1761 | if ((strcmp(arg->op.op, "*") == 0) && |
1734 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { | 1762 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { |
1763 | char *new_atom; | ||
1764 | |||
1735 | if (left->type != PRINT_ATOM) | 1765 | if (left->type != PRINT_ATOM) |
1736 | die("bad pointer type"); | 1766 | die("bad pointer type"); |
1737 | left->atom.atom = realloc(left->atom.atom, | 1767 | new_atom = realloc(left->atom.atom, |
1738 | strlen(left->atom.atom) + 3); | 1768 | strlen(left->atom.atom) + 3); |
1769 | if (!new_atom) | ||
1770 | goto out_free; | ||
1771 | |||
1772 | left->atom.atom = new_atom; | ||
1739 | strcat(left->atom.atom, " *"); | 1773 | strcat(left->atom.atom, " *"); |
1740 | free(arg->op.op); | 1774 | free(arg->op.op); |
1741 | *arg = *left; | 1775 | *arg = *left; |
@@ -2152,6 +2186,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2152 | if (value == NULL) | 2186 | if (value == NULL) |
2153 | goto out_free; | 2187 | goto out_free; |
2154 | field->value = strdup(value); | 2188 | field->value = strdup(value); |
2189 | if (field->value == NULL) | ||
2190 | goto out_free; | ||
2155 | 2191 | ||
2156 | free_arg(arg); | 2192 | free_arg(arg); |
2157 | arg = alloc_arg(); | 2193 | arg = alloc_arg(); |
@@ -2165,6 +2201,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2165 | if (value == NULL) | 2201 | if (value == NULL) |
2166 | goto out_free; | 2202 | goto out_free; |
2167 | field->str = strdup(value); | 2203 | field->str = strdup(value); |
2204 | if (field->str == NULL) | ||
2205 | goto out_free; | ||
2168 | free_arg(arg); | 2206 | free_arg(arg); |
2169 | arg = NULL; | 2207 | arg = NULL; |
2170 | 2208 | ||
@@ -2590,7 +2628,16 @@ process_arg_token(struct event_format *event, struct print_arg *arg, | |||
2590 | } | 2628 | } |
2591 | /* atoms can be more than one token long */ | 2629 | /* atoms can be more than one token long */ |
2592 | while (type == EVENT_ITEM) { | 2630 | while (type == EVENT_ITEM) { |
2593 | atom = realloc(atom, strlen(atom) + strlen(token) + 2); | 2631 | char *new_atom; |
2632 | new_atom = realloc(atom, | ||
2633 | strlen(atom) + strlen(token) + 2); | ||
2634 | if (!new_atom) { | ||
2635 | free(atom); | ||
2636 | *tok = NULL; | ||
2637 | free_token(token); | ||
2638 | return EVENT_ERROR; | ||
2639 | } | ||
2640 | atom = new_atom; | ||
2594 | strcat(atom, " "); | 2641 | strcat(atom, " "); |
2595 | strcat(atom, token); | 2642 | strcat(atom, token); |
2596 | free_token(token); | 2643 | free_token(token); |
@@ -2884,7 +2931,7 @@ static int get_common_info(struct pevent *pevent, | |||
2884 | event = pevent->events[0]; | 2931 | event = pevent->events[0]; |
2885 | field = pevent_find_common_field(event, type); | 2932 | field = pevent_find_common_field(event, type); |
2886 | if (!field) | 2933 | if (!field) |
2887 | die("field '%s' not found", type); | 2934 | return -1; |
2888 | 2935 | ||
2889 | *offset = field->offset; | 2936 | *offset = field->offset; |
2890 | *size = field->size; | 2937 | *size = field->size; |
@@ -2935,15 +2982,16 @@ static int parse_common_flags(struct pevent *pevent, void *data) | |||
2935 | 2982 | ||
2936 | static int parse_common_lock_depth(struct pevent *pevent, void *data) | 2983 | static int parse_common_lock_depth(struct pevent *pevent, void *data) |
2937 | { | 2984 | { |
2938 | int ret; | 2985 | return __parse_common(pevent, data, |
2939 | 2986 | &pevent->ld_size, &pevent->ld_offset, | |
2940 | ret = __parse_common(pevent, data, | 2987 | "common_lock_depth"); |
2941 | &pevent->ld_size, &pevent->ld_offset, | 2988 | } |
2942 | "common_lock_depth"); | ||
2943 | if (ret < 0) | ||
2944 | return -1; | ||
2945 | 2989 | ||
2946 | return ret; | 2990 | static int parse_common_migrate_disable(struct pevent *pevent, void *data) |
2991 | { | ||
2992 | return __parse_common(pevent, data, | ||
2993 | &pevent->ld_size, &pevent->ld_offset, | ||
2994 | "common_migrate_disable"); | ||
2947 | } | 2995 | } |
2948 | 2996 | ||
2949 | static int events_id_cmp(const void *a, const void *b); | 2997 | static int events_id_cmp(const void *a, const void *b); |
@@ -3370,7 +3418,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
3370 | break; | 3418 | break; |
3371 | } | 3419 | } |
3372 | case PRINT_BSTRING: | 3420 | case PRINT_BSTRING: |
3373 | trace_seq_printf(s, format, arg->string.string); | 3421 | print_str_to_seq(s, format, len_arg, arg->string.string); |
3374 | break; | 3422 | break; |
3375 | case PRINT_OP: | 3423 | case PRINT_OP: |
3376 | /* | 3424 | /* |
@@ -3434,6 +3482,10 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
3434 | string = malloc_or_die(sizeof(*string)); | 3482 | string = malloc_or_die(sizeof(*string)); |
3435 | string->next = strings; | 3483 | string->next = strings; |
3436 | string->str = strdup(str.buffer); | 3484 | string->str = strdup(str.buffer); |
3485 | if (!string->str) | ||
3486 | die("malloc str"); | ||
3487 | |||
3488 | args[i] = (unsigned long long)string->str; | ||
3437 | strings = string; | 3489 | strings = string; |
3438 | trace_seq_destroy(&str); | 3490 | trace_seq_destroy(&str); |
3439 | break; | 3491 | break; |
@@ -3471,6 +3523,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3471 | unsigned long long ip, val; | 3523 | unsigned long long ip, val; |
3472 | char *ptr; | 3524 | char *ptr; |
3473 | void *bptr; | 3525 | void *bptr; |
3526 | int vsize; | ||
3474 | 3527 | ||
3475 | field = pevent->bprint_buf_field; | 3528 | field = pevent->bprint_buf_field; |
3476 | ip_field = pevent->bprint_ip_field; | 3529 | ip_field = pevent->bprint_ip_field; |
@@ -3519,6 +3572,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3519 | goto process_again; | 3572 | goto process_again; |
3520 | case '0' ... '9': | 3573 | case '0' ... '9': |
3521 | goto process_again; | 3574 | goto process_again; |
3575 | case '.': | ||
3576 | goto process_again; | ||
3522 | case 'p': | 3577 | case 'p': |
3523 | ls = 1; | 3578 | ls = 1; |
3524 | /* fall through */ | 3579 | /* fall through */ |
@@ -3526,23 +3581,30 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3526 | case 'u': | 3581 | case 'u': |
3527 | case 'x': | 3582 | case 'x': |
3528 | case 'i': | 3583 | case 'i': |
3529 | /* the pointers are always 4 bytes aligned */ | ||
3530 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3531 | ~3); | ||
3532 | switch (ls) { | 3584 | switch (ls) { |
3533 | case 0: | 3585 | case 0: |
3534 | ls = 4; | 3586 | vsize = 4; |
3535 | break; | 3587 | break; |
3536 | case 1: | 3588 | case 1: |
3537 | ls = pevent->long_size; | 3589 | vsize = pevent->long_size; |
3538 | break; | 3590 | break; |
3539 | case 2: | 3591 | case 2: |
3540 | ls = 8; | 3592 | vsize = 8; |
3593 | break; | ||
3541 | default: | 3594 | default: |
3595 | vsize = ls; /* ? */ | ||
3542 | break; | 3596 | break; |
3543 | } | 3597 | } |
3544 | val = pevent_read_number(pevent, bptr, ls); | 3598 | /* fall through */ |
3545 | bptr += ls; | 3599 | case '*': |
3600 | if (*ptr == '*') | ||
3601 | vsize = 4; | ||
3602 | |||
3603 | /* the pointers are always 4 bytes aligned */ | ||
3604 | bptr = (void *)(((unsigned long)bptr + 3) & | ||
3605 | ~3); | ||
3606 | val = pevent_read_number(pevent, bptr, vsize); | ||
3607 | bptr += vsize; | ||
3546 | arg = alloc_arg(); | 3608 | arg = alloc_arg(); |
3547 | arg->next = NULL; | 3609 | arg->next = NULL; |
3548 | arg->type = PRINT_ATOM; | 3610 | arg->type = PRINT_ATOM; |
@@ -3550,12 +3612,21 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3550 | sprintf(arg->atom.atom, "%lld", val); | 3612 | sprintf(arg->atom.atom, "%lld", val); |
3551 | *next = arg; | 3613 | *next = arg; |
3552 | next = &arg->next; | 3614 | next = &arg->next; |
3615 | /* | ||
3616 | * The '*' case means that an arg is used as the length. | ||
3617 | * We need to continue to figure out for what. | ||
3618 | */ | ||
3619 | if (*ptr == '*') | ||
3620 | goto process_again; | ||
3621 | |||
3553 | break; | 3622 | break; |
3554 | case 's': | 3623 | case 's': |
3555 | arg = alloc_arg(); | 3624 | arg = alloc_arg(); |
3556 | arg->next = NULL; | 3625 | arg->next = NULL; |
3557 | arg->type = PRINT_BSTRING; | 3626 | arg->type = PRINT_BSTRING; |
3558 | arg->string.string = strdup(bptr); | 3627 | arg->string.string = strdup(bptr); |
3628 | if (!arg->string.string) | ||
3629 | break; | ||
3559 | bptr += strlen(bptr) + 1; | 3630 | bptr += strlen(bptr) + 1; |
3560 | *next = arg; | 3631 | *next = arg; |
3561 | next = &arg->next; | 3632 | next = &arg->next; |
@@ -3841,6 +3912,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3841 | } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { | 3912 | } else if (*(ptr+1) == 'M' || *(ptr+1) == 'm') { |
3842 | print_mac_arg(s, *(ptr+1), data, size, event, arg); | 3913 | print_mac_arg(s, *(ptr+1), data, size, event, arg); |
3843 | ptr++; | 3914 | ptr++; |
3915 | arg = arg->next; | ||
3844 | break; | 3916 | break; |
3845 | } | 3917 | } |
3846 | 3918 | ||
@@ -3877,14 +3949,15 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3877 | break; | 3949 | break; |
3878 | } | 3950 | } |
3879 | } | 3951 | } |
3880 | if (pevent->long_size == 8 && ls) { | 3952 | if (pevent->long_size == 8 && ls && |
3953 | sizeof(long) != 8) { | ||
3881 | char *p; | 3954 | char *p; |
3882 | 3955 | ||
3883 | ls = 2; | 3956 | ls = 2; |
3884 | /* make %l into %ll */ | 3957 | /* make %l into %ll */ |
3885 | p = strchr(format, 'l'); | 3958 | p = strchr(format, 'l'); |
3886 | if (p) | 3959 | if (p) |
3887 | memmove(p, p+1, strlen(p)+1); | 3960 | memmove(p+1, p, strlen(p)+1); |
3888 | else if (strcmp(format, "%p") == 0) | 3961 | else if (strcmp(format, "%p") == 0) |
3889 | strcpy(format, "0x%llx"); | 3962 | strcpy(format, "0x%llx"); |
3890 | } | 3963 | } |
@@ -3961,8 +4034,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
3961 | * pevent_data_lat_fmt - parse the data for the latency format | 4034 | * pevent_data_lat_fmt - parse the data for the latency format |
3962 | * @pevent: a handle to the pevent | 4035 | * @pevent: a handle to the pevent |
3963 | * @s: the trace_seq to write to | 4036 | * @s: the trace_seq to write to |
3964 | * @data: the raw data to read from | 4037 | * @record: the record to read from |
3965 | * @size: currently unused. | ||
3966 | * | 4038 | * |
3967 | * This parses out the Latency format (interrupts disabled, | 4039 | * This parses out the Latency format (interrupts disabled, |
3968 | * need rescheduling, in hard/soft interrupt, preempt count | 4040 | * need rescheduling, in hard/soft interrupt, preempt count |
@@ -3972,10 +4044,13 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
3972 | struct trace_seq *s, struct pevent_record *record) | 4044 | struct trace_seq *s, struct pevent_record *record) |
3973 | { | 4045 | { |
3974 | static int check_lock_depth = 1; | 4046 | static int check_lock_depth = 1; |
4047 | static int check_migrate_disable = 1; | ||
3975 | static int lock_depth_exists; | 4048 | static int lock_depth_exists; |
4049 | static int migrate_disable_exists; | ||
3976 | unsigned int lat_flags; | 4050 | unsigned int lat_flags; |
3977 | unsigned int pc; | 4051 | unsigned int pc; |
3978 | int lock_depth; | 4052 | int lock_depth; |
4053 | int migrate_disable; | ||
3979 | int hardirq; | 4054 | int hardirq; |
3980 | int softirq; | 4055 | int softirq; |
3981 | void *data = record->data; | 4056 | void *data = record->data; |
@@ -3983,18 +4058,26 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
3983 | lat_flags = parse_common_flags(pevent, data); | 4058 | lat_flags = parse_common_flags(pevent, data); |
3984 | pc = parse_common_pc(pevent, data); | 4059 | pc = parse_common_pc(pevent, data); |
3985 | /* lock_depth may not always exist */ | 4060 | /* lock_depth may not always exist */ |
3986 | if (check_lock_depth) { | ||
3987 | struct format_field *field; | ||
3988 | struct event_format *event; | ||
3989 | |||
3990 | check_lock_depth = 0; | ||
3991 | event = pevent->events[0]; | ||
3992 | field = pevent_find_common_field(event, "common_lock_depth"); | ||
3993 | if (field) | ||
3994 | lock_depth_exists = 1; | ||
3995 | } | ||
3996 | if (lock_depth_exists) | 4061 | if (lock_depth_exists) |
3997 | lock_depth = parse_common_lock_depth(pevent, data); | 4062 | lock_depth = parse_common_lock_depth(pevent, data); |
4063 | else if (check_lock_depth) { | ||
4064 | lock_depth = parse_common_lock_depth(pevent, data); | ||
4065 | if (lock_depth < 0) | ||
4066 | check_lock_depth = 0; | ||
4067 | else | ||
4068 | lock_depth_exists = 1; | ||
4069 | } | ||
4070 | |||
4071 | /* migrate_disable may not always exist */ | ||
4072 | if (migrate_disable_exists) | ||
4073 | migrate_disable = parse_common_migrate_disable(pevent, data); | ||
4074 | else if (check_migrate_disable) { | ||
4075 | migrate_disable = parse_common_migrate_disable(pevent, data); | ||
4076 | if (migrate_disable < 0) | ||
4077 | check_migrate_disable = 0; | ||
4078 | else | ||
4079 | migrate_disable_exists = 1; | ||
4080 | } | ||
3998 | 4081 | ||
3999 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; | 4082 | hardirq = lat_flags & TRACE_FLAG_HARDIRQ; |
4000 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; | 4083 | softirq = lat_flags & TRACE_FLAG_SOFTIRQ; |
@@ -4013,6 +4096,13 @@ void pevent_data_lat_fmt(struct pevent *pevent, | |||
4013 | else | 4096 | else |
4014 | trace_seq_putc(s, '.'); | 4097 | trace_seq_putc(s, '.'); |
4015 | 4098 | ||
4099 | if (migrate_disable_exists) { | ||
4100 | if (migrate_disable < 0) | ||
4101 | trace_seq_putc(s, '.'); | ||
4102 | else | ||
4103 | trace_seq_printf(s, "%d", migrate_disable); | ||
4104 | } | ||
4105 | |||
4016 | if (lock_depth_exists) { | 4106 | if (lock_depth_exists) { |
4017 | if (lock_depth < 0) | 4107 | if (lock_depth < 0) |
4018 | trace_seq_putc(s, '.'); | 4108 | trace_seq_putc(s, '.'); |
@@ -4079,10 +4169,7 @@ const char *pevent_data_comm_from_pid(struct pevent *pevent, int pid) | |||
4079 | * pevent_data_comm_from_pid - parse the data into the print format | 4169 | * pevent_data_comm_from_pid - parse the data into the print format |
4080 | * @s: the trace_seq to write to | 4170 | * @s: the trace_seq to write to |
4081 | * @event: the handle to the event | 4171 | * @event: the handle to the event |
4082 | * @cpu: the cpu the event was recorded on | 4172 | * @record: the record to read from |
4083 | * @data: the raw data | ||
4084 | * @size: the size of the raw data | ||
4085 | * @nsecs: the timestamp of the event | ||
4086 | * | 4173 | * |
4087 | * This parses the raw @data using the given @event information and | 4174 | * This parses the raw @data using the given @event information and |
4088 | * writes the print format into the trace_seq. | 4175 | * writes the print format into the trace_seq. |
@@ -4631,6 +4718,8 @@ int pevent_parse_event(struct pevent *pevent, | |||
4631 | die("failed to read event id"); | 4718 | die("failed to read event id"); |
4632 | 4719 | ||
4633 | event->system = strdup(sys); | 4720 | event->system = strdup(sys); |
4721 | if (!event->system) | ||
4722 | die("failed to allocate system"); | ||
4634 | 4723 | ||
4635 | /* Add pevent to event so that it can be referenced */ | 4724 | /* Add pevent to event so that it can be referenced */ |
4636 | event->pevent = pevent; | 4725 | event->pevent = pevent; |
@@ -4672,6 +4761,11 @@ int pevent_parse_event(struct pevent *pevent, | |||
4672 | list = &arg->next; | 4761 | list = &arg->next; |
4673 | arg->type = PRINT_FIELD; | 4762 | arg->type = PRINT_FIELD; |
4674 | arg->field.name = strdup(field->name); | 4763 | arg->field.name = strdup(field->name); |
4764 | if (!arg->field.name) { | ||
4765 | do_warning("failed to allocate field name"); | ||
4766 | event->flags |= EVENT_FL_FAILED; | ||
4767 | return -1; | ||
4768 | } | ||
4675 | arg->field.field = field; | 4769 | arg->field.field = field; |
4676 | } | 4770 | } |
4677 | return 0; | 4771 | return 0; |
@@ -4843,7 +4937,7 @@ int pevent_get_any_field_val(struct trace_seq *s, struct event_format *event, | |||
4843 | * @record: The record with the field name. | 4937 | * @record: The record with the field name. |
4844 | * @err: print default error if failed. | 4938 | * @err: print default error if failed. |
4845 | * | 4939 | * |
4846 | * Returns: 0 on success, -1 field not fould, or 1 if buffer is full. | 4940 | * Returns: 0 on success, -1 field not found, or 1 if buffer is full. |
4847 | */ | 4941 | */ |
4848 | int pevent_print_num_field(struct trace_seq *s, const char *fmt, | 4942 | int pevent_print_num_field(struct trace_seq *s, const char *fmt, |
4849 | struct event_format *event, const char *name, | 4943 | struct event_format *event, const char *name, |
@@ -4885,11 +4979,12 @@ static void free_func_handle(struct pevent_function_handler *func) | |||
4885 | * pevent_register_print_function - register a helper function | 4979 | * pevent_register_print_function - register a helper function |
4886 | * @pevent: the handle to the pevent | 4980 | * @pevent: the handle to the pevent |
4887 | * @func: the function to process the helper function | 4981 | * @func: the function to process the helper function |
4982 | * @ret_type: the return type of the helper function | ||
4888 | * @name: the name of the helper function | 4983 | * @name: the name of the helper function |
4889 | * @parameters: A list of enum pevent_func_arg_type | 4984 | * @parameters: A list of enum pevent_func_arg_type |
4890 | * | 4985 | * |
4891 | * Some events may have helper functions in the print format arguments. | 4986 | * Some events may have helper functions in the print format arguments. |
4892 | * This allows a plugin to dynmically create a way to process one | 4987 | * This allows a plugin to dynamically create a way to process one |
4893 | * of these functions. | 4988 | * of these functions. |
4894 | * | 4989 | * |
4895 | * The @parameters is a variable list of pevent_func_arg_type enums that | 4990 | * The @parameters is a variable list of pevent_func_arg_type enums that |
@@ -4960,12 +5055,13 @@ int pevent_register_print_function(struct pevent *pevent, | |||
4960 | } | 5055 | } |
4961 | 5056 | ||
4962 | /** | 5057 | /** |
4963 | * pevent_register_event_handle - register a way to parse an event | 5058 | * pevent_register_event_handler - register a way to parse an event |
4964 | * @pevent: the handle to the pevent | 5059 | * @pevent: the handle to the pevent |
4965 | * @id: the id of the event to register | 5060 | * @id: the id of the event to register |
4966 | * @sys_name: the system name the event belongs to | 5061 | * @sys_name: the system name the event belongs to |
4967 | * @event_name: the name of the event | 5062 | * @event_name: the name of the event |
4968 | * @func: the function to call to parse the event information | 5063 | * @func: the function to call to parse the event information |
5064 | * @context: the data to be passed to @func | ||
4969 | * | 5065 | * |
4970 | * This function allows a developer to override the parsing of | 5066 | * This function allows a developer to override the parsing of |
4971 | * a given event. If for some reason the default print format | 5067 | * a given event. If for some reason the default print format |
@@ -5015,6 +5111,11 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
5015 | if (sys_name) | 5111 | if (sys_name) |
5016 | handle->sys_name = strdup(sys_name); | 5112 | handle->sys_name = strdup(sys_name); |
5017 | 5113 | ||
5114 | if ((event_name && !handle->event_name) || | ||
5115 | (sys_name && !handle->sys_name)) { | ||
5116 | die("Failed to allocate event/sys name"); | ||
5117 | } | ||
5118 | |||
5018 | handle->func = func; | 5119 | handle->func = func; |
5019 | handle->next = pevent->handlers; | 5120 | handle->next = pevent->handlers; |
5020 | pevent->handlers = handle; | 5121 | pevent->handlers = handle; |
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c index dfcfe2c131de..ad17855528f9 100644 --- a/tools/lib/traceevent/parse-filter.c +++ b/tools/lib/traceevent/parse-filter.c | |||
@@ -96,7 +96,7 @@ static enum event_type read_token(char **tok) | |||
96 | (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && | 96 | (strcmp(token, "=") == 0 || strcmp(token, "!") == 0) && |
97 | pevent_peek_char() == '~') { | 97 | pevent_peek_char() == '~') { |
98 | /* append it */ | 98 | /* append it */ |
99 | *tok = malloc(3); | 99 | *tok = malloc_or_die(3); |
100 | sprintf(*tok, "%c%c", *token, '~'); | 100 | sprintf(*tok, "%c%c", *token, '~'); |
101 | free_token(token); | 101 | free_token(token); |
102 | /* Now remove the '~' from the buffer */ | 102 | /* Now remove the '~' from the buffer */ |
@@ -148,17 +148,11 @@ add_filter_type(struct event_filter *filter, int id) | |||
148 | if (filter_type) | 148 | if (filter_type) |
149 | return filter_type; | 149 | return filter_type; |
150 | 150 | ||
151 | if (!filter->filters) | 151 | filter->event_filters = realloc(filter->event_filters, |
152 | filter->event_filters = | 152 | sizeof(*filter->event_filters) * |
153 | malloc_or_die(sizeof(*filter->event_filters)); | 153 | (filter->filters + 1)); |
154 | else { | 154 | if (!filter->event_filters) |
155 | filter->event_filters = | 155 | die("Could not allocate filter"); |
156 | realloc(filter->event_filters, | ||
157 | sizeof(*filter->event_filters) * | ||
158 | (filter->filters + 1)); | ||
159 | if (!filter->event_filters) | ||
160 | die("Could not allocate filter"); | ||
161 | } | ||
162 | 156 | ||
163 | for (i = 0; i < filter->filters; i++) { | 157 | for (i = 0; i < filter->filters; i++) { |
164 | if (filter->event_filters[i].event_id > id) | 158 | if (filter->event_filters[i].event_id > id) |
@@ -1480,7 +1474,7 @@ void pevent_filter_clear_trivial(struct event_filter *filter, | |||
1480 | { | 1474 | { |
1481 | struct filter_type *filter_type; | 1475 | struct filter_type *filter_type; |
1482 | int count = 0; | 1476 | int count = 0; |
1483 | int *ids; | 1477 | int *ids = NULL; |
1484 | int i; | 1478 | int i; |
1485 | 1479 | ||
1486 | if (!filter->filters) | 1480 | if (!filter->filters) |
@@ -1504,10 +1498,8 @@ void pevent_filter_clear_trivial(struct event_filter *filter, | |||
1504 | default: | 1498 | default: |
1505 | break; | 1499 | break; |
1506 | } | 1500 | } |
1507 | if (count) | 1501 | |
1508 | ids = realloc(ids, sizeof(*ids) * (count + 1)); | 1502 | ids = realloc(ids, sizeof(*ids) * (count + 1)); |
1509 | else | ||
1510 | ids = malloc(sizeof(*ids)); | ||
1511 | if (!ids) | 1503 | if (!ids) |
1512 | die("Can't allocate ids"); | 1504 | die("Can't allocate ids"); |
1513 | ids[count++] = filter_type->event_id; | 1505 | ids[count++] = filter_type->event_id; |
@@ -1710,18 +1702,43 @@ static int test_num(struct event_format *event, | |||
1710 | 1702 | ||
1711 | static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) | 1703 | static const char *get_field_str(struct filter_arg *arg, struct pevent_record *record) |
1712 | { | 1704 | { |
1713 | const char *val = record->data + arg->str.field->offset; | 1705 | struct event_format *event; |
1706 | struct pevent *pevent; | ||
1707 | unsigned long long addr; | ||
1708 | const char *val = NULL; | ||
1709 | char hex[64]; | ||
1714 | 1710 | ||
1715 | /* | 1711 | /* If the field is not a string convert it */ |
1716 | * We need to copy the data since we can't be sure the field | 1712 | if (arg->str.field->flags & FIELD_IS_STRING) { |
1717 | * is null terminated. | 1713 | val = record->data + arg->str.field->offset; |
1718 | */ | 1714 | |
1719 | if (*(val + arg->str.field->size - 1)) { | 1715 | /* |
1720 | /* copy it */ | 1716 | * We need to copy the data since we can't be sure the field |
1721 | memcpy(arg->str.buffer, val, arg->str.field->size); | 1717 | * is null terminated. |
1722 | /* the buffer is already NULL terminated */ | 1718 | */ |
1723 | val = arg->str.buffer; | 1719 | if (*(val + arg->str.field->size - 1)) { |
1720 | /* copy it */ | ||
1721 | memcpy(arg->str.buffer, val, arg->str.field->size); | ||
1722 | /* the buffer is already NULL terminated */ | ||
1723 | val = arg->str.buffer; | ||
1724 | } | ||
1725 | |||
1726 | } else { | ||
1727 | event = arg->str.field->event; | ||
1728 | pevent = event->pevent; | ||
1729 | addr = get_value(event, arg->str.field, record); | ||
1730 | |||
1731 | if (arg->str.field->flags & (FIELD_IS_POINTER | FIELD_IS_LONG)) | ||
1732 | /* convert to a kernel symbol */ | ||
1733 | val = pevent_find_function(pevent, addr); | ||
1734 | |||
1735 | if (val == NULL) { | ||
1736 | /* just use the hex of the string name */ | ||
1737 | snprintf(hex, 64, "0x%llx", addr); | ||
1738 | val = hex; | ||
1739 | } | ||
1724 | } | 1740 | } |
1741 | |||
1725 | return val; | 1742 | return val; |
1726 | } | 1743 | } |
1727 | 1744 | ||
@@ -2001,11 +2018,13 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2001 | char *lstr; | 2018 | char *lstr; |
2002 | char *rstr; | 2019 | char *rstr; |
2003 | char *op; | 2020 | char *op; |
2004 | char *str; | 2021 | char *str = NULL; |
2005 | int len; | 2022 | int len; |
2006 | 2023 | ||
2007 | lstr = arg_to_str(filter, arg->exp.left); | 2024 | lstr = arg_to_str(filter, arg->exp.left); |
2008 | rstr = arg_to_str(filter, arg->exp.right); | 2025 | rstr = arg_to_str(filter, arg->exp.right); |
2026 | if (!lstr || !rstr) | ||
2027 | goto out; | ||
2009 | 2028 | ||
2010 | switch (arg->exp.type) { | 2029 | switch (arg->exp.type) { |
2011 | case FILTER_EXP_ADD: | 2030 | case FILTER_EXP_ADD: |
@@ -2045,6 +2064,7 @@ static char *exp_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2045 | len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; | 2064 | len = strlen(op) + strlen(lstr) + strlen(rstr) + 4; |
2046 | str = malloc_or_die(len); | 2065 | str = malloc_or_die(len); |
2047 | snprintf(str, len, "%s %s %s", lstr, op, rstr); | 2066 | snprintf(str, len, "%s %s %s", lstr, op, rstr); |
2067 | out: | ||
2048 | free(lstr); | 2068 | free(lstr); |
2049 | free(rstr); | 2069 | free(rstr); |
2050 | 2070 | ||
@@ -2061,6 +2081,8 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2061 | 2081 | ||
2062 | lstr = arg_to_str(filter, arg->num.left); | 2082 | lstr = arg_to_str(filter, arg->num.left); |
2063 | rstr = arg_to_str(filter, arg->num.right); | 2083 | rstr = arg_to_str(filter, arg->num.right); |
2084 | if (!lstr || !rstr) | ||
2085 | goto out; | ||
2064 | 2086 | ||
2065 | switch (arg->num.type) { | 2087 | switch (arg->num.type) { |
2066 | case FILTER_CMP_EQ: | 2088 | case FILTER_CMP_EQ: |
@@ -2097,6 +2119,7 @@ static char *num_to_str(struct event_filter *filter, struct filter_arg *arg) | |||
2097 | break; | 2119 | break; |
2098 | } | 2120 | } |
2099 | 2121 | ||
2122 | out: | ||
2100 | free(lstr); | 2123 | free(lstr); |
2101 | free(rstr); | 2124 | free(rstr); |
2102 | return str; | 2125 | return str; |
@@ -2247,7 +2270,12 @@ int pevent_filter_compare(struct event_filter *filter1, struct event_filter *fil | |||
2247 | /* The best way to compare complex filters is with strings */ | 2270 | /* The best way to compare complex filters is with strings */ |
2248 | str1 = arg_to_str(filter1, filter_type1->filter); | 2271 | str1 = arg_to_str(filter1, filter_type1->filter); |
2249 | str2 = arg_to_str(filter2, filter_type2->filter); | 2272 | str2 = arg_to_str(filter2, filter_type2->filter); |
2250 | result = strcmp(str1, str2) != 0; | 2273 | if (str1 && str2) |
2274 | result = strcmp(str1, str2) != 0; | ||
2275 | else | ||
2276 | /* bail out if allocation fails */ | ||
2277 | result = 1; | ||
2278 | |||
2251 | free(str1); | 2279 | free(str1); |
2252 | free(str2); | 2280 | free(str2); |
2253 | if (result) | 2281 | if (result) |