diff options
Diffstat (limited to 'tools/lib/traceevent/event-parse.c')
| -rw-r--r-- | tools/lib/traceevent/event-parse.c | 754 |
1 files changed, 548 insertions, 206 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 5f34aa371b56..47264b4652b9 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
| @@ -24,13 +24,14 @@ | |||
| 24 | * Frederic Weisbecker gave his permission to relicense the code to | 24 | * Frederic Weisbecker gave his permission to relicense the code to |
| 25 | * the Lesser General Public License. | 25 | * the Lesser General Public License. |
| 26 | */ | 26 | */ |
| 27 | #define _GNU_SOURCE | ||
| 28 | #include <stdio.h> | 27 | #include <stdio.h> |
| 29 | #include <stdlib.h> | 28 | #include <stdlib.h> |
| 30 | #include <string.h> | 29 | #include <string.h> |
| 31 | #include <stdarg.h> | 30 | #include <stdarg.h> |
| 32 | #include <ctype.h> | 31 | #include <ctype.h> |
| 33 | #include <errno.h> | 32 | #include <errno.h> |
| 33 | #include <stdint.h> | ||
| 34 | #include <limits.h> | ||
| 34 | 35 | ||
| 35 | #include "event-parse.h" | 36 | #include "event-parse.h" |
| 36 | #include "event-utils.h" | 37 | #include "event-utils.h" |
| @@ -117,14 +118,7 @@ void breakpoint(void) | |||
| 117 | 118 | ||
| 118 | struct print_arg *alloc_arg(void) | 119 | struct print_arg *alloc_arg(void) |
| 119 | { | 120 | { |
| 120 | struct print_arg *arg; | 121 | return calloc(1, sizeof(struct print_arg)); |
| 121 | |||
| 122 | arg = malloc_or_die(sizeof(*arg)); | ||
| 123 | if (!arg) | ||
| 124 | return NULL; | ||
| 125 | memset(arg, 0, sizeof(*arg)); | ||
| 126 | |||
| 127 | return arg; | ||
| 128 | } | 122 | } |
| 129 | 123 | ||
| 130 | struct cmdline { | 124 | struct cmdline { |
| @@ -158,7 +152,9 @@ static int cmdline_init(struct pevent *pevent) | |||
| 158 | struct cmdline *cmdlines; | 152 | struct cmdline *cmdlines; |
| 159 | int i; | 153 | int i; |
| 160 | 154 | ||
| 161 | cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count); | 155 | cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); |
| 156 | if (!cmdlines) | ||
| 157 | return -1; | ||
| 162 | 158 | ||
| 163 | i = 0; | 159 | i = 0; |
| 164 | while (cmdlist) { | 160 | while (cmdlist) { |
| @@ -186,8 +182,8 @@ static char *find_cmdline(struct pevent *pevent, int pid) | |||
| 186 | if (!pid) | 182 | if (!pid) |
| 187 | return "<idle>"; | 183 | return "<idle>"; |
| 188 | 184 | ||
| 189 | if (!pevent->cmdlines) | 185 | if (!pevent->cmdlines && cmdline_init(pevent)) |
| 190 | cmdline_init(pevent); | 186 | return "<not enough memory for cmdlines!>"; |
| 191 | 187 | ||
| 192 | key.pid = pid; | 188 | key.pid = pid; |
| 193 | 189 | ||
| @@ -215,8 +211,8 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid) | |||
| 215 | if (!pid) | 211 | if (!pid) |
| 216 | return 1; | 212 | return 1; |
| 217 | 213 | ||
| 218 | if (!pevent->cmdlines) | 214 | if (!pevent->cmdlines && cmdline_init(pevent)) |
| 219 | cmdline_init(pevent); | 215 | return 0; |
| 220 | 216 | ||
| 221 | key.pid = pid; | 217 | key.pid = pid; |
| 222 | 218 | ||
| @@ -258,10 +254,14 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid) | |||
| 258 | return -1; | 254 | return -1; |
| 259 | } | 255 | } |
| 260 | 256 | ||
| 261 | cmdlines[pevent->cmdline_count].pid = pid; | ||
| 262 | cmdlines[pevent->cmdline_count].comm = strdup(comm); | 257 | cmdlines[pevent->cmdline_count].comm = strdup(comm); |
| 263 | if (!cmdlines[pevent->cmdline_count].comm) | 258 | if (!cmdlines[pevent->cmdline_count].comm) { |
| 264 | die("malloc comm"); | 259 | free(cmdlines); |
| 260 | errno = ENOMEM; | ||
| 261 | return -1; | ||
| 262 | } | ||
| 263 | |||
| 264 | cmdlines[pevent->cmdline_count].pid = pid; | ||
| 265 | 265 | ||
| 266 | if (cmdlines[pevent->cmdline_count].comm) | 266 | if (cmdlines[pevent->cmdline_count].comm) |
| 267 | pevent->cmdline_count++; | 267 | pevent->cmdline_count++; |
| @@ -288,10 +288,15 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid) | |||
| 288 | if (pevent->cmdlines) | 288 | if (pevent->cmdlines) |
| 289 | return add_new_comm(pevent, comm, pid); | 289 | return add_new_comm(pevent, comm, pid); |
| 290 | 290 | ||
| 291 | item = malloc_or_die(sizeof(*item)); | 291 | item = malloc(sizeof(*item)); |
| 292 | if (!item) | ||
| 293 | return -1; | ||
| 294 | |||
| 292 | item->comm = strdup(comm); | 295 | item->comm = strdup(comm); |
| 293 | if (!item->comm) | 296 | if (!item->comm) { |
| 294 | die("malloc comm"); | 297 | free(item); |
| 298 | return -1; | ||
| 299 | } | ||
| 295 | item->pid = pid; | 300 | item->pid = pid; |
| 296 | item->next = pevent->cmdlist; | 301 | item->next = pevent->cmdlist; |
| 297 | 302 | ||
| @@ -355,7 +360,10 @@ static int func_map_init(struct pevent *pevent) | |||
| 355 | struct func_map *func_map; | 360 | struct func_map *func_map; |
| 356 | int i; | 361 | int i; |
| 357 | 362 | ||
| 358 | func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1)); | 363 | func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1)); |
| 364 | if (!func_map) | ||
| 365 | return -1; | ||
| 366 | |||
| 359 | funclist = pevent->funclist; | 367 | funclist = pevent->funclist; |
| 360 | 368 | ||
| 361 | i = 0; | 369 | i = 0; |
| @@ -455,25 +463,36 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr) | |||
| 455 | int pevent_register_function(struct pevent *pevent, char *func, | 463 | int pevent_register_function(struct pevent *pevent, char *func, |
| 456 | unsigned long long addr, char *mod) | 464 | unsigned long long addr, char *mod) |
| 457 | { | 465 | { |
| 458 | struct func_list *item; | 466 | struct func_list *item = malloc(sizeof(*item)); |
| 459 | 467 | ||
| 460 | item = malloc_or_die(sizeof(*item)); | 468 | if (!item) |
| 469 | return -1; | ||
| 461 | 470 | ||
| 462 | item->next = pevent->funclist; | 471 | item->next = pevent->funclist; |
| 463 | item->func = strdup(func); | 472 | item->func = strdup(func); |
| 464 | if (mod) | 473 | if (!item->func) |
| 474 | goto out_free; | ||
| 475 | |||
| 476 | if (mod) { | ||
| 465 | item->mod = strdup(mod); | 477 | item->mod = strdup(mod); |
| 466 | else | 478 | if (!item->mod) |
| 479 | goto out_free_func; | ||
| 480 | } else | ||
| 467 | item->mod = NULL; | 481 | item->mod = NULL; |
| 468 | item->addr = addr; | 482 | item->addr = addr; |
| 469 | 483 | ||
| 470 | if (!item->func || (mod && !item->mod)) | ||
| 471 | die("malloc func"); | ||
| 472 | |||
| 473 | pevent->funclist = item; | 484 | pevent->funclist = item; |
| 474 | pevent->func_count++; | 485 | pevent->func_count++; |
| 475 | 486 | ||
| 476 | return 0; | 487 | return 0; |
| 488 | |||
| 489 | out_free_func: | ||
| 490 | free(item->func); | ||
| 491 | item->func = NULL; | ||
| 492 | out_free: | ||
| 493 | free(item); | ||
| 494 | errno = ENOMEM; | ||
| 495 | return -1; | ||
| 477 | } | 496 | } |
| 478 | 497 | ||
| 479 | /** | 498 | /** |
| @@ -524,14 +543,16 @@ static int printk_cmp(const void *a, const void *b) | |||
| 524 | return 0; | 543 | return 0; |
| 525 | } | 544 | } |
| 526 | 545 | ||
| 527 | static void printk_map_init(struct pevent *pevent) | 546 | static int printk_map_init(struct pevent *pevent) |
| 528 | { | 547 | { |
| 529 | struct printk_list *printklist; | 548 | struct printk_list *printklist; |
| 530 | struct printk_list *item; | 549 | struct printk_list *item; |
| 531 | struct printk_map *printk_map; | 550 | struct printk_map *printk_map; |
| 532 | int i; | 551 | int i; |
| 533 | 552 | ||
| 534 | printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1)); | 553 | printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1)); |
| 554 | if (!printk_map) | ||
| 555 | return -1; | ||
| 535 | 556 | ||
| 536 | printklist = pevent->printklist; | 557 | printklist = pevent->printklist; |
| 537 | 558 | ||
| @@ -549,6 +570,8 @@ static void printk_map_init(struct pevent *pevent) | |||
| 549 | 570 | ||
| 550 | pevent->printk_map = printk_map; | 571 | pevent->printk_map = printk_map; |
| 551 | pevent->printklist = NULL; | 572 | pevent->printklist = NULL; |
| 573 | |||
| 574 | return 0; | ||
| 552 | } | 575 | } |
| 553 | 576 | ||
| 554 | static struct printk_map * | 577 | static struct printk_map * |
| @@ -557,8 +580,8 @@ find_printk(struct pevent *pevent, unsigned long long addr) | |||
| 557 | struct printk_map *printk; | 580 | struct printk_map *printk; |
| 558 | struct printk_map key; | 581 | struct printk_map key; |
| 559 | 582 | ||
| 560 | if (!pevent->printk_map) | 583 | if (!pevent->printk_map && printk_map_init(pevent)) |
| 561 | printk_map_init(pevent); | 584 | return NULL; |
| 562 | 585 | ||
| 563 | key.addr = addr; | 586 | key.addr = addr; |
| 564 | 587 | ||
| @@ -580,21 +603,27 @@ find_printk(struct pevent *pevent, unsigned long long addr) | |||
| 580 | int pevent_register_print_string(struct pevent *pevent, char *fmt, | 603 | int pevent_register_print_string(struct pevent *pevent, char *fmt, |
| 581 | unsigned long long addr) | 604 | unsigned long long addr) |
| 582 | { | 605 | { |
| 583 | struct printk_list *item; | 606 | struct printk_list *item = malloc(sizeof(*item)); |
| 584 | 607 | ||
| 585 | item = malloc_or_die(sizeof(*item)); | 608 | if (!item) |
| 609 | return -1; | ||
| 586 | 610 | ||
| 587 | item->next = pevent->printklist; | 611 | item->next = pevent->printklist; |
| 588 | item->printk = strdup(fmt); | ||
| 589 | item->addr = addr; | 612 | item->addr = addr; |
| 590 | 613 | ||
| 614 | item->printk = strdup(fmt); | ||
| 591 | if (!item->printk) | 615 | if (!item->printk) |
| 592 | die("malloc fmt"); | 616 | goto out_free; |
| 593 | 617 | ||
| 594 | pevent->printklist = item; | 618 | pevent->printklist = item; |
| 595 | pevent->printk_count++; | 619 | pevent->printk_count++; |
| 596 | 620 | ||
| 597 | return 0; | 621 | return 0; |
| 622 | |||
| 623 | out_free: | ||
| 624 | free(item); | ||
| 625 | errno = ENOMEM; | ||
| 626 | return -1; | ||
| 598 | } | 627 | } |
| 599 | 628 | ||
| 600 | /** | 629 | /** |
| @@ -619,24 +648,18 @@ void pevent_print_printk(struct pevent *pevent) | |||
| 619 | 648 | ||
| 620 | static struct event_format *alloc_event(void) | 649 | static struct event_format *alloc_event(void) |
| 621 | { | 650 | { |
| 622 | struct event_format *event; | 651 | return calloc(1, sizeof(struct event_format)); |
| 623 | |||
| 624 | event = malloc(sizeof(*event)); | ||
| 625 | if (!event) | ||
| 626 | return NULL; | ||
| 627 | memset(event, 0, sizeof(*event)); | ||
| 628 | |||
| 629 | return event; | ||
| 630 | } | 652 | } |
| 631 | 653 | ||
| 632 | static void add_event(struct pevent *pevent, struct event_format *event) | 654 | static int add_event(struct pevent *pevent, struct event_format *event) |
| 633 | { | 655 | { |
| 634 | int i; | 656 | int i; |
| 657 | struct event_format **events = realloc(pevent->events, sizeof(event) * | ||
| 658 | (pevent->nr_events + 1)); | ||
| 659 | if (!events) | ||
| 660 | return -1; | ||
| 635 | 661 | ||
| 636 | pevent->events = realloc(pevent->events, sizeof(event) * | 662 | pevent->events = events; |
| 637 | (pevent->nr_events + 1)); | ||
| 638 | if (!pevent->events) | ||
| 639 | die("Can not allocate events"); | ||
| 640 | 663 | ||
| 641 | for (i = 0; i < pevent->nr_events; i++) { | 664 | for (i = 0; i < pevent->nr_events; i++) { |
| 642 | if (pevent->events[i]->id > event->id) | 665 | if (pevent->events[i]->id > event->id) |
| @@ -651,6 +674,8 @@ static void add_event(struct pevent *pevent, struct event_format *event) | |||
| 651 | pevent->nr_events++; | 674 | pevent->nr_events++; |
| 652 | 675 | ||
| 653 | event->pevent = pevent; | 676 | event->pevent = pevent; |
| 677 | |||
| 678 | return 0; | ||
| 654 | } | 679 | } |
| 655 | 680 | ||
| 656 | static int event_item_type(enum event_type type) | 681 | static int event_item_type(enum event_type type) |
| @@ -827,9 +852,9 @@ static enum event_type __read_token(char **tok) | |||
| 827 | switch (type) { | 852 | switch (type) { |
| 828 | case EVENT_NEWLINE: | 853 | case EVENT_NEWLINE: |
| 829 | case EVENT_DELIM: | 854 | case EVENT_DELIM: |
| 830 | *tok = malloc_or_die(2); | 855 | if (asprintf(tok, "%c", ch) < 0) |
| 831 | (*tok)[0] = ch; | 856 | return EVENT_ERROR; |
| 832 | (*tok)[1] = 0; | 857 | |
| 833 | return type; | 858 | return type; |
| 834 | 859 | ||
| 835 | case EVENT_OP: | 860 | case EVENT_OP: |
| @@ -1240,8 +1265,10 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
| 1240 | 1265 | ||
| 1241 | last_token = token; | 1266 | last_token = token; |
| 1242 | 1267 | ||
| 1243 | field = malloc_or_die(sizeof(*field)); | 1268 | field = calloc(1, sizeof(*field)); |
| 1244 | memset(field, 0, sizeof(*field)); | 1269 | if (!field) |
| 1270 | goto fail; | ||
| 1271 | |||
| 1245 | field->event = event; | 1272 | field->event = event; |
| 1246 | 1273 | ||
| 1247 | /* read the rest of the type */ | 1274 | /* read the rest of the type */ |
| @@ -1282,7 +1309,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
| 1282 | } | 1309 | } |
| 1283 | 1310 | ||
| 1284 | if (!field->type) { | 1311 | if (!field->type) { |
| 1285 | die("no type found"); | 1312 | do_warning("%s: no type found", __func__); |
| 1286 | goto fail; | 1313 | goto fail; |
| 1287 | } | 1314 | } |
| 1288 | field->name = last_token; | 1315 | field->name = last_token; |
| @@ -1329,7 +1356,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f | |||
| 1329 | free_token(token); | 1356 | free_token(token); |
| 1330 | type = read_token(&token); | 1357 | type = read_token(&token); |
| 1331 | if (type == EVENT_NONE) { | 1358 | if (type == EVENT_NONE) { |
| 1332 | die("failed to find token"); | 1359 | do_warning("failed to find token"); |
| 1333 | goto fail; | 1360 | goto fail; |
| 1334 | } | 1361 | } |
| 1335 | } | 1362 | } |
| @@ -1538,6 +1565,14 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok) | |||
| 1538 | left = alloc_arg(); | 1565 | left = alloc_arg(); |
| 1539 | right = alloc_arg(); | 1566 | right = alloc_arg(); |
| 1540 | 1567 | ||
| 1568 | if (!arg || !left || !right) { | ||
| 1569 | do_warning("%s: not enough memory!", __func__); | ||
| 1570 | /* arg will be freed at out_free */ | ||
| 1571 | free_arg(left); | ||
| 1572 | free_arg(right); | ||
| 1573 | goto out_free; | ||
| 1574 | } | ||
| 1575 | |||
| 1541 | arg->type = PRINT_OP; | 1576 | arg->type = PRINT_OP; |
| 1542 | arg->op.left = left; | 1577 | arg->op.left = left; |
| 1543 | arg->op.right = right; | 1578 | arg->op.right = right; |
| @@ -1580,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) | |||
| 1580 | char *token = NULL; | 1615 | char *token = NULL; |
| 1581 | 1616 | ||
| 1582 | arg = alloc_arg(); | 1617 | arg = alloc_arg(); |
| 1618 | if (!arg) { | ||
| 1619 | do_warning("%s: not enough memory!", __func__); | ||
| 1620 | /* '*tok' is set to top->op.op. No need to free. */ | ||
| 1621 | *tok = NULL; | ||
| 1622 | return EVENT_ERROR; | ||
| 1623 | } | ||
| 1583 | 1624 | ||
| 1584 | *tok = NULL; | 1625 | *tok = NULL; |
| 1585 | type = process_arg(event, arg, &token); | 1626 | type = process_arg(event, arg, &token); |
| @@ -1595,8 +1636,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) | |||
| 1595 | return type; | 1636 | return type; |
| 1596 | 1637 | ||
| 1597 | out_free: | 1638 | out_free: |
| 1598 | free_token(*tok); | 1639 | free_token(token); |
| 1599 | *tok = NULL; | ||
| 1600 | free_arg(arg); | 1640 | free_arg(arg); |
| 1601 | return EVENT_ERROR; | 1641 | return EVENT_ERROR; |
| 1602 | } | 1642 | } |
| @@ -1682,7 +1722,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1682 | if (arg->type == PRINT_OP && !arg->op.left) { | 1722 | if (arg->type == PRINT_OP && !arg->op.left) { |
| 1683 | /* handle single op */ | 1723 | /* handle single op */ |
| 1684 | if (token[1]) { | 1724 | if (token[1]) { |
| 1685 | die("bad op token %s", token); | 1725 | do_warning("bad op token %s", token); |
| 1686 | goto out_free; | 1726 | goto out_free; |
| 1687 | } | 1727 | } |
| 1688 | switch (token[0]) { | 1728 | switch (token[0]) { |
| @@ -1699,10 +1739,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1699 | 1739 | ||
| 1700 | /* make an empty left */ | 1740 | /* make an empty left */ |
| 1701 | left = alloc_arg(); | 1741 | left = alloc_arg(); |
| 1742 | if (!left) | ||
| 1743 | goto out_warn_free; | ||
| 1744 | |||
| 1702 | left->type = PRINT_NULL; | 1745 | left->type = PRINT_NULL; |
| 1703 | arg->op.left = left; | 1746 | arg->op.left = left; |
| 1704 | 1747 | ||
| 1705 | right = alloc_arg(); | 1748 | right = alloc_arg(); |
| 1749 | if (!right) | ||
| 1750 | goto out_warn_free; | ||
| 1751 | |||
| 1706 | arg->op.right = right; | 1752 | arg->op.right = right; |
| 1707 | 1753 | ||
| 1708 | /* do not free the token, it belongs to an op */ | 1754 | /* do not free the token, it belongs to an op */ |
| @@ -1712,6 +1758,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1712 | } else if (strcmp(token, "?") == 0) { | 1758 | } else if (strcmp(token, "?") == 0) { |
| 1713 | 1759 | ||
| 1714 | left = alloc_arg(); | 1760 | left = alloc_arg(); |
| 1761 | if (!left) | ||
| 1762 | goto out_warn_free; | ||
| 1763 | |||
| 1715 | /* copy the top arg to the left */ | 1764 | /* copy the top arg to the left */ |
| 1716 | *left = *arg; | 1765 | *left = *arg; |
| 1717 | 1766 | ||
| @@ -1720,6 +1769,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1720 | arg->op.left = left; | 1769 | arg->op.left = left; |
| 1721 | arg->op.prio = 0; | 1770 | arg->op.prio = 0; |
| 1722 | 1771 | ||
| 1772 | /* it will set arg->op.right */ | ||
| 1723 | type = process_cond(event, arg, tok); | 1773 | type = process_cond(event, arg, tok); |
| 1724 | 1774 | ||
| 1725 | } else if (strcmp(token, ">>") == 0 || | 1775 | } else if (strcmp(token, ">>") == 0 || |
| @@ -1739,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1739 | strcmp(token, "!=") == 0) { | 1789 | strcmp(token, "!=") == 0) { |
| 1740 | 1790 | ||
| 1741 | left = alloc_arg(); | 1791 | left = alloc_arg(); |
| 1792 | if (!left) | ||
| 1793 | goto out_warn_free; | ||
| 1742 | 1794 | ||
| 1743 | /* copy the top arg to the left */ | 1795 | /* copy the top arg to the left */ |
| 1744 | *left = *arg; | 1796 | *left = *arg; |
| @@ -1746,6 +1798,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1746 | arg->type = PRINT_OP; | 1798 | arg->type = PRINT_OP; |
| 1747 | arg->op.op = token; | 1799 | arg->op.op = token; |
| 1748 | arg->op.left = left; | 1800 | arg->op.left = left; |
| 1801 | arg->op.right = NULL; | ||
| 1749 | 1802 | ||
| 1750 | if (set_op_prio(arg) == -1) { | 1803 | if (set_op_prio(arg) == -1) { |
| 1751 | event->flags |= EVENT_FL_FAILED; | 1804 | event->flags |= EVENT_FL_FAILED; |
| @@ -1762,12 +1815,14 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1762 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { | 1815 | type == EVENT_DELIM && (strcmp(token, ")") == 0)) { |
| 1763 | char *new_atom; | 1816 | char *new_atom; |
| 1764 | 1817 | ||
| 1765 | if (left->type != PRINT_ATOM) | 1818 | if (left->type != PRINT_ATOM) { |
| 1766 | die("bad pointer type"); | 1819 | do_warning("bad pointer type"); |
| 1820 | goto out_free; | ||
| 1821 | } | ||
| 1767 | new_atom = realloc(left->atom.atom, | 1822 | new_atom = realloc(left->atom.atom, |
| 1768 | strlen(left->atom.atom) + 3); | 1823 | strlen(left->atom.atom) + 3); |
| 1769 | if (!new_atom) | 1824 | if (!new_atom) |
| 1770 | goto out_free; | 1825 | goto out_warn_free; |
| 1771 | 1826 | ||
| 1772 | left->atom.atom = new_atom; | 1827 | left->atom.atom = new_atom; |
| 1773 | strcat(left->atom.atom, " *"); | 1828 | strcat(left->atom.atom, " *"); |
| @@ -1779,12 +1834,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1779 | } | 1834 | } |
| 1780 | 1835 | ||
| 1781 | right = alloc_arg(); | 1836 | right = alloc_arg(); |
| 1837 | if (!right) | ||
| 1838 | goto out_warn_free; | ||
| 1839 | |||
| 1782 | type = process_arg_token(event, right, tok, type); | 1840 | type = process_arg_token(event, right, tok, type); |
| 1783 | arg->op.right = right; | 1841 | arg->op.right = right; |
| 1784 | 1842 | ||
| 1785 | } else if (strcmp(token, "[") == 0) { | 1843 | } else if (strcmp(token, "[") == 0) { |
| 1786 | 1844 | ||
| 1787 | left = alloc_arg(); | 1845 | left = alloc_arg(); |
| 1846 | if (!left) | ||
| 1847 | goto out_warn_free; | ||
| 1848 | |||
| 1788 | *left = *arg; | 1849 | *left = *arg; |
| 1789 | 1850 | ||
| 1790 | arg->type = PRINT_OP; | 1851 | arg->type = PRINT_OP; |
| @@ -1793,6 +1854,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1793 | 1854 | ||
| 1794 | arg->op.prio = 0; | 1855 | arg->op.prio = 0; |
| 1795 | 1856 | ||
| 1857 | /* it will set arg->op.right */ | ||
| 1796 | type = process_array(event, arg, tok); | 1858 | type = process_array(event, arg, tok); |
| 1797 | 1859 | ||
| 1798 | } else { | 1860 | } else { |
| @@ -1816,14 +1878,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 1816 | 1878 | ||
| 1817 | return type; | 1879 | return type; |
| 1818 | 1880 | ||
| 1819 | out_free: | 1881 | out_warn_free: |
| 1882 | do_warning("%s: not enough memory!", __func__); | ||
| 1883 | out_free: | ||
| 1820 | free_token(token); | 1884 | free_token(token); |
| 1821 | *tok = NULL; | 1885 | *tok = NULL; |
| 1822 | return EVENT_ERROR; | 1886 | return EVENT_ERROR; |
| 1823 | } | 1887 | } |
| 1824 | 1888 | ||
| 1825 | static enum event_type | 1889 | static enum event_type |
| 1826 | process_entry(struct event_format *event __unused, struct print_arg *arg, | 1890 | process_entry(struct event_format *event __maybe_unused, struct print_arg *arg, |
| 1827 | char **tok) | 1891 | char **tok) |
| 1828 | { | 1892 | { |
| 1829 | enum event_type type; | 1893 | enum event_type type; |
| @@ -1880,7 +1944,11 @@ eval_type_str(unsigned long long val, const char *type, int pointer) | |||
| 1880 | return val; | 1944 | return val; |
| 1881 | } | 1945 | } |
| 1882 | 1946 | ||
| 1883 | ref = malloc_or_die(len); | 1947 | ref = malloc(len); |
| 1948 | if (!ref) { | ||
| 1949 | do_warning("%s: not enough memory!", __func__); | ||
| 1950 | return val; | ||
| 1951 | } | ||
| 1884 | memcpy(ref, type, len); | 1952 | memcpy(ref, type, len); |
| 1885 | 1953 | ||
| 1886 | /* chop off the " *" */ | 1954 | /* chop off the " *" */ |
| @@ -1957,8 +2025,10 @@ eval_type_str(unsigned long long val, const char *type, int pointer) | |||
| 1957 | static unsigned long long | 2025 | static unsigned long long |
| 1958 | eval_type(unsigned long long val, struct print_arg *arg, int pointer) | 2026 | eval_type(unsigned long long val, struct print_arg *arg, int pointer) |
| 1959 | { | 2027 | { |
| 1960 | if (arg->type != PRINT_TYPE) | 2028 | if (arg->type != PRINT_TYPE) { |
| 1961 | die("expected type argument"); | 2029 | do_warning("expected type argument"); |
| 2030 | return 0; | ||
| 2031 | } | ||
| 1962 | 2032 | ||
| 1963 | return eval_type_str(val, arg->typecast.type, pointer); | 2033 | return eval_type_str(val, arg->typecast.type, pointer); |
| 1964 | } | 2034 | } |
| @@ -2143,7 +2213,7 @@ static char *arg_eval (struct print_arg *arg) | |||
| 2143 | case PRINT_STRING: | 2213 | case PRINT_STRING: |
| 2144 | case PRINT_BSTRING: | 2214 | case PRINT_BSTRING: |
| 2145 | default: | 2215 | default: |
| 2146 | die("invalid eval type %d", arg->type); | 2216 | do_warning("invalid eval type %d", arg->type); |
| 2147 | break; | 2217 | break; |
| 2148 | } | 2218 | } |
| 2149 | 2219 | ||
| @@ -2166,6 +2236,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
| 2166 | break; | 2236 | break; |
| 2167 | 2237 | ||
| 2168 | arg = alloc_arg(); | 2238 | arg = alloc_arg(); |
| 2239 | if (!arg) | ||
| 2240 | goto out_free; | ||
| 2169 | 2241 | ||
| 2170 | free_token(token); | 2242 | free_token(token); |
| 2171 | type = process_arg(event, arg, &token); | 2243 | type = process_arg(event, arg, &token); |
| @@ -2179,30 +2251,33 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
| 2179 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2251 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
| 2180 | goto out_free; | 2252 | goto out_free; |
| 2181 | 2253 | ||
| 2182 | field = malloc_or_die(sizeof(*field)); | 2254 | field = calloc(1, sizeof(*field)); |
| 2183 | memset(field, 0, sizeof(*field)); | 2255 | if (!field) |
| 2256 | goto out_free; | ||
| 2184 | 2257 | ||
| 2185 | value = arg_eval(arg); | 2258 | value = arg_eval(arg); |
| 2186 | if (value == NULL) | 2259 | if (value == NULL) |
| 2187 | goto out_free; | 2260 | goto out_free_field; |
| 2188 | field->value = strdup(value); | 2261 | field->value = strdup(value); |
| 2189 | if (field->value == NULL) | 2262 | if (field->value == NULL) |
| 2190 | goto out_free; | 2263 | goto out_free_field; |
| 2191 | 2264 | ||
| 2192 | free_arg(arg); | 2265 | free_arg(arg); |
| 2193 | arg = alloc_arg(); | 2266 | arg = alloc_arg(); |
| 2267 | if (!arg) | ||
| 2268 | goto out_free; | ||
| 2194 | 2269 | ||
| 2195 | free_token(token); | 2270 | free_token(token); |
| 2196 | type = process_arg(event, arg, &token); | 2271 | type = process_arg(event, arg, &token); |
| 2197 | if (test_type_token(type, token, EVENT_OP, "}")) | 2272 | if (test_type_token(type, token, EVENT_OP, "}")) |
| 2198 | goto out_free; | 2273 | goto out_free_field; |
| 2199 | 2274 | ||
| 2200 | value = arg_eval(arg); | 2275 | value = arg_eval(arg); |
| 2201 | if (value == NULL) | 2276 | if (value == NULL) |
| 2202 | goto out_free; | 2277 | goto out_free_field; |
| 2203 | field->str = strdup(value); | 2278 | field->str = strdup(value); |
| 2204 | if (field->str == NULL) | 2279 | if (field->str == NULL) |
| 2205 | goto out_free; | 2280 | goto out_free_field; |
| 2206 | free_arg(arg); | 2281 | free_arg(arg); |
| 2207 | arg = NULL; | 2282 | arg = NULL; |
| 2208 | 2283 | ||
| @@ -2216,6 +2291,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
| 2216 | *tok = token; | 2291 | *tok = token; |
| 2217 | return type; | 2292 | return type; |
| 2218 | 2293 | ||
| 2294 | out_free_field: | ||
| 2295 | free_flag_sym(field); | ||
| 2219 | out_free: | 2296 | out_free: |
| 2220 | free_arg(arg); | 2297 | free_arg(arg); |
| 2221 | free_token(token); | 2298 | free_token(token); |
| @@ -2235,6 +2312,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2235 | arg->type = PRINT_FLAGS; | 2312 | arg->type = PRINT_FLAGS; |
| 2236 | 2313 | ||
| 2237 | field = alloc_arg(); | 2314 | field = alloc_arg(); |
| 2315 | if (!field) { | ||
| 2316 | do_warning("%s: not enough memory!", __func__); | ||
| 2317 | goto out_free; | ||
| 2318 | } | ||
| 2238 | 2319 | ||
| 2239 | type = process_arg(event, field, &token); | 2320 | type = process_arg(event, field, &token); |
| 2240 | 2321 | ||
| @@ -2243,7 +2324,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2243 | type = process_op(event, field, &token); | 2324 | type = process_op(event, field, &token); |
| 2244 | 2325 | ||
| 2245 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2326 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
| 2246 | goto out_free; | 2327 | goto out_free_field; |
| 2247 | free_token(token); | 2328 | free_token(token); |
| 2248 | 2329 | ||
| 2249 | arg->flags.field = field; | 2330 | arg->flags.field = field; |
| @@ -2265,7 +2346,9 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2265 | type = read_token_item(tok); | 2346 | type = read_token_item(tok); |
| 2266 | return type; | 2347 | return type; |
| 2267 | 2348 | ||
| 2268 | out_free: | 2349 | out_free_field: |
| 2350 | free_arg(field); | ||
| 2351 | out_free: | ||
| 2269 | free_token(token); | 2352 | free_token(token); |
| 2270 | *tok = NULL; | 2353 | *tok = NULL; |
| 2271 | return EVENT_ERROR; | 2354 | return EVENT_ERROR; |
| @@ -2282,10 +2365,14 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2282 | arg->type = PRINT_SYMBOL; | 2365 | arg->type = PRINT_SYMBOL; |
| 2283 | 2366 | ||
| 2284 | field = alloc_arg(); | 2367 | field = alloc_arg(); |
| 2368 | if (!field) { | ||
| 2369 | do_warning("%s: not enough memory!", __func__); | ||
| 2370 | goto out_free; | ||
| 2371 | } | ||
| 2285 | 2372 | ||
| 2286 | type = process_arg(event, field, &token); | 2373 | type = process_arg(event, field, &token); |
| 2287 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2374 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
| 2288 | goto out_free; | 2375 | goto out_free_field; |
| 2289 | 2376 | ||
| 2290 | arg->symbol.field = field; | 2377 | arg->symbol.field = field; |
| 2291 | 2378 | ||
| @@ -2297,7 +2384,9 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2297 | type = read_token_item(tok); | 2384 | type = read_token_item(tok); |
| 2298 | return type; | 2385 | return type; |
| 2299 | 2386 | ||
| 2300 | out_free: | 2387 | out_free_field: |
| 2388 | free_arg(field); | ||
| 2389 | out_free: | ||
| 2301 | free_token(token); | 2390 | free_token(token); |
| 2302 | *tok = NULL; | 2391 | *tok = NULL; |
| 2303 | return EVENT_ERROR; | 2392 | return EVENT_ERROR; |
| @@ -2314,6 +2403,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2314 | arg->type = PRINT_HEX; | 2403 | arg->type = PRINT_HEX; |
| 2315 | 2404 | ||
| 2316 | field = alloc_arg(); | 2405 | field = alloc_arg(); |
| 2406 | if (!field) { | ||
| 2407 | do_warning("%s: not enough memory!", __func__); | ||
| 2408 | goto out_free; | ||
| 2409 | } | ||
| 2410 | |||
| 2317 | type = process_arg(event, field, &token); | 2411 | type = process_arg(event, field, &token); |
| 2318 | 2412 | ||
| 2319 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2413 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
| @@ -2324,6 +2418,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2324 | free_token(token); | 2418 | free_token(token); |
| 2325 | 2419 | ||
| 2326 | field = alloc_arg(); | 2420 | field = alloc_arg(); |
| 2421 | if (!field) { | ||
| 2422 | do_warning("%s: not enough memory!", __func__); | ||
| 2423 | *tok = NULL; | ||
| 2424 | return EVENT_ERROR; | ||
| 2425 | } | ||
| 2426 | |||
| 2327 | type = process_arg(event, field, &token); | 2427 | type = process_arg(event, field, &token); |
| 2328 | 2428 | ||
| 2329 | if (test_type_token(type, token, EVENT_DELIM, ")")) | 2429 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
| @@ -2381,6 +2481,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** | |||
| 2381 | 2481 | ||
| 2382 | free_token(token); | 2482 | free_token(token); |
| 2383 | arg = alloc_arg(); | 2483 | arg = alloc_arg(); |
| 2484 | if (!field) { | ||
| 2485 | do_warning("%s: not enough memory!", __func__); | ||
| 2486 | *tok = NULL; | ||
| 2487 | return EVENT_ERROR; | ||
| 2488 | } | ||
| 2489 | |||
| 2384 | type = process_arg(event, arg, &token); | 2490 | type = process_arg(event, arg, &token); |
| 2385 | if (type == EVENT_ERROR) | 2491 | if (type == EVENT_ERROR) |
| 2386 | goto out_free_arg; | 2492 | goto out_free_arg; |
| @@ -2434,10 +2540,16 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2434 | /* make this a typecast and contine */ | 2540 | /* make this a typecast and contine */ |
| 2435 | 2541 | ||
| 2436 | /* prevous must be an atom */ | 2542 | /* prevous must be an atom */ |
| 2437 | if (arg->type != PRINT_ATOM) | 2543 | if (arg->type != PRINT_ATOM) { |
| 2438 | die("previous needed to be PRINT_ATOM"); | 2544 | do_warning("previous needed to be PRINT_ATOM"); |
| 2545 | goto out_free; | ||
| 2546 | } | ||
| 2439 | 2547 | ||
| 2440 | item_arg = alloc_arg(); | 2548 | item_arg = alloc_arg(); |
| 2549 | if (!item_arg) { | ||
| 2550 | do_warning("%s: not enough memory!", __func__); | ||
| 2551 | goto out_free; | ||
| 2552 | } | ||
| 2441 | 2553 | ||
| 2442 | arg->type = PRINT_TYPE; | 2554 | arg->type = PRINT_TYPE; |
| 2443 | arg->typecast.type = arg->atom.atom; | 2555 | arg->typecast.type = arg->atom.atom; |
| @@ -2457,7 +2569,8 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) | |||
| 2457 | 2569 | ||
| 2458 | 2570 | ||
| 2459 | static enum event_type | 2571 | static enum event_type |
| 2460 | process_str(struct event_format *event __unused, struct print_arg *arg, char **tok) | 2572 | process_str(struct event_format *event __maybe_unused, struct print_arg *arg, |
| 2573 | char **tok) | ||
| 2461 | { | 2574 | { |
| 2462 | enum event_type type; | 2575 | enum event_type type; |
| 2463 | char *token; | 2576 | char *token; |
| @@ -2532,6 +2645,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler | |||
| 2532 | next_arg = &(arg->func.args); | 2645 | next_arg = &(arg->func.args); |
| 2533 | for (i = 0; i < func->nr_args; i++) { | 2646 | for (i = 0; i < func->nr_args; i++) { |
| 2534 | farg = alloc_arg(); | 2647 | farg = alloc_arg(); |
| 2648 | if (!farg) { | ||
| 2649 | do_warning("%s: not enough memory!", __func__); | ||
| 2650 | return EVENT_ERROR; | ||
| 2651 | } | ||
| 2652 | |||
| 2535 | type = process_arg(event, farg, &token); | 2653 | type = process_arg(event, farg, &token); |
| 2536 | if (i < (func->nr_args - 1)) | 2654 | if (i < (func->nr_args - 1)) |
| 2537 | test = ","; | 2655 | test = ","; |
| @@ -2676,7 +2794,8 @@ process_arg_token(struct event_format *event, struct print_arg *arg, | |||
| 2676 | 2794 | ||
| 2677 | case EVENT_ERROR ... EVENT_NEWLINE: | 2795 | case EVENT_ERROR ... EVENT_NEWLINE: |
| 2678 | default: | 2796 | default: |
| 2679 | die("unexpected type %d", type); | 2797 | do_warning("unexpected type %d", type); |
| 2798 | return EVENT_ERROR; | ||
| 2680 | } | 2799 | } |
| 2681 | *tok = token; | 2800 | *tok = token; |
| 2682 | 2801 | ||
| @@ -2697,6 +2816,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** | |||
| 2697 | } | 2816 | } |
| 2698 | 2817 | ||
| 2699 | arg = alloc_arg(); | 2818 | arg = alloc_arg(); |
| 2819 | if (!arg) { | ||
| 2820 | do_warning("%s: not enough memory!", __func__); | ||
| 2821 | return -1; | ||
| 2822 | } | ||
| 2700 | 2823 | ||
| 2701 | type = process_arg(event, arg, &token); | 2824 | type = process_arg(event, arg, &token); |
| 2702 | 2825 | ||
| @@ -2768,10 +2891,8 @@ static int event_read_print(struct event_format *event) | |||
| 2768 | if (type == EVENT_DQUOTE) { | 2891 | if (type == EVENT_DQUOTE) { |
| 2769 | char *cat; | 2892 | char *cat; |
| 2770 | 2893 | ||
| 2771 | cat = malloc_or_die(strlen(event->print_fmt.format) + | 2894 | if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) |
| 2772 | strlen(token) + 1); | 2895 | goto fail; |
| 2773 | strcpy(cat, event->print_fmt.format); | ||
| 2774 | strcat(cat, token); | ||
| 2775 | free_token(token); | 2896 | free_token(token); |
| 2776 | free_token(event->print_fmt.format); | 2897 | free_token(event->print_fmt.format); |
| 2777 | event->print_fmt.format = NULL; | 2898 | event->print_fmt.format = NULL; |
| @@ -2925,8 +3046,10 @@ static int get_common_info(struct pevent *pevent, | |||
| 2925 | * All events should have the same common elements. | 3046 | * All events should have the same common elements. |
| 2926 | * Pick any event to find where the type is; | 3047 | * Pick any event to find where the type is; |
| 2927 | */ | 3048 | */ |
| 2928 | if (!pevent->events) | 3049 | if (!pevent->events) { |
| 2929 | die("no event_list!"); | 3050 | do_warning("no event_list!"); |
| 3051 | return -1; | ||
| 3052 | } | ||
| 2930 | 3053 | ||
| 2931 | event = pevent->events[0]; | 3054 | event = pevent->events[0]; |
| 2932 | field = pevent_find_common_field(event, type); | 3055 | field = pevent_find_common_field(event, type); |
| @@ -3084,7 +3207,8 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3084 | if (!arg->field.field) { | 3207 | if (!arg->field.field) { |
| 3085 | arg->field.field = pevent_find_any_field(event, arg->field.name); | 3208 | arg->field.field = pevent_find_any_field(event, arg->field.name); |
| 3086 | if (!arg->field.field) | 3209 | if (!arg->field.field) |
| 3087 | die("field %s not found", arg->field.name); | 3210 | goto out_warning_field; |
| 3211 | |||
| 3088 | } | 3212 | } |
| 3089 | /* must be a number */ | 3213 | /* must be a number */ |
| 3090 | val = pevent_read_number(pevent, data + arg->field.field->offset, | 3214 | val = pevent_read_number(pevent, data + arg->field.field->offset, |
| @@ -3145,8 +3269,10 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3145 | if (!larg->field.field) { | 3269 | if (!larg->field.field) { |
| 3146 | larg->field.field = | 3270 | larg->field.field = |
| 3147 | pevent_find_any_field(event, larg->field.name); | 3271 | pevent_find_any_field(event, larg->field.name); |
| 3148 | if (!larg->field.field) | 3272 | if (!larg->field.field) { |
| 3149 | die("field %s not found", larg->field.name); | 3273 | arg = larg; |
| 3274 | goto out_warning_field; | ||
| 3275 | } | ||
| 3150 | } | 3276 | } |
| 3151 | field_size = larg->field.field->elementsize; | 3277 | field_size = larg->field.field->elementsize; |
| 3152 | offset = larg->field.field->offset + | 3278 | offset = larg->field.field->offset + |
| @@ -3182,7 +3308,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3182 | val = left != right; | 3308 | val = left != right; |
| 3183 | break; | 3309 | break; |
| 3184 | default: | 3310 | default: |
| 3185 | die("unknown op '%s'", arg->op.op); | 3311 | goto out_warning_op; |
| 3186 | } | 3312 | } |
| 3187 | break; | 3313 | break; |
| 3188 | case '~': | 3314 | case '~': |
| @@ -3212,7 +3338,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3212 | val = left <= right; | 3338 | val = left <= right; |
| 3213 | break; | 3339 | break; |
| 3214 | default: | 3340 | default: |
| 3215 | die("unknown op '%s'", arg->op.op); | 3341 | goto out_warning_op; |
| 3216 | } | 3342 | } |
| 3217 | break; | 3343 | break; |
| 3218 | case '>': | 3344 | case '>': |
| @@ -3227,12 +3353,13 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3227 | val = left >= right; | 3353 | val = left >= right; |
| 3228 | break; | 3354 | break; |
| 3229 | default: | 3355 | default: |
| 3230 | die("unknown op '%s'", arg->op.op); | 3356 | goto out_warning_op; |
| 3231 | } | 3357 | } |
| 3232 | break; | 3358 | break; |
| 3233 | case '=': | 3359 | case '=': |
| 3234 | if (arg->op.op[1] != '=') | 3360 | if (arg->op.op[1] != '=') |
| 3235 | die("unknown op '%s'", arg->op.op); | 3361 | goto out_warning_op; |
| 3362 | |||
| 3236 | val = left == right; | 3363 | val = left == right; |
| 3237 | break; | 3364 | break; |
| 3238 | case '-': | 3365 | case '-': |
| @@ -3248,13 +3375,21 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg | |||
| 3248 | val = left * right; | 3375 | val = left * right; |
| 3249 | break; | 3376 | break; |
| 3250 | default: | 3377 | default: |
| 3251 | die("unknown op '%s'", arg->op.op); | 3378 | goto out_warning_op; |
| 3252 | } | 3379 | } |
| 3253 | break; | 3380 | break; |
| 3254 | default: /* not sure what to do there */ | 3381 | default: /* not sure what to do there */ |
| 3255 | return 0; | 3382 | return 0; |
| 3256 | } | 3383 | } |
| 3257 | return val; | 3384 | return val; |
| 3385 | |||
| 3386 | out_warning_op: | ||
| 3387 | do_warning("%s: unknown op '%s'", __func__, arg->op.op); | ||
| 3388 | return 0; | ||
| 3389 | |||
| 3390 | out_warning_field: | ||
| 3391 | do_warning("%s: field %s not found", __func__, arg->field.name); | ||
| 3392 | return 0; | ||
| 3258 | } | 3393 | } |
| 3259 | 3394 | ||
| 3260 | struct flag { | 3395 | struct flag { |
| @@ -3331,8 +3466,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3331 | field = arg->field.field; | 3466 | field = arg->field.field; |
| 3332 | if (!field) { | 3467 | if (!field) { |
| 3333 | field = pevent_find_any_field(event, arg->field.name); | 3468 | field = pevent_find_any_field(event, arg->field.name); |
| 3334 | if (!field) | 3469 | if (!field) { |
| 3335 | die("field %s not found", arg->field.name); | 3470 | str = arg->field.name; |
| 3471 | goto out_warning_field; | ||
| 3472 | } | ||
| 3336 | arg->field.field = field; | 3473 | arg->field.field = field; |
| 3337 | } | 3474 | } |
| 3338 | /* Zero sized fields, mean the rest of the data */ | 3475 | /* Zero sized fields, mean the rest of the data */ |
| @@ -3349,7 +3486,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3349 | trace_seq_printf(s, "%lx", addr); | 3486 | trace_seq_printf(s, "%lx", addr); |
| 3350 | break; | 3487 | break; |
| 3351 | } | 3488 | } |
| 3352 | str = malloc_or_die(len + 1); | 3489 | str = malloc(len + 1); |
| 3490 | if (!str) { | ||
| 3491 | do_warning("%s: not enough memory!", __func__); | ||
| 3492 | return; | ||
| 3493 | } | ||
| 3353 | memcpy(str, data + field->offset, len); | 3494 | memcpy(str, data + field->offset, len); |
| 3354 | str[len] = 0; | 3495 | str[len] = 0; |
| 3355 | print_str_to_seq(s, format, len_arg, str); | 3496 | print_str_to_seq(s, format, len_arg, str); |
| @@ -3389,7 +3530,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3389 | str = arg->hex.field->field.name; | 3530 | str = arg->hex.field->field.name; |
| 3390 | field = pevent_find_any_field(event, str); | 3531 | field = pevent_find_any_field(event, str); |
| 3391 | if (!field) | 3532 | if (!field) |
| 3392 | die("field %s not found", str); | 3533 | goto out_warning_field; |
| 3393 | arg->hex.field->field.field = field; | 3534 | arg->hex.field->field.field = field; |
| 3394 | } | 3535 | } |
| 3395 | hex = data + field->offset; | 3536 | hex = data + field->offset; |
| @@ -3441,6 +3582,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, | |||
| 3441 | /* well... */ | 3582 | /* well... */ |
| 3442 | break; | 3583 | break; |
| 3443 | } | 3584 | } |
| 3585 | |||
| 3586 | return; | ||
| 3587 | |||
| 3588 | out_warning_field: | ||
| 3589 | do_warning("%s: field %s not found", __func__, arg->field.name); | ||
| 3444 | } | 3590 | } |
| 3445 | 3591 | ||
| 3446 | static unsigned long long | 3592 | static unsigned long long |
| @@ -3467,7 +3613,11 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
| 3467 | farg = arg->func.args; | 3613 | farg = arg->func.args; |
| 3468 | param = func_handle->params; | 3614 | param = func_handle->params; |
| 3469 | 3615 | ||
| 3470 | args = malloc_or_die(sizeof(*args) * func_handle->nr_args); | 3616 | ret = ULLONG_MAX; |
| 3617 | args = malloc(sizeof(*args) * func_handle->nr_args); | ||
| 3618 | if (!args) | ||
| 3619 | goto out; | ||
| 3620 | |||
| 3471 | for (i = 0; i < func_handle->nr_args; i++) { | 3621 | for (i = 0; i < func_handle->nr_args; i++) { |
| 3472 | switch (param->type) { | 3622 | switch (param->type) { |
| 3473 | case PEVENT_FUNC_ARG_INT: | 3623 | case PEVENT_FUNC_ARG_INT: |
| @@ -3479,13 +3629,19 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
| 3479 | trace_seq_init(&str); | 3629 | trace_seq_init(&str); |
| 3480 | print_str_arg(&str, data, size, event, "%s", -1, farg); | 3630 | print_str_arg(&str, data, size, event, "%s", -1, farg); |
| 3481 | trace_seq_terminate(&str); | 3631 | trace_seq_terminate(&str); |
| 3482 | string = malloc_or_die(sizeof(*string)); | 3632 | string = malloc(sizeof(*string)); |
| 3633 | if (!string) { | ||
| 3634 | do_warning("%s(%d): malloc str", __func__, __LINE__); | ||
| 3635 | goto out_free; | ||
| 3636 | } | ||
| 3483 | string->next = strings; | 3637 | string->next = strings; |
| 3484 | string->str = strdup(str.buffer); | 3638 | string->str = strdup(str.buffer); |
| 3485 | if (!string->str) | 3639 | if (!string->str) { |
| 3486 | die("malloc str"); | 3640 | free(string); |
| 3487 | 3641 | do_warning("%s(%d): malloc str", __func__, __LINE__); | |
| 3488 | args[i] = (unsigned long long)string->str; | 3642 | goto out_free; |
| 3643 | } | ||
| 3644 | args[i] = (uintptr_t)string->str; | ||
| 3489 | strings = string; | 3645 | strings = string; |
| 3490 | trace_seq_destroy(&str); | 3646 | trace_seq_destroy(&str); |
| 3491 | break; | 3647 | break; |
| @@ -3494,14 +3650,15 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
| 3494 | * Something went totally wrong, this is not | 3650 | * Something went totally wrong, this is not |
| 3495 | * an input error, something in this code broke. | 3651 | * an input error, something in this code broke. |
| 3496 | */ | 3652 | */ |
| 3497 | die("Unexpected end of arguments\n"); | 3653 | do_warning("Unexpected end of arguments\n"); |
| 3498 | break; | 3654 | goto out_free; |
| 3499 | } | 3655 | } |
| 3500 | farg = farg->next; | 3656 | farg = farg->next; |
| 3501 | param = param->next; | 3657 | param = param->next; |
| 3502 | } | 3658 | } |
| 3503 | 3659 | ||
| 3504 | ret = (*func_handle->func)(s, args); | 3660 | ret = (*func_handle->func)(s, args); |
| 3661 | out_free: | ||
| 3505 | free(args); | 3662 | free(args); |
| 3506 | while (strings) { | 3663 | while (strings) { |
| 3507 | string = strings; | 3664 | string = strings; |
| @@ -3515,6 +3672,18 @@ process_defined_func(struct trace_seq *s, void *data, int size, | |||
| 3515 | return ret; | 3672 | return ret; |
| 3516 | } | 3673 | } |
| 3517 | 3674 | ||
| 3675 | static void free_args(struct print_arg *args) | ||
| 3676 | { | ||
| 3677 | struct print_arg *next; | ||
| 3678 | |||
| 3679 | while (args) { | ||
| 3680 | next = args->next; | ||
| 3681 | |||
| 3682 | free_arg(args); | ||
| 3683 | args = next; | ||
| 3684 | } | ||
| 3685 | } | ||
| 3686 | |||
| 3518 | static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) | 3687 | static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) |
| 3519 | { | 3688 | { |
| 3520 | struct pevent *pevent = event->pevent; | 3689 | struct pevent *pevent = event->pevent; |
| @@ -3530,11 +3699,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3530 | 3699 | ||
| 3531 | if (!field) { | 3700 | if (!field) { |
| 3532 | field = pevent_find_field(event, "buf"); | 3701 | field = pevent_find_field(event, "buf"); |
| 3533 | if (!field) | 3702 | if (!field) { |
| 3534 | die("can't find buffer field for binary printk"); | 3703 | do_warning("can't find buffer field for binary printk"); |
| 3704 | return NULL; | ||
| 3705 | } | ||
| 3535 | ip_field = pevent_find_field(event, "ip"); | 3706 | ip_field = pevent_find_field(event, "ip"); |
| 3536 | if (!ip_field) | 3707 | if (!ip_field) { |
| 3537 | die("can't find ip field for binary printk"); | 3708 | do_warning("can't find ip field for binary printk"); |
| 3709 | return NULL; | ||
| 3710 | } | ||
| 3538 | pevent->bprint_buf_field = field; | 3711 | pevent->bprint_buf_field = field; |
| 3539 | pevent->bprint_ip_field = ip_field; | 3712 | pevent->bprint_ip_field = ip_field; |
| 3540 | } | 3713 | } |
| @@ -3545,13 +3718,18 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3545 | * The first arg is the IP pointer. | 3718 | * The first arg is the IP pointer. |
| 3546 | */ | 3719 | */ |
| 3547 | args = alloc_arg(); | 3720 | args = alloc_arg(); |
| 3721 | if (!args) { | ||
| 3722 | do_warning("%s(%d): not enough memory!", __func__, __LINE__); | ||
| 3723 | return NULL; | ||
| 3724 | } | ||
| 3548 | arg = args; | 3725 | arg = args; |
| 3549 | arg->next = NULL; | 3726 | arg->next = NULL; |
| 3550 | next = &arg->next; | 3727 | next = &arg->next; |
| 3551 | 3728 | ||
| 3552 | arg->type = PRINT_ATOM; | 3729 | arg->type = PRINT_ATOM; |
| 3553 | arg->atom.atom = malloc_or_die(32); | 3730 | |
| 3554 | sprintf(arg->atom.atom, "%lld", ip); | 3731 | if (asprintf(&arg->atom.atom, "%lld", ip) < 0) |
| 3732 | goto out_free; | ||
| 3555 | 3733 | ||
| 3556 | /* skip the first "%pf : " */ | 3734 | /* skip the first "%pf : " */ |
| 3557 | for (ptr = fmt + 6, bptr = data + field->offset; | 3735 | for (ptr = fmt + 6, bptr = data + field->offset; |
| @@ -3606,10 +3784,17 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3606 | val = pevent_read_number(pevent, bptr, vsize); | 3784 | val = pevent_read_number(pevent, bptr, vsize); |
| 3607 | bptr += vsize; | 3785 | bptr += vsize; |
| 3608 | arg = alloc_arg(); | 3786 | arg = alloc_arg(); |
| 3787 | if (!arg) { | ||
| 3788 | do_warning("%s(%d): not enough memory!", | ||
| 3789 | __func__, __LINE__); | ||
| 3790 | goto out_free; | ||
| 3791 | } | ||
| 3609 | arg->next = NULL; | 3792 | arg->next = NULL; |
| 3610 | arg->type = PRINT_ATOM; | 3793 | arg->type = PRINT_ATOM; |
| 3611 | arg->atom.atom = malloc_or_die(32); | 3794 | if (asprintf(&arg->atom.atom, "%lld", val) < 0) { |
| 3612 | sprintf(arg->atom.atom, "%lld", val); | 3795 | free(arg); |
| 3796 | goto out_free; | ||
| 3797 | } | ||
| 3613 | *next = arg; | 3798 | *next = arg; |
| 3614 | next = &arg->next; | 3799 | next = &arg->next; |
| 3615 | /* | 3800 | /* |
| @@ -3622,11 +3807,16 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3622 | break; | 3807 | break; |
| 3623 | case 's': | 3808 | case 's': |
| 3624 | arg = alloc_arg(); | 3809 | arg = alloc_arg(); |
| 3810 | if (!arg) { | ||
| 3811 | do_warning("%s(%d): not enough memory!", | ||
| 3812 | __func__, __LINE__); | ||
| 3813 | goto out_free; | ||
| 3814 | } | ||
| 3625 | arg->next = NULL; | 3815 | arg->next = NULL; |
| 3626 | arg->type = PRINT_BSTRING; | 3816 | arg->type = PRINT_BSTRING; |
| 3627 | arg->string.string = strdup(bptr); | 3817 | arg->string.string = strdup(bptr); |
| 3628 | if (!arg->string.string) | 3818 | if (!arg->string.string) |
| 3629 | break; | 3819 | goto out_free; |
| 3630 | bptr += strlen(bptr) + 1; | 3820 | bptr += strlen(bptr) + 1; |
| 3631 | *next = arg; | 3821 | *next = arg; |
| 3632 | next = &arg->next; | 3822 | next = &arg->next; |
| @@ -3637,22 +3827,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
| 3637 | } | 3827 | } |
| 3638 | 3828 | ||
| 3639 | return args; | 3829 | return args; |
| 3640 | } | ||
| 3641 | 3830 | ||
| 3642 | static void free_args(struct print_arg *args) | 3831 | out_free: |
| 3643 | { | 3832 | free_args(args); |
| 3644 | struct print_arg *next; | 3833 | return NULL; |
| 3645 | |||
| 3646 | while (args) { | ||
| 3647 | next = args->next; | ||
| 3648 | |||
| 3649 | free_arg(args); | ||
| 3650 | args = next; | ||
| 3651 | } | ||
| 3652 | } | 3834 | } |
| 3653 | 3835 | ||
| 3654 | static char * | 3836 | static char * |
| 3655 | get_bprint_format(void *data, int size __unused, struct event_format *event) | 3837 | get_bprint_format(void *data, int size __maybe_unused, |
| 3838 | struct event_format *event) | ||
| 3656 | { | 3839 | { |
| 3657 | struct pevent *pevent = event->pevent; | 3840 | struct pevent *pevent = event->pevent; |
| 3658 | unsigned long long addr; | 3841 | unsigned long long addr; |
| @@ -3665,8 +3848,10 @@ get_bprint_format(void *data, int size __unused, struct event_format *event) | |||
| 3665 | 3848 | ||
| 3666 | if (!field) { | 3849 | if (!field) { |
| 3667 | field = pevent_find_field(event, "fmt"); | 3850 | field = pevent_find_field(event, "fmt"); |
| 3668 | if (!field) | 3851 | if (!field) { |
| 3669 | die("can't find format field for binary printk"); | 3852 | do_warning("can't find format field for binary printk"); |
| 3853 | return NULL; | ||
| 3854 | } | ||
| 3670 | pevent->bprint_fmt_field = field; | 3855 | pevent->bprint_fmt_field = field; |
| 3671 | } | 3856 | } |
| 3672 | 3857 | ||
| @@ -3674,9 +3859,8 @@ get_bprint_format(void *data, int size __unused, struct event_format *event) | |||
| 3674 | 3859 | ||
| 3675 | printk = find_printk(pevent, addr); | 3860 | printk = find_printk(pevent, addr); |
| 3676 | if (!printk) { | 3861 | if (!printk) { |
| 3677 | format = malloc_or_die(45); | 3862 | if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0) |
| 3678 | sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", | 3863 | return NULL; |
| 3679 | addr); | ||
| 3680 | return format; | 3864 | return format; |
| 3681 | } | 3865 | } |
| 3682 | 3866 | ||
| @@ -3684,8 +3868,8 @@ get_bprint_format(void *data, int size __unused, struct event_format *event) | |||
| 3684 | /* Remove any quotes. */ | 3868 | /* Remove any quotes. */ |
| 3685 | if (*p == '"') | 3869 | if (*p == '"') |
| 3686 | p++; | 3870 | p++; |
| 3687 | format = malloc_or_die(strlen(p) + 10); | 3871 | if (asprintf(&format, "%s : %s", "%pf", p) < 0) |
| 3688 | sprintf(format, "%s : %s", "%pf", p); | 3872 | return NULL; |
| 3689 | /* remove ending quotes and new line since we will add one too */ | 3873 | /* remove ending quotes and new line since we will add one too */ |
| 3690 | p = format + strlen(format) - 1; | 3874 | p = format + strlen(format) - 1; |
| 3691 | if (*p == '"') | 3875 | if (*p == '"') |
| @@ -3720,8 +3904,11 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, | |||
| 3720 | if (!arg->field.field) { | 3904 | if (!arg->field.field) { |
| 3721 | arg->field.field = | 3905 | arg->field.field = |
| 3722 | pevent_find_any_field(event, arg->field.name); | 3906 | pevent_find_any_field(event, arg->field.name); |
| 3723 | if (!arg->field.field) | 3907 | if (!arg->field.field) { |
| 3724 | die("field %s not found", arg->field.name); | 3908 | do_warning("%s: field %s not found", |
| 3909 | __func__, arg->field.name); | ||
| 3910 | return; | ||
| 3911 | } | ||
| 3725 | } | 3912 | } |
| 3726 | if (arg->field.field->size != 6) { | 3913 | if (arg->field.field->size != 6) { |
| 3727 | trace_seq_printf(s, "INVALIDMAC"); | 3914 | trace_seq_printf(s, "INVALIDMAC"); |
| @@ -3888,8 +4075,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3888 | goto cont_process; | 4075 | goto cont_process; |
| 3889 | case '*': | 4076 | case '*': |
| 3890 | /* The argument is the length. */ | 4077 | /* The argument is the length. */ |
| 3891 | if (!arg) | 4078 | if (!arg) { |
| 3892 | die("no argument match"); | 4079 | do_warning("no argument match"); |
| 4080 | event->flags |= EVENT_FL_FAILED; | ||
| 4081 | goto out_failed; | ||
| 4082 | } | ||
| 3893 | len_arg = eval_num_arg(data, size, event, arg); | 4083 | len_arg = eval_num_arg(data, size, event, arg); |
| 3894 | len_as_arg = 1; | 4084 | len_as_arg = 1; |
| 3895 | arg = arg->next; | 4085 | arg = arg->next; |
| @@ -3922,15 +4112,21 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3922 | case 'x': | 4112 | case 'x': |
| 3923 | case 'X': | 4113 | case 'X': |
| 3924 | case 'u': | 4114 | case 'u': |
| 3925 | if (!arg) | 4115 | if (!arg) { |
| 3926 | die("no argument match"); | 4116 | do_warning("no argument match"); |
| 4117 | event->flags |= EVENT_FL_FAILED; | ||
| 4118 | goto out_failed; | ||
| 4119 | } | ||
| 3927 | 4120 | ||
| 3928 | len = ((unsigned long)ptr + 1) - | 4121 | len = ((unsigned long)ptr + 1) - |
| 3929 | (unsigned long)saveptr; | 4122 | (unsigned long)saveptr; |
| 3930 | 4123 | ||
| 3931 | /* should never happen */ | 4124 | /* should never happen */ |
| 3932 | if (len > 31) | 4125 | if (len > 31) { |
| 3933 | die("bad format!"); | 4126 | do_warning("bad format!"); |
| 4127 | event->flags |= EVENT_FL_FAILED; | ||
| 4128 | len = 31; | ||
| 4129 | } | ||
| 3934 | 4130 | ||
| 3935 | memcpy(format, saveptr, len); | 4131 | memcpy(format, saveptr, len); |
| 3936 | format[len] = 0; | 4132 | format[len] = 0; |
| @@ -3994,19 +4190,26 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 3994 | trace_seq_printf(s, format, (long long)val); | 4190 | trace_seq_printf(s, format, (long long)val); |
| 3995 | break; | 4191 | break; |
| 3996 | default: | 4192 | default: |
| 3997 | die("bad count (%d)", ls); | 4193 | do_warning("bad count (%d)", ls); |
| 4194 | event->flags |= EVENT_FL_FAILED; | ||
| 3998 | } | 4195 | } |
| 3999 | break; | 4196 | break; |
| 4000 | case 's': | 4197 | case 's': |
| 4001 | if (!arg) | 4198 | if (!arg) { |
| 4002 | die("no matching argument"); | 4199 | do_warning("no matching argument"); |
| 4200 | event->flags |= EVENT_FL_FAILED; | ||
| 4201 | goto out_failed; | ||
| 4202 | } | ||
| 4003 | 4203 | ||
| 4004 | len = ((unsigned long)ptr + 1) - | 4204 | len = ((unsigned long)ptr + 1) - |
| 4005 | (unsigned long)saveptr; | 4205 | (unsigned long)saveptr; |
| 4006 | 4206 | ||
| 4007 | /* should never happen */ | 4207 | /* should never happen */ |
| 4008 | if (len > 31) | 4208 | if (len > 31) { |
| 4009 | die("bad format!"); | 4209 | do_warning("bad format!"); |
| 4210 | event->flags |= EVENT_FL_FAILED; | ||
| 4211 | len = 31; | ||
| 4212 | } | ||
| 4010 | 4213 | ||
| 4011 | memcpy(format, saveptr, len); | 4214 | memcpy(format, saveptr, len); |
| 4012 | format[len] = 0; | 4215 | format[len] = 0; |
| @@ -4024,6 +4227,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event | |||
| 4024 | trace_seq_putc(s, *ptr); | 4227 | trace_seq_putc(s, *ptr); |
| 4025 | } | 4228 | } |
| 4026 | 4229 | ||
| 4230 | if (event->flags & EVENT_FL_FAILED) { | ||
| 4231 | out_failed: | ||
| 4232 | trace_seq_printf(s, "[FAILED TO PARSE]"); | ||
| 4233 | } | ||
| 4234 | |||
| 4027 | if (args) { | 4235 | if (args) { |
| 4028 | free_args(args); | 4236 | free_args(args); |
| 4029 | free(bprint_fmt); | 4237 | free(bprint_fmt); |
| @@ -4356,7 +4564,10 @@ get_event_fields(const char *type, const char *name, | |||
| 4356 | struct format_field *field; | 4564 | struct format_field *field; |
| 4357 | int i = 0; | 4565 | int i = 0; |
| 4358 | 4566 | ||
| 4359 | fields = malloc_or_die(sizeof(*fields) * (count + 1)); | 4567 | fields = malloc(sizeof(*fields) * (count + 1)); |
| 4568 | if (!fields) | ||
| 4569 | return NULL; | ||
| 4570 | |||
| 4360 | for (field = list; field; field = field->next) { | 4571 | for (field = list; field; field = field->next) { |
| 4361 | fields[i++] = field; | 4572 | fields[i++] = field; |
| 4362 | if (i == count + 1) { | 4573 | if (i == count + 1) { |
| @@ -4672,8 +4883,7 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event) | |||
| 4672 | } | 4883 | } |
| 4673 | 4884 | ||
| 4674 | /** | 4885 | /** |
| 4675 | * pevent_parse_event - parse the event format | 4886 | * __pevent_parse_format - parse the event format |
| 4676 | * @pevent: the handle to the pevent | ||
| 4677 | * @buf: the buffer storing the event format string | 4887 | * @buf: the buffer storing the event format string |
| 4678 | * @size: the size of @buf | 4888 | * @size: the size of @buf |
| 4679 | * @sys: the system the event belongs to | 4889 | * @sys: the system the event belongs to |
| @@ -4685,28 +4895,27 @@ static int find_event_handle(struct pevent *pevent, struct event_format *event) | |||
| 4685 | * | 4895 | * |
| 4686 | * /sys/kernel/debug/tracing/events/.../.../format | 4896 | * /sys/kernel/debug/tracing/events/.../.../format |
| 4687 | */ | 4897 | */ |
| 4688 | int pevent_parse_event(struct pevent *pevent, | 4898 | enum pevent_errno __pevent_parse_format(struct event_format **eventp, |
| 4689 | const char *buf, unsigned long size, | 4899 | struct pevent *pevent, const char *buf, |
| 4690 | const char *sys) | 4900 | unsigned long size, const char *sys) |
| 4691 | { | 4901 | { |
| 4692 | struct event_format *event; | 4902 | struct event_format *event; |
| 4693 | int ret; | 4903 | int ret; |
| 4694 | 4904 | ||
| 4695 | init_input_buf(buf, size); | 4905 | init_input_buf(buf, size); |
| 4696 | 4906 | ||
| 4697 | event = alloc_event(); | 4907 | *eventp = event = alloc_event(); |
| 4698 | if (!event) | 4908 | if (!event) |
| 4699 | return -ENOMEM; | 4909 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; |
| 4700 | 4910 | ||
| 4701 | event->name = event_read_name(); | 4911 | event->name = event_read_name(); |
| 4702 | if (!event->name) { | 4912 | if (!event->name) { |
| 4703 | /* Bad event? */ | 4913 | /* Bad event? */ |
| 4704 | free(event); | 4914 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; |
| 4705 | return -1; | 4915 | goto event_alloc_failed; |
| 4706 | } | 4916 | } |
| 4707 | 4917 | ||
| 4708 | if (strcmp(sys, "ftrace") == 0) { | 4918 | if (strcmp(sys, "ftrace") == 0) { |
| 4709 | |||
| 4710 | event->flags |= EVENT_FL_ISFTRACE; | 4919 | event->flags |= EVENT_FL_ISFTRACE; |
| 4711 | 4920 | ||
| 4712 | if (strcmp(event->name, "bprint") == 0) | 4921 | if (strcmp(event->name, "bprint") == 0) |
| @@ -4714,74 +4923,189 @@ int pevent_parse_event(struct pevent *pevent, | |||
| 4714 | } | 4923 | } |
| 4715 | 4924 | ||
| 4716 | event->id = event_read_id(); | 4925 | event->id = event_read_id(); |
| 4717 | if (event->id < 0) | 4926 | if (event->id < 0) { |
| 4718 | die("failed to read event id"); | 4927 | ret = PEVENT_ERRNO__READ_ID_FAILED; |
| 4928 | /* | ||
| 4929 | * This isn't an allocation error actually. | ||
| 4930 | * But as the ID is critical, just bail out. | ||
| 4931 | */ | ||
| 4932 | goto event_alloc_failed; | ||
| 4933 | } | ||
| 4719 | 4934 | ||
| 4720 | event->system = strdup(sys); | 4935 | event->system = strdup(sys); |
| 4721 | if (!event->system) | 4936 | if (!event->system) { |
| 4722 | die("failed to allocate system"); | 4937 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; |
| 4723 | 4938 | goto event_alloc_failed; | |
| 4724 | /* Add pevent to event so that it can be referenced */ | 4939 | } |
| 4725 | event->pevent = pevent; | ||
| 4726 | 4940 | ||
| 4727 | ret = event_read_format(event); | 4941 | ret = event_read_format(event); |
| 4728 | if (ret < 0) { | 4942 | if (ret < 0) { |
| 4729 | do_warning("failed to read event format for %s", event->name); | 4943 | ret = PEVENT_ERRNO__READ_FORMAT_FAILED; |
| 4730 | goto event_failed; | 4944 | goto event_parse_failed; |
| 4731 | } | 4945 | } |
| 4732 | 4946 | ||
| 4733 | /* | 4947 | /* |
| 4734 | * If the event has an override, don't print warnings if the event | 4948 | * If the event has an override, don't print warnings if the event |
| 4735 | * print format fails to parse. | 4949 | * print format fails to parse. |
| 4736 | */ | 4950 | */ |
| 4737 | if (find_event_handle(pevent, event)) | 4951 | if (pevent && find_event_handle(pevent, event)) |
| 4738 | show_warning = 0; | 4952 | show_warning = 0; |
| 4739 | 4953 | ||
| 4740 | ret = event_read_print(event); | 4954 | ret = event_read_print(event); |
| 4741 | if (ret < 0) { | ||
| 4742 | do_warning("failed to read event print fmt for %s", | ||
| 4743 | event->name); | ||
| 4744 | show_warning = 1; | ||
| 4745 | goto event_failed; | ||
| 4746 | } | ||
| 4747 | show_warning = 1; | 4955 | show_warning = 1; |
| 4748 | 4956 | ||
| 4749 | add_event(pevent, event); | 4957 | if (ret < 0) { |
| 4958 | ret = PEVENT_ERRNO__READ_PRINT_FAILED; | ||
| 4959 | goto event_parse_failed; | ||
| 4960 | } | ||
| 4750 | 4961 | ||
| 4751 | if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { | 4962 | if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { |
| 4752 | struct format_field *field; | 4963 | struct format_field *field; |
| 4753 | struct print_arg *arg, **list; | 4964 | struct print_arg *arg, **list; |
| 4754 | 4965 | ||
| 4755 | /* old ftrace had no args */ | 4966 | /* old ftrace had no args */ |
| 4756 | |||
| 4757 | list = &event->print_fmt.args; | 4967 | list = &event->print_fmt.args; |
| 4758 | for (field = event->format.fields; field; field = field->next) { | 4968 | for (field = event->format.fields; field; field = field->next) { |
| 4759 | arg = alloc_arg(); | 4969 | arg = alloc_arg(); |
| 4760 | *list = arg; | 4970 | if (!arg) { |
| 4761 | list = &arg->next; | 4971 | event->flags |= EVENT_FL_FAILED; |
| 4972 | return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; | ||
| 4973 | } | ||
| 4762 | arg->type = PRINT_FIELD; | 4974 | arg->type = PRINT_FIELD; |
| 4763 | arg->field.name = strdup(field->name); | 4975 | arg->field.name = strdup(field->name); |
| 4764 | if (!arg->field.name) { | 4976 | if (!arg->field.name) { |
| 4765 | do_warning("failed to allocate field name"); | ||
| 4766 | event->flags |= EVENT_FL_FAILED; | 4977 | event->flags |= EVENT_FL_FAILED; |
| 4767 | return -1; | 4978 | free_arg(arg); |
| 4979 | return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; | ||
| 4768 | } | 4980 | } |
| 4769 | arg->field.field = field; | 4981 | arg->field.field = field; |
| 4982 | *list = arg; | ||
| 4983 | list = &arg->next; | ||
| 4770 | } | 4984 | } |
| 4771 | return 0; | 4985 | return 0; |
| 4772 | } | 4986 | } |
| 4773 | 4987 | ||
| 4988 | return 0; | ||
| 4989 | |||
| 4990 | event_parse_failed: | ||
| 4991 | event->flags |= EVENT_FL_FAILED; | ||
| 4992 | return ret; | ||
| 4993 | |||
| 4994 | event_alloc_failed: | ||
| 4995 | free(event->system); | ||
| 4996 | free(event->name); | ||
| 4997 | free(event); | ||
| 4998 | *eventp = NULL; | ||
| 4999 | return ret; | ||
| 5000 | } | ||
| 5001 | |||
| 5002 | /** | ||
| 5003 | * pevent_parse_format - parse the event format | ||
| 5004 | * @buf: the buffer storing the event format string | ||
| 5005 | * @size: the size of @buf | ||
| 5006 | * @sys: the system the event belongs to | ||
| 5007 | * | ||
| 5008 | * This parses the event format and creates an event structure | ||
| 5009 | * to quickly parse raw data for a given event. | ||
| 5010 | * | ||
| 5011 | * These files currently come from: | ||
| 5012 | * | ||
| 5013 | * /sys/kernel/debug/tracing/events/.../.../format | ||
| 5014 | */ | ||
| 5015 | enum pevent_errno pevent_parse_format(struct event_format **eventp, const char *buf, | ||
| 5016 | unsigned long size, const char *sys) | ||
| 5017 | { | ||
| 5018 | return __pevent_parse_format(eventp, NULL, buf, size, sys); | ||
| 5019 | } | ||
| 5020 | |||
| 5021 | /** | ||
| 5022 | * pevent_parse_event - parse the event format | ||
| 5023 | * @pevent: the handle to the pevent | ||
| 5024 | * @buf: the buffer storing the event format string | ||
| 5025 | * @size: the size of @buf | ||
| 5026 | * @sys: the system the event belongs to | ||
| 5027 | * | ||
| 5028 | * This parses the event format and creates an event structure | ||
| 5029 | * to quickly parse raw data for a given event. | ||
| 5030 | * | ||
| 5031 | * These files currently come from: | ||
| 5032 | * | ||
| 5033 | * /sys/kernel/debug/tracing/events/.../.../format | ||
| 5034 | */ | ||
| 5035 | enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, | ||
| 5036 | unsigned long size, const char *sys) | ||
| 5037 | { | ||
| 5038 | struct event_format *event = NULL; | ||
| 5039 | int ret = __pevent_parse_format(&event, pevent, buf, size, sys); | ||
| 5040 | |||
| 5041 | if (event == NULL) | ||
| 5042 | return ret; | ||
| 5043 | |||
| 5044 | /* Add pevent to event so that it can be referenced */ | ||
| 5045 | event->pevent = pevent; | ||
| 5046 | |||
| 5047 | if (add_event(pevent, event)) { | ||
| 5048 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5049 | goto event_add_failed; | ||
| 5050 | } | ||
| 5051 | |||
| 4774 | #define PRINT_ARGS 0 | 5052 | #define PRINT_ARGS 0 |
| 4775 | if (PRINT_ARGS && event->print_fmt.args) | 5053 | if (PRINT_ARGS && event->print_fmt.args) |
| 4776 | print_args(event->print_fmt.args); | 5054 | print_args(event->print_fmt.args); |
| 4777 | 5055 | ||
| 4778 | return 0; | 5056 | return 0; |
| 4779 | 5057 | ||
| 4780 | event_failed: | 5058 | event_add_failed: |
| 4781 | event->flags |= EVENT_FL_FAILED; | 5059 | pevent_free_format(event); |
| 4782 | /* still add it even if it failed */ | 5060 | return ret; |
| 4783 | add_event(pevent, event); | 5061 | } |
| 4784 | return -1; | 5062 | |
| 5063 | #undef _PE | ||
| 5064 | #define _PE(code, str) str | ||
| 5065 | static const char * const pevent_error_str[] = { | ||
| 5066 | PEVENT_ERRORS | ||
| 5067 | }; | ||
| 5068 | #undef _PE | ||
| 5069 | |||
| 5070 | int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, | ||
| 5071 | char *buf, size_t buflen) | ||
| 5072 | { | ||
| 5073 | int idx; | ||
| 5074 | const char *msg; | ||
| 5075 | |||
| 5076 | if (errnum >= 0) { | ||
| 5077 | msg = strerror_r(errnum, buf, buflen); | ||
| 5078 | if (msg != buf) { | ||
| 5079 | size_t len = strlen(msg); | ||
| 5080 | memcpy(buf, msg, min(buflen - 1, len)); | ||
| 5081 | *(buf + min(buflen - 1, len)) = '\0'; | ||
| 5082 | } | ||
| 5083 | return 0; | ||
| 5084 | } | ||
| 5085 | |||
| 5086 | if (errnum <= __PEVENT_ERRNO__START || | ||
| 5087 | errnum >= __PEVENT_ERRNO__END) | ||
| 5088 | return -1; | ||
| 5089 | |||
| 5090 | idx = errnum - __PEVENT_ERRNO__START - 1; | ||
| 5091 | msg = pevent_error_str[idx]; | ||
| 5092 | |||
| 5093 | switch (errnum) { | ||
| 5094 | case PEVENT_ERRNO__MEM_ALLOC_FAILED: | ||
| 5095 | case PEVENT_ERRNO__PARSE_EVENT_FAILED: | ||
| 5096 | case PEVENT_ERRNO__READ_ID_FAILED: | ||
| 5097 | case PEVENT_ERRNO__READ_FORMAT_FAILED: | ||
| 5098 | case PEVENT_ERRNO__READ_PRINT_FAILED: | ||
| 5099 | case PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED: | ||
| 5100 | snprintf(buf, buflen, "%s", msg); | ||
| 5101 | break; | ||
| 5102 | |||
| 5103 | default: | ||
| 5104 | /* cannot reach here */ | ||
| 5105 | break; | ||
| 5106 | } | ||
| 5107 | |||
| 5108 | return 0; | ||
| 4785 | } | 5109 | } |
| 4786 | 5110 | ||
| 4787 | int get_field_val(struct trace_seq *s, struct format_field *field, | 5111 | int get_field_val(struct trace_seq *s, struct format_field *field, |
| @@ -5000,6 +5324,7 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5000 | struct pevent_func_params *param; | 5324 | struct pevent_func_params *param; |
| 5001 | enum pevent_func_arg_type type; | 5325 | enum pevent_func_arg_type type; |
| 5002 | va_list ap; | 5326 | va_list ap; |
| 5327 | int ret; | ||
| 5003 | 5328 | ||
| 5004 | func_handle = find_func_handler(pevent, name); | 5329 | func_handle = find_func_handler(pevent, name); |
| 5005 | if (func_handle) { | 5330 | if (func_handle) { |
| @@ -5012,14 +5337,20 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5012 | remove_func_handler(pevent, name); | 5337 | remove_func_handler(pevent, name); |
| 5013 | } | 5338 | } |
| 5014 | 5339 | ||
| 5015 | func_handle = malloc_or_die(sizeof(*func_handle)); | 5340 | func_handle = calloc(1, sizeof(*func_handle)); |
| 5016 | memset(func_handle, 0, sizeof(*func_handle)); | 5341 | if (!func_handle) { |
| 5342 | do_warning("Failed to allocate function handler"); | ||
| 5343 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5344 | } | ||
| 5017 | 5345 | ||
| 5018 | func_handle->ret_type = ret_type; | 5346 | func_handle->ret_type = ret_type; |
| 5019 | func_handle->name = strdup(name); | 5347 | func_handle->name = strdup(name); |
| 5020 | func_handle->func = func; | 5348 | func_handle->func = func; |
| 5021 | if (!func_handle->name) | 5349 | if (!func_handle->name) { |
| 5022 | die("Failed to allocate function name"); | 5350 | do_warning("Failed to allocate function name"); |
| 5351 | free(func_handle); | ||
| 5352 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5353 | } | ||
| 5023 | 5354 | ||
| 5024 | next_param = &(func_handle->params); | 5355 | next_param = &(func_handle->params); |
| 5025 | va_start(ap, name); | 5356 | va_start(ap, name); |
| @@ -5029,11 +5360,17 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5029 | break; | 5360 | break; |
| 5030 | 5361 | ||
| 5031 | if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { | 5362 | if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { |
| 5032 | warning("Invalid argument type %d", type); | 5363 | do_warning("Invalid argument type %d", type); |
| 5364 | ret = PEVENT_ERRNO__INVALID_ARG_TYPE; | ||
| 5033 | goto out_free; | 5365 | goto out_free; |
| 5034 | } | 5366 | } |
| 5035 | 5367 | ||
| 5036 | param = malloc_or_die(sizeof(*param)); | 5368 | param = malloc(sizeof(*param)); |
| 5369 | if (!param) { | ||
| 5370 | do_warning("Failed to allocate function param"); | ||
| 5371 | ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5372 | goto out_free; | ||
| 5373 | } | ||
| 5037 | param->type = type; | 5374 | param->type = type; |
| 5038 | param->next = NULL; | 5375 | param->next = NULL; |
| 5039 | 5376 | ||
| @@ -5051,7 +5388,7 @@ int pevent_register_print_function(struct pevent *pevent, | |||
| 5051 | out_free: | 5388 | out_free: |
| 5052 | va_end(ap); | 5389 | va_end(ap); |
| 5053 | free_func_handle(func_handle); | 5390 | free_func_handle(func_handle); |
| 5054 | return -1; | 5391 | return ret; |
| 5055 | } | 5392 | } |
| 5056 | 5393 | ||
| 5057 | /** | 5394 | /** |
| @@ -5103,8 +5440,12 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
| 5103 | 5440 | ||
| 5104 | not_found: | 5441 | not_found: |
| 5105 | /* Save for later use. */ | 5442 | /* Save for later use. */ |
| 5106 | handle = malloc_or_die(sizeof(*handle)); | 5443 | handle = calloc(1, sizeof(*handle)); |
| 5107 | memset(handle, 0, sizeof(*handle)); | 5444 | if (!handle) { |
| 5445 | do_warning("Failed to allocate event handler"); | ||
| 5446 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5447 | } | ||
| 5448 | |||
| 5108 | handle->id = id; | 5449 | handle->id = id; |
| 5109 | if (event_name) | 5450 | if (event_name) |
| 5110 | handle->event_name = strdup(event_name); | 5451 | handle->event_name = strdup(event_name); |
| @@ -5113,7 +5454,11 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
| 5113 | 5454 | ||
| 5114 | if ((event_name && !handle->event_name) || | 5455 | if ((event_name && !handle->event_name) || |
| 5115 | (sys_name && !handle->sys_name)) { | 5456 | (sys_name && !handle->sys_name)) { |
| 5116 | die("Failed to allocate event/sys name"); | 5457 | do_warning("Failed to allocate event/sys name"); |
| 5458 | free((void *)handle->event_name); | ||
| 5459 | free((void *)handle->sys_name); | ||
| 5460 | free(handle); | ||
| 5461 | return PEVENT_ERRNO__MEM_ALLOC_FAILED; | ||
| 5117 | } | 5462 | } |
| 5118 | 5463 | ||
| 5119 | handle->func = func; | 5464 | handle->func = func; |
| @@ -5129,13 +5474,10 @@ int pevent_register_event_handler(struct pevent *pevent, | |||
| 5129 | */ | 5474 | */ |
| 5130 | struct pevent *pevent_alloc(void) | 5475 | struct pevent *pevent_alloc(void) |
| 5131 | { | 5476 | { |
| 5132 | struct pevent *pevent; | 5477 | struct pevent *pevent = calloc(1, sizeof(*pevent)); |
| 5133 | 5478 | ||
| 5134 | pevent = malloc(sizeof(*pevent)); | 5479 | if (pevent) |
| 5135 | if (!pevent) | 5480 | pevent->ref_count = 1; |
| 5136 | return NULL; | ||
| 5137 | memset(pevent, 0, sizeof(*pevent)); | ||
| 5138 | pevent->ref_count = 1; | ||
| 5139 | 5481 | ||
| 5140 | return pevent; | 5482 | return pevent; |
| 5141 | } | 5483 | } |
| @@ -5164,7 +5506,7 @@ static void free_formats(struct format *format) | |||
| 5164 | free_format_fields(format->fields); | 5506 | free_format_fields(format->fields); |
| 5165 | } | 5507 | } |
| 5166 | 5508 | ||
| 5167 | static void free_event(struct event_format *event) | 5509 | void pevent_free_format(struct event_format *event) |
| 5168 | { | 5510 | { |
| 5169 | free(event->name); | 5511 | free(event->name); |
| 5170 | free(event->system); | 5512 | free(event->system); |
| @@ -5250,7 +5592,7 @@ void pevent_free(struct pevent *pevent) | |||
| 5250 | } | 5592 | } |
| 5251 | 5593 | ||
| 5252 | for (i = 0; i < pevent->nr_events; i++) | 5594 | for (i = 0; i < pevent->nr_events; i++) |
| 5253 | free_event(pevent->events[i]); | 5595 | pevent_free_format(pevent->events[i]); |
| 5254 | 5596 | ||
| 5255 | while (pevent->handlers) { | 5597 | while (pevent->handlers) { |
| 5256 | handle = pevent->handlers; | 5598 | handle = pevent->handlers; |
