diff options
author | Namhyung Kim <namhyung@kernel.org> | 2012-09-19 22:09:19 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-09-24 11:31:52 -0400 |
commit | b1ac754b67b5a875d63bee880f60ccb0c6bd8899 (patch) | |
tree | b026c7a30a439e5a718e4a37eb48a603a432f0fd | |
parent | 6a6cd11d4e5793ce1a2fb88dc7a09dbf43f9c618 (diff) |
tools lib traceevent: Handle alloc_arg failure
Now alloc_arg returns NULL if memory allocation failed, it should be
handled on callsites properly.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/87k3vpzbqo.fsf_-_@sejong.aot.lge.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/lib/traceevent/event-parse.c | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 1fa71caf295a..17c922145e88 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c | |||
@@ -1565,6 +1565,14 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok) | |||
1565 | left = alloc_arg(); | 1565 | left = alloc_arg(); |
1566 | right = alloc_arg(); | 1566 | right = alloc_arg(); |
1567 | 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 | |||
1568 | arg->type = PRINT_OP; | 1576 | arg->type = PRINT_OP; |
1569 | arg->op.left = left; | 1577 | arg->op.left = left; |
1570 | arg->op.right = right; | 1578 | arg->op.right = right; |
@@ -1607,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) | |||
1607 | char *token = NULL; | 1615 | char *token = NULL; |
1608 | 1616 | ||
1609 | 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 | } | ||
1610 | 1624 | ||
1611 | *tok = NULL; | 1625 | *tok = NULL; |
1612 | type = process_arg(event, arg, &token); | 1626 | type = process_arg(event, arg, &token); |
@@ -1725,10 +1739,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1725 | 1739 | ||
1726 | /* make an empty left */ | 1740 | /* make an empty left */ |
1727 | left = alloc_arg(); | 1741 | left = alloc_arg(); |
1742 | if (!left) | ||
1743 | goto out_warn_free; | ||
1744 | |||
1728 | left->type = PRINT_NULL; | 1745 | left->type = PRINT_NULL; |
1729 | arg->op.left = left; | 1746 | arg->op.left = left; |
1730 | 1747 | ||
1731 | right = alloc_arg(); | 1748 | right = alloc_arg(); |
1749 | if (!right) | ||
1750 | goto out_warn_free; | ||
1751 | |||
1732 | arg->op.right = right; | 1752 | arg->op.right = right; |
1733 | 1753 | ||
1734 | /* do not free the token, it belongs to an op */ | 1754 | /* do not free the token, it belongs to an op */ |
@@ -1738,6 +1758,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1738 | } else if (strcmp(token, "?") == 0) { | 1758 | } else if (strcmp(token, "?") == 0) { |
1739 | 1759 | ||
1740 | left = alloc_arg(); | 1760 | left = alloc_arg(); |
1761 | if (!left) | ||
1762 | goto out_warn_free; | ||
1763 | |||
1741 | /* copy the top arg to the left */ | 1764 | /* copy the top arg to the left */ |
1742 | *left = *arg; | 1765 | *left = *arg; |
1743 | 1766 | ||
@@ -1766,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1766 | strcmp(token, "!=") == 0) { | 1789 | strcmp(token, "!=") == 0) { |
1767 | 1790 | ||
1768 | left = alloc_arg(); | 1791 | left = alloc_arg(); |
1792 | if (!left) | ||
1793 | goto out_warn_free; | ||
1769 | 1794 | ||
1770 | /* copy the top arg to the left */ | 1795 | /* copy the top arg to the left */ |
1771 | *left = *arg; | 1796 | *left = *arg; |
@@ -1797,7 +1822,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1797 | new_atom = realloc(left->atom.atom, | 1822 | new_atom = realloc(left->atom.atom, |
1798 | strlen(left->atom.atom) + 3); | 1823 | strlen(left->atom.atom) + 3); |
1799 | if (!new_atom) | 1824 | if (!new_atom) |
1800 | goto out_free; | 1825 | goto out_warn_free; |
1801 | 1826 | ||
1802 | left->atom.atom = new_atom; | 1827 | left->atom.atom = new_atom; |
1803 | strcat(left->atom.atom, " *"); | 1828 | strcat(left->atom.atom, " *"); |
@@ -1809,12 +1834,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1809 | } | 1834 | } |
1810 | 1835 | ||
1811 | right = alloc_arg(); | 1836 | right = alloc_arg(); |
1837 | if (!right) | ||
1838 | goto out_warn_free; | ||
1839 | |||
1812 | type = process_arg_token(event, right, tok, type); | 1840 | type = process_arg_token(event, right, tok, type); |
1813 | arg->op.right = right; | 1841 | arg->op.right = right; |
1814 | 1842 | ||
1815 | } else if (strcmp(token, "[") == 0) { | 1843 | } else if (strcmp(token, "[") == 0) { |
1816 | 1844 | ||
1817 | left = alloc_arg(); | 1845 | left = alloc_arg(); |
1846 | if (!left) | ||
1847 | goto out_warn_free; | ||
1848 | |||
1818 | *left = *arg; | 1849 | *left = *arg; |
1819 | 1850 | ||
1820 | arg->type = PRINT_OP; | 1851 | arg->type = PRINT_OP; |
@@ -1847,7 +1878,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) | |||
1847 | 1878 | ||
1848 | return type; | 1879 | return type; |
1849 | 1880 | ||
1850 | out_free: | 1881 | out_warn_free: |
1882 | do_warning("%s: not enough memory!", __func__); | ||
1883 | out_free: | ||
1851 | free_token(token); | 1884 | free_token(token); |
1852 | *tok = NULL; | 1885 | *tok = NULL; |
1853 | return EVENT_ERROR; | 1886 | return EVENT_ERROR; |
@@ -2203,6 +2236,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2203 | break; | 2236 | break; |
2204 | 2237 | ||
2205 | arg = alloc_arg(); | 2238 | arg = alloc_arg(); |
2239 | if (!arg) | ||
2240 | goto out_free; | ||
2206 | 2241 | ||
2207 | free_token(token); | 2242 | free_token(token); |
2208 | type = process_arg(event, arg, &token); | 2243 | type = process_arg(event, arg, &token); |
@@ -2229,6 +2264,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** | |||
2229 | 2264 | ||
2230 | free_arg(arg); | 2265 | free_arg(arg); |
2231 | arg = alloc_arg(); | 2266 | arg = alloc_arg(); |
2267 | if (!arg) | ||
2268 | goto out_free; | ||
2232 | 2269 | ||
2233 | free_token(token); | 2270 | free_token(token); |
2234 | type = process_arg(event, arg, &token); | 2271 | type = process_arg(event, arg, &token); |
@@ -2275,6 +2312,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) | |||
2275 | arg->type = PRINT_FLAGS; | 2312 | arg->type = PRINT_FLAGS; |
2276 | 2313 | ||
2277 | field = alloc_arg(); | 2314 | field = alloc_arg(); |
2315 | if (!field) { | ||
2316 | do_warning("%s: not enough memory!", __func__); | ||
2317 | goto out_free; | ||
2318 | } | ||
2278 | 2319 | ||
2279 | type = process_arg(event, field, &token); | 2320 | type = process_arg(event, field, &token); |
2280 | 2321 | ||
@@ -2324,6 +2365,10 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) | |||
2324 | arg->type = PRINT_SYMBOL; | 2365 | arg->type = PRINT_SYMBOL; |
2325 | 2366 | ||
2326 | field = alloc_arg(); | 2367 | field = alloc_arg(); |
2368 | if (!field) { | ||
2369 | do_warning("%s: not enough memory!", __func__); | ||
2370 | goto out_free; | ||
2371 | } | ||
2327 | 2372 | ||
2328 | type = process_arg(event, field, &token); | 2373 | type = process_arg(event, field, &token); |
2329 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2374 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
@@ -2358,6 +2403,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) | |||
2358 | arg->type = PRINT_HEX; | 2403 | arg->type = PRINT_HEX; |
2359 | 2404 | ||
2360 | field = alloc_arg(); | 2405 | field = alloc_arg(); |
2406 | if (!field) { | ||
2407 | do_warning("%s: not enough memory!", __func__); | ||
2408 | goto out_free; | ||
2409 | } | ||
2410 | |||
2361 | type = process_arg(event, field, &token); | 2411 | type = process_arg(event, field, &token); |
2362 | 2412 | ||
2363 | if (test_type_token(type, token, EVENT_DELIM, ",")) | 2413 | if (test_type_token(type, token, EVENT_DELIM, ",")) |
@@ -2368,6 +2418,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) | |||
2368 | free_token(token); | 2418 | free_token(token); |
2369 | 2419 | ||
2370 | 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 | |||
2371 | type = process_arg(event, field, &token); | 2427 | type = process_arg(event, field, &token); |
2372 | 2428 | ||
2373 | if (test_type_token(type, token, EVENT_DELIM, ")")) | 2429 | if (test_type_token(type, token, EVENT_DELIM, ")")) |
@@ -2425,6 +2481,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** | |||
2425 | 2481 | ||
2426 | free_token(token); | 2482 | free_token(token); |
2427 | 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 | |||
2428 | type = process_arg(event, arg, &token); | 2490 | type = process_arg(event, arg, &token); |
2429 | if (type == EVENT_ERROR) | 2491 | if (type == EVENT_ERROR) |
2430 | goto out_free_arg; | 2492 | goto out_free_arg; |
@@ -2484,6 +2546,10 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) | |||
2484 | } | 2546 | } |
2485 | 2547 | ||
2486 | 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 | } | ||
2487 | 2553 | ||
2488 | arg->type = PRINT_TYPE; | 2554 | arg->type = PRINT_TYPE; |
2489 | arg->typecast.type = arg->atom.atom; | 2555 | arg->typecast.type = arg->atom.atom; |
@@ -2579,6 +2645,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler | |||
2579 | next_arg = &(arg->func.args); | 2645 | next_arg = &(arg->func.args); |
2580 | for (i = 0; i < func->nr_args; i++) { | 2646 | for (i = 0; i < func->nr_args; i++) { |
2581 | farg = alloc_arg(); | 2647 | farg = alloc_arg(); |
2648 | if (!farg) { | ||
2649 | do_warning("%s: not enough memory!", __func__); | ||
2650 | return EVENT_ERROR; | ||
2651 | } | ||
2652 | |||
2582 | type = process_arg(event, farg, &token); | 2653 | type = process_arg(event, farg, &token); |
2583 | if (i < (func->nr_args - 1)) | 2654 | if (i < (func->nr_args - 1)) |
2584 | test = ","; | 2655 | test = ","; |
@@ -2745,6 +2816,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** | |||
2745 | } | 2816 | } |
2746 | 2817 | ||
2747 | arg = alloc_arg(); | 2818 | arg = alloc_arg(); |
2819 | if (!arg) { | ||
2820 | do_warning("%s: not enough memory!", __func__); | ||
2821 | return -1; | ||
2822 | } | ||
2748 | 2823 | ||
2749 | type = process_arg(event, arg, &token); | 2824 | type = process_arg(event, arg, &token); |
2750 | 2825 | ||
@@ -3643,6 +3718,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3643 | * The first arg is the IP pointer. | 3718 | * The first arg is the IP pointer. |
3644 | */ | 3719 | */ |
3645 | args = alloc_arg(); | 3720 | args = alloc_arg(); |
3721 | if (!args) { | ||
3722 | do_warning("%s(%d): not enough memory!", __func__, __LINE__); | ||
3723 | return NULL; | ||
3724 | } | ||
3646 | arg = args; | 3725 | arg = args; |
3647 | arg->next = NULL; | 3726 | arg->next = NULL; |
3648 | next = &arg->next; | 3727 | next = &arg->next; |
@@ -3705,6 +3784,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3705 | val = pevent_read_number(pevent, bptr, vsize); | 3784 | val = pevent_read_number(pevent, bptr, vsize); |
3706 | bptr += vsize; | 3785 | bptr += vsize; |
3707 | 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 | } | ||
3708 | arg->next = NULL; | 3792 | arg->next = NULL; |
3709 | arg->type = PRINT_ATOM; | 3793 | arg->type = PRINT_ATOM; |
3710 | if (asprintf(&arg->atom.atom, "%lld", val) < 0) { | 3794 | if (asprintf(&arg->atom.atom, "%lld", val) < 0) { |
@@ -3723,6 +3807,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc | |||
3723 | break; | 3807 | break; |
3724 | case 's': | 3808 | case 's': |
3725 | 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 | } | ||
3726 | arg->next = NULL; | 3815 | arg->next = NULL; |
3727 | arg->type = PRINT_BSTRING; | 3816 | arg->type = PRINT_BSTRING; |
3728 | arg->string.string = strdup(bptr); | 3817 | arg->string.string = strdup(bptr); |
@@ -4878,6 +4967,10 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp, | |||
4878 | list = &event->print_fmt.args; | 4967 | list = &event->print_fmt.args; |
4879 | for (field = event->format.fields; field; field = field->next) { | 4968 | for (field = event->format.fields; field; field = field->next) { |
4880 | arg = alloc_arg(); | 4969 | arg = alloc_arg(); |
4970 | if (!arg) { | ||
4971 | event->flags |= EVENT_FL_FAILED; | ||
4972 | return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; | ||
4973 | } | ||
4881 | arg->type = PRINT_FIELD; | 4974 | arg->type = PRINT_FIELD; |
4882 | arg->field.name = strdup(field->name); | 4975 | arg->field.name = strdup(field->name); |
4883 | if (!arg->field.name) { | 4976 | if (!arg->field.name) { |