* [RFC 0/4] Some libtraceevent cleanups/simplifications
@ 2012-09-17 20:50 Arnaldo Carvalho de Melo
2012-09-17 20:50 ` [PATCH 1/4] tools lib traceevent: Use asprintf were applicable Arnaldo Carvalho de Melo
` (4 more replies)
0 siblings, 5 replies; 14+ messages in thread
From: Arnaldo Carvalho de Melo @ 2012-09-17 20:50 UTC (permalink / raw)
To: Steven Rostedt
Cc: linux-kernel, Arnaldo Carvalho de Melo, David Ahern,
Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Namhyung Kim,
Paul Mackerras, Peter Zijlstra, Stephane Eranian, arnaldo.melo
Hi Steven,
Please take a look, while looking at how to do some stuff in 'perf
test' just for parsing the /format file I ended up with this series, lemme know
if I can add your Acked-by and push via my perf/core branch.
- Arnaldo
Arnaldo Carvalho de Melo (4):
tools lib traceevent: Use asprintf were applicable
tools lib traceevent: Use calloc were applicable
tools lib traceevent: Fix afterlife gotos
tools lib traceevent: Remove some die() calls
tools/lib/traceevent/event-parse.c | 357 ++++++++++++++++++++++--------------
1 file changed, 223 insertions(+), 134 deletions(-)
--
1.7.9.2.358.g22243
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/4] tools lib traceevent: Use asprintf were applicable 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo @ 2012-09-17 20:50 ` Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 2/4] tools lib traceevent: Use calloc " Arnaldo Carvalho de Melo ` (3 subsequent siblings) 4 siblings, 0 replies; 14+ messages in thread From: Arnaldo Carvalho de Melo @ 2012-09-17 20:50 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Arnaldo Carvalho de Melo, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Namhyung Kim, Paul Mackerras, Peter Zijlstra, Stephane Eranian From: Arnaldo Carvalho de Melo <acme@redhat.com> Replacing the equivalent open coded malloc + sprintf bits. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/n/tip-ghokwtdw2hgmmmn7oa9s03r4@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/traceevent/event-parse.c | 58 +++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 77ebeb8..278f989 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -827,9 +827,9 @@ static enum event_type __read_token(char **tok) switch (type) { case EVENT_NEWLINE: case EVENT_DELIM: - *tok = malloc_or_die(2); - (*tok)[0] = ch; - (*tok)[1] = 0; + if (asprintf(tok, "%c", ch) < 0) + return EVENT_ERROR; + return type; case EVENT_OP: @@ -2769,10 +2769,8 @@ static int event_read_print(struct event_format *event) if (type == EVENT_DQUOTE) { char *cat; - cat = malloc_or_die(strlen(event->print_fmt.format) + - strlen(token) + 1); - strcpy(cat, event->print_fmt.format); - strcat(cat, token); + if (asprintf(&cat, "%s%s", event->print_fmt.format, token) < 0) + goto fail; free_token(token); free_token(event->print_fmt.format); event->print_fmt.format = NULL; @@ -3516,6 +3514,18 @@ process_defined_func(struct trace_seq *s, void *data, int size, return ret; } +static void free_args(struct print_arg *args) +{ + struct print_arg *next; + + while (args) { + next = args->next; + + free_arg(args); + args = next; + } +} + static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struct event_format *event) { struct pevent *pevent = event->pevent; @@ -3551,8 +3561,9 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc next = &arg->next; arg->type = PRINT_ATOM; - arg->atom.atom = malloc_or_die(32); - sprintf(arg->atom.atom, "%lld", ip); + + if (asprintf(&arg->atom.atom, "%lld", ip) < 0) + goto out_free; /* skip the first "%pf : " */ for (ptr = fmt + 6, bptr = data + field->offset; @@ -3609,8 +3620,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc arg = alloc_arg(); arg->next = NULL; arg->type = PRINT_ATOM; - arg->atom.atom = malloc_or_die(32); - sprintf(arg->atom.atom, "%lld", val); + if (asprintf(&arg->atom.atom, "%lld", val) < 0) { + free(arg); + goto out_free; + } *next = arg; next = &arg->next; /* @@ -3638,18 +3651,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc } return args; -} - -static void free_args(struct print_arg *args) -{ - struct print_arg *next; - - while (args) { - next = args->next; - free_arg(args); - args = next; - } +out_free: + free_args(args); + return NULL; } static char * @@ -3676,9 +3681,8 @@ get_bprint_format(void *data, int size __maybe_unused, printk = find_printk(pevent, addr); if (!printk) { - format = malloc_or_die(45); - sprintf(format, "%%pf : (NO FORMAT FOUND at %llx)\n", - addr); + if (asprintf(&format, "%%pf : (NO FORMAT FOUND at %llx)\n", addr) < 0) + return NULL; return format; } @@ -3686,8 +3690,8 @@ get_bprint_format(void *data, int size __maybe_unused, /* Remove any quotes. */ if (*p == '"') p++; - format = malloc_or_die(strlen(p) + 10); - sprintf(format, "%s : %s", "%pf", p); + if (asprintf(&format, "%s : %s", "%pf", p) < 0) + return NULL; /* remove ending quotes and new line since we will add one too */ p = format + strlen(format) - 1; if (*p == '"') -- 1.7.9.2.358.g22243 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] tools lib traceevent: Use calloc were applicable 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 1/4] tools lib traceevent: Use asprintf were applicable Arnaldo Carvalho de Melo @ 2012-09-17 20:50 ` Arnaldo Carvalho de Melo 2012-09-19 2:54 ` Namhyung Kim 2012-09-17 20:50 ` [PATCH 3/4] tools lib traceevent: Fix afterlife gotos Arnaldo Carvalho de Melo ` (2 subsequent siblings) 4 siblings, 1 reply; 14+ messages in thread From: Arnaldo Carvalho de Melo @ 2012-09-17 20:50 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Arnaldo Carvalho de Melo, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Namhyung Kim, Paul Mackerras, Peter Zijlstra, Stephane Eranian From: Arnaldo Carvalho de Melo <acme@redhat.com> Replacing the equivalent open coded malloc + memset bits. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/n/tip-598fjtjbzal4wxh7fp0yv0q1@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/traceevent/event-parse.c | 44 ++++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 278f989..5e38d2f 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -117,14 +117,7 @@ void breakpoint(void) struct print_arg *alloc_arg(void) { - struct print_arg *arg; - - arg = malloc_or_die(sizeof(*arg)); - if (!arg) - return NULL; - memset(arg, 0, sizeof(*arg)); - - return arg; + return calloc(1, sizeof(struct print_arg)); } struct cmdline { @@ -619,14 +612,7 @@ void pevent_print_printk(struct pevent *pevent) static struct event_format *alloc_event(void) { - struct event_format *event; - - event = malloc(sizeof(*event)); - if (!event) - return NULL; - memset(event, 0, sizeof(*event)); - - return event; + return calloc(1, sizeof(struct event_format)); } static void add_event(struct pevent *pevent, struct event_format *event) @@ -1240,8 +1226,10 @@ static int event_read_fields(struct event_format *event, struct format_field **f last_token = token; - field = malloc_or_die(sizeof(*field)); - memset(field, 0, sizeof(*field)); + field = calloc(1, sizeof(*field)); + if (!field) + goto fail; + field->event = event; /* read the rest of the type */ @@ -2179,8 +2167,9 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** if (test_type_token(type, token, EVENT_DELIM, ",")) goto out_free; - field = malloc_or_die(sizeof(*field)); - memset(field, 0, sizeof(*field)); + field = calloc(1, sizeof(*field)); + if (!field) + goto out_free; value = arg_eval(arg); if (value == NULL) @@ -5098,12 +5087,11 @@ int pevent_register_print_function(struct pevent *pevent, remove_func_handler(pevent, name); } - func_handle = malloc(sizeof(*func_handle)); + func_handle = calloc(1, sizeof(*func_handle)); if (!func_handle) { do_warning("Failed to allocate function handler"); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } - memset(func_handle, 0, sizeof(*func_handle)); func_handle->ret_type = ret_type; func_handle->name = strdup(name); @@ -5202,13 +5190,12 @@ int pevent_register_event_handler(struct pevent *pevent, not_found: /* Save for later use. */ - handle = malloc(sizeof(*handle)); + handle = calloc(1, sizeof(*handle)); if (!handle) { do_warning("Failed to allocate event handler"); return PEVENT_ERRNO__MEM_ALLOC_FAILED; } - memset(handle, 0, sizeof(*handle)); handle->id = id; if (event_name) handle->event_name = strdup(event_name); @@ -5237,13 +5224,10 @@ int pevent_register_event_handler(struct pevent *pevent, */ struct pevent *pevent_alloc(void) { - struct pevent *pevent; + struct pevent *pevent = calloc(1, sizeof(*pevent)); - pevent = malloc(sizeof(*pevent)); - if (!pevent) - return NULL; - memset(pevent, 0, sizeof(*pevent)); - pevent->ref_count = 1; + if (pevent) + pevent->ref_count = 1; return pevent; } -- 1.7.9.2.358.g22243 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/4] tools lib traceevent: Use calloc were applicable 2012-09-17 20:50 ` [PATCH 2/4] tools lib traceevent: Use calloc " Arnaldo Carvalho de Melo @ 2012-09-19 2:54 ` Namhyung Kim 2012-09-19 6:45 ` [PATCH] tools lib traceevent: Handle alloc_arg failure Namhyung Kim 0 siblings, 1 reply; 14+ messages in thread From: Namhyung Kim @ 2012-09-19 2:54 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Steven Rostedt, linux-kernel, Arnaldo Carvalho de Melo, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Paul Mackerras, Peter Zijlstra, Stephane Eranian On Mon, 17 Sep 2012 17:50:47 -0300, Arnaldo Carvalho de Melo wrote: > From: Arnaldo Carvalho de Melo <acme@redhat.com> > > Replacing the equivalent open coded malloc + memset bits. > > Cc: David Ahern <dsahern@gmail.com> > Cc: Frederic Weisbecker <fweisbec@gmail.com> > Cc: Jiri Olsa <jolsa@redhat.com> > Cc: Mike Galbraith <efault@gmx.de> > Cc: Namhyung Kim <namhyung@gmail.com> > Cc: Paul Mackerras <paulus@samba.org> > Cc: Peter Zijlstra <peterz@infradead.org> > Cc: Stephane Eranian <eranian@google.com> > Cc: Steven Rostedt <rostedt@goodmis.org> > Link: http://lkml.kernel.org/n/tip-598fjtjbzal4wxh7fp0yv0q1@git.kernel.org > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> > --- > tools/lib/traceevent/event-parse.c | 44 ++++++++++++------------------------ > 1 file changed, 14 insertions(+), 30 deletions(-) > > diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c > index 278f989..5e38d2f 100644 > --- a/tools/lib/traceevent/event-parse.c > +++ b/tools/lib/traceevent/event-parse.c > @@ -117,14 +117,7 @@ void breakpoint(void) > > struct print_arg *alloc_arg(void) > { > - struct print_arg *arg; > - > - arg = malloc_or_die(sizeof(*arg)); > - if (!arg) > - return NULL; > - memset(arg, 0, sizeof(*arg)); > - > - return arg; > + return calloc(1, sizeof(struct print_arg)); > } This requires every callsite of the function should handle allocation failure. Thanks, Namhyung ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH] tools lib traceevent: Handle alloc_arg failure 2012-09-19 2:54 ` Namhyung Kim @ 2012-09-19 6:45 ` Namhyung Kim 2012-09-19 11:42 ` Ingo Molnar 0 siblings, 1 reply; 14+ messages in thread From: Namhyung Kim @ 2012-09-19 6:45 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra, Paul Mackerras, Ingo Molnar, LKML, Steven Rostedt, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim From: Namhyung Kim <namhyung.kim@lge.com> Now alloc_arg returns NULL if memory allocation failed, it should be handled on callsites properly. Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- tools/lib/traceevent/event-parse.c | 98 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index e8e0fe0443a4..ee4fa1912542 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) left = alloc_arg(); right = alloc_arg(); + if (!arg || !left || !right) { + do_warning("%s: not enough memory!", __func__); + /* arg will be freed at out_free */ + free_arg(left); + free_arg(right); + goto out_free; + } + arg->type = PRINT_OP; arg->op.left = left; arg->op.right = right; @@ -1607,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) char *token = NULL; arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + /* '*tok' is set to top->op.op. No need to free. */ + *tok = NULL; + return EVENT_ERROR; + } *tok = NULL; type = process_arg(event, arg, &token); @@ -1726,10 +1740,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) /* make an empty left */ left = alloc_arg(); + if (!left) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } left->type = PRINT_NULL; arg->op.left = left; right = alloc_arg(); + if (!right) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } arg->op.right = right; /* do not free the token, it belongs to an op */ @@ -1739,6 +1761,10 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) } else if (strcmp(token, "?") == 0) { left = alloc_arg(); + if (!left) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } /* copy the top arg to the left */ *left = *arg; @@ -1766,6 +1792,10 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) strcmp(token, "!=") == 0) { left = alloc_arg(); + if (!left) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } /* copy the top arg to the left */ *left = *arg; @@ -1808,12 +1838,20 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) } right = alloc_arg(); + if (!right) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } type = process_arg_token(event, right, tok, type); arg->op.right = right; } else if (strcmp(token, "[") == 0) { left = alloc_arg(); + if (!left) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + goto out_free; + } *left = *arg; arg->type = PRINT_OP; @@ -2201,6 +2239,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** break; arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2227,6 +2267,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** free_arg(arg); arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2271,6 +2313,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_FLAGS; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); @@ -2318,6 +2364,10 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_SYMBOL; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2350,6 +2400,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_HEX; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2360,6 +2415,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) free_token(token); field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) @@ -2417,6 +2478,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** free_token(token); arg = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, arg, &token); if (type == EVENT_ERROR) goto out_free_arg; @@ -2476,6 +2543,10 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) } item_arg = alloc_arg(); + if (!item_arg) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } arg->type = PRINT_TYPE; arg->typecast.type = arg->atom.atom; @@ -2571,6 +2642,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler next_arg = &(arg->func.args); for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); + if (!farg) { + do_warning("%s: not enough memory!", __func__); + return EVENT_ERROR; + } + type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) test = ","; @@ -2737,6 +2813,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** } arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + return -1; + } type = process_arg(event, arg, &token); @@ -3635,6 +3715,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc * The first arg is the IP pointer. */ args = alloc_arg(); + if (!args) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + return NULL; + } arg = args; arg->next = NULL; next = &arg->next; @@ -3697,6 +3781,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc val = pevent_read_number(pevent, bptr, vsize); bptr += vsize; arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_ATOM; if (asprintf(&arg->atom.atom, "%lld", val) < 0) { @@ -3715,6 +3804,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc break; case 's': arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_BSTRING; arg->string.string = strdup(bptr); @@ -4876,6 +4970,10 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, list = &event->print_fmt.args; for (field = event->format.fields; field; field = field->next) { arg = alloc_arg(); + if (!arg) { + event->flags |= EVENT_FL_FAILED; + return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; + } arg->type = PRINT_FIELD; arg->field.name = strdup(field->name); if (!arg->field.name) { -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH] tools lib traceevent: Handle alloc_arg failure 2012-09-19 6:45 ` [PATCH] tools lib traceevent: Handle alloc_arg failure Namhyung Kim @ 2012-09-19 11:42 ` Ingo Molnar 2012-09-19 12:26 ` Namhyung Kim 0 siblings, 1 reply; 14+ messages in thread From: Ingo Molnar @ 2012-09-19 11:42 UTC (permalink / raw) To: Namhyung Kim Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras, LKML, Steven Rostedt, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim * Namhyung Kim <namhyung@kernel.org> wrote: > + if (!left) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + if (!right) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + } > + if (!left) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + } > + if (!left) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + } > + if (!right) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + } > + if (!left) { > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > + goto out_free; > + } These repetitive patterns are seriously uglifying the code and are crying out loud for a out_war_free label: if (!left) goto out_warn_free; (The function here seems to be rather large as well, making it a possible candidate for shrinkage/splitup.) Thanks, Ingo ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] tools lib traceevent: Handle alloc_arg failure 2012-09-19 11:42 ` Ingo Molnar @ 2012-09-19 12:26 ` Namhyung Kim 2012-09-19 12:41 ` Steven Rostedt 0 siblings, 1 reply; 14+ messages in thread From: Namhyung Kim @ 2012-09-19 12:26 UTC (permalink / raw) To: Ingo Molnar Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras, LKML, Steven Rostedt, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim Hi Ingo, 2012-09-19 (수), 13:42 +0200, Ingo Molnar: > * Namhyung Kim <namhyung@kernel.org> wrote: > > > + if (!left) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > > + if (!right) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > + } > > > + if (!left) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > + } > > > + if (!left) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > + } > > > + if (!right) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > + } > > > + if (!left) { > > + do_warning("%s(%d): not enough memory!", __func__, __LINE__); > > + goto out_free; > > + } > > These repetitive patterns are seriously uglifying the code and > are crying out loud for a out_war_free label: > > if (!left) > goto out_warn_free; Yeah, I agree. But I wanted to add a bit more helpful (to developers) info - function name and line number - rather than just "not enough memory" message. Maybe we could change do_warning to emit such info automatically. Thanks, Namhyung ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] tools lib traceevent: Handle alloc_arg failure 2012-09-19 12:26 ` Namhyung Kim @ 2012-09-19 12:41 ` Steven Rostedt 2012-09-19 13:30 ` Namhyung Kim 0 siblings, 1 reply; 14+ messages in thread From: Steven Rostedt @ 2012-09-19 12:41 UTC (permalink / raw) To: Namhyung Kim Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras, LKML, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim On Wed, 2012-09-19 at 21:26 +0900, Namhyung Kim wrote: > Hi Ingo, > > Yeah, I agree. But I wanted to add a bit more helpful (to developers) > info - function name and line number - rather than just "not enough > memory" message. Maybe we could change do_warning to emit such info > automatically. But these only fail if you run out of memory for the tool. In that case, I don't think it's that important which allocation failed. -- Steve ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH] tools lib traceevent: Handle alloc_arg failure 2012-09-19 12:41 ` Steven Rostedt @ 2012-09-19 13:30 ` Namhyung Kim 2012-09-20 2:09 ` [PATCH v2] " Namhyung Kim 0 siblings, 1 reply; 14+ messages in thread From: Namhyung Kim @ 2012-09-19 13:30 UTC (permalink / raw) To: Steven Rostedt Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras, LKML, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim Hi Steve, 2012-09-19 (수), 08:41 -0400, Steven Rostedt: > On Wed, 2012-09-19 at 21:26 +0900, Namhyung Kim wrote: > > Yeah, I agree. But I wanted to add a bit more helpful (to developers) > > info - function name and line number - rather than just "not enough > > memory" message. Maybe we could change do_warning to emit such info > > automatically. > > But these only fail if you run out of memory for the tool. In that case, > I don't think it's that important which allocation failed. Okay, I'll send v2 tomorrow according to Ingo's suggestion. Thanks, Namhyung ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2] tools lib traceevent: Handle alloc_arg failure 2012-09-19 13:30 ` Namhyung Kim @ 2012-09-20 2:09 ` Namhyung Kim 2012-09-27 5:47 ` [tip:perf/core] " tip-bot for Namhyung Kim 0 siblings, 1 reply; 14+ messages in thread From: Namhyung Kim @ 2012-09-20 2:09 UTC (permalink / raw) To: Steven Rostedt Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Peter Zijlstra, Paul Mackerras, LKML, David Ahern, Frederic Weisbecker, Jiri Olsa, Stephane Eranian, Mike Galbraith, Namhyung Kim Now alloc_arg returns NULL if memory allocation failed, it should be handled on callsites properly. Signed-off-by: Namhyung Kim <namhyung@kernel.org> --- Hmm.. how about this? Do you want that the __func__ part also gets removed? tools/lib/traceevent/event-parse.c | 97 +++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index e8e0fe0443a4..2e3fc5ec9cc6 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) left = alloc_arg(); right = alloc_arg(); + if (!arg || !left || !right) { + do_warning("%s: not enough memory!", __func__); + /* arg will be freed at out_free */ + free_arg(left); + free_arg(right); + goto out_free; + } + arg->type = PRINT_OP; arg->op.left = left; arg->op.right = right; @@ -1607,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) char *token = NULL; arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + /* '*tok' is set to top->op.op. No need to free. */ + *tok = NULL; + return EVENT_ERROR; + } *tok = NULL; type = process_arg(event, arg, &token); @@ -1726,10 +1740,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) /* make an empty left */ left = alloc_arg(); + if (!left) + goto out_warn_free; + left->type = PRINT_NULL; arg->op.left = left; right = alloc_arg(); + if (!right) + goto out_warn_free; + arg->op.right = right; /* do not free the token, it belongs to an op */ @@ -1739,6 +1759,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) } else if (strcmp(token, "?") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; + /* copy the top arg to the left */ *left = *arg; @@ -1766,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) strcmp(token, "!=") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; /* copy the top arg to the left */ *left = *arg; @@ -1796,7 +1821,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) new_atom = realloc(left->atom.atom, strlen(left->atom.atom) + 3); if (!new_atom) - goto out_free; + goto out_warn_free; left->atom.atom = new_atom; strcat(left->atom.atom, " *"); @@ -1808,12 +1833,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) } right = alloc_arg(); + if (!right) + goto out_warn_free; + type = process_arg_token(event, right, tok, type); arg->op.right = right; } else if (strcmp(token, "[") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; + *left = *arg; arg->type = PRINT_OP; @@ -1845,7 +1876,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) return type; - out_free: +out_warn_free: + do_warning("%s: not enough memory!", __func__); +out_free: free_token(token); *tok = NULL; return EVENT_ERROR; @@ -2201,6 +2234,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** break; arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2227,6 +2262,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** free_arg(arg); arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2271,6 +2308,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_FLAGS; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); @@ -2318,6 +2359,10 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_SYMBOL; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2350,6 +2395,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_HEX; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2360,6 +2410,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) free_token(token); field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) @@ -2417,6 +2473,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** free_token(token); arg = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, arg, &token); if (type == EVENT_ERROR) goto out_free_arg; @@ -2476,6 +2538,10 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) } item_arg = alloc_arg(); + if (!item_arg) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } arg->type = PRINT_TYPE; arg->typecast.type = arg->atom.atom; @@ -2571,6 +2637,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler next_arg = &(arg->func.args); for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); + if (!farg) { + do_warning("%s: not enough memory!", __func__); + return EVENT_ERROR; + } + type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) test = ","; @@ -2737,6 +2808,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** } arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + return -1; + } type = process_arg(event, arg, &token); @@ -3635,6 +3710,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc * The first arg is the IP pointer. */ args = alloc_arg(); + if (!args) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + return NULL; + } arg = args; arg->next = NULL; next = &arg->next; @@ -3697,6 +3776,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc val = pevent_read_number(pevent, bptr, vsize); bptr += vsize; arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_ATOM; if (asprintf(&arg->atom.atom, "%lld", val) < 0) { @@ -3715,6 +3799,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc break; case 's': arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_BSTRING; arg->string.string = strdup(bptr); @@ -4876,6 +4965,10 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, list = &event->print_fmt.args; for (field = event->format.fields; field; field = field->next) { arg = alloc_arg(); + if (!arg) { + event->flags |= EVENT_FL_FAILED; + return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; + } arg->type = PRINT_FIELD; arg->field.name = strdup(field->name); if (!arg->field.name) { -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [tip:perf/core] tools lib traceevent: Handle alloc_arg failure 2012-09-20 2:09 ` [PATCH v2] " Namhyung Kim @ 2012-09-27 5:47 ` tip-bot for Namhyung Kim 0 siblings, 0 replies; 14+ messages in thread From: tip-bot for Namhyung Kim @ 2012-09-27 5:47 UTC (permalink / raw) To: linux-tip-commits Cc: acme, linux-kernel, eranian, paulus, hpa, mingo, a.p.zijlstra, efault, namhyung.kim, namhyung, jolsa, fweisbec, rostedt, dsahern, tglx Commit-ID: b1ac754b67b5a875d63bee880f60ccb0c6bd8899 Gitweb: http://git.kernel.org/tip/b1ac754b67b5a875d63bee880f60ccb0c6bd8899 Author: Namhyung Kim <namhyung@kernel.org> AuthorDate: Thu, 20 Sep 2012 11:09:19 +0900 Committer: Arnaldo Carvalho de Melo <acme@redhat.com> CommitDate: Mon, 24 Sep 2012 12:31:52 -0300 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> --- 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 1fa71ca..17c9221 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) left = alloc_arg(); right = alloc_arg(); + if (!arg || !left || !right) { + do_warning("%s: not enough memory!", __func__); + /* arg will be freed at out_free */ + free_arg(left); + free_arg(right); + goto out_free; + } + arg->type = PRINT_OP; arg->op.left = left; arg->op.right = right; @@ -1607,6 +1615,12 @@ process_array(struct event_format *event, struct print_arg *top, char **tok) char *token = NULL; arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + /* '*tok' is set to top->op.op. No need to free. */ + *tok = NULL; + return EVENT_ERROR; + } *tok = NULL; type = process_arg(event, arg, &token); @@ -1725,10 +1739,16 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) /* make an empty left */ left = alloc_arg(); + if (!left) + goto out_warn_free; + left->type = PRINT_NULL; arg->op.left = left; right = alloc_arg(); + if (!right) + goto out_warn_free; + arg->op.right = right; /* 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) } else if (strcmp(token, "?") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; + /* copy the top arg to the left */ *left = *arg; @@ -1766,6 +1789,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) strcmp(token, "!=") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; /* copy the top arg to the left */ *left = *arg; @@ -1797,7 +1822,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) new_atom = realloc(left->atom.atom, strlen(left->atom.atom) + 3); if (!new_atom) - goto out_free; + goto out_warn_free; left->atom.atom = new_atom; strcat(left->atom.atom, " *"); @@ -1809,12 +1834,18 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) } right = alloc_arg(); + if (!right) + goto out_warn_free; + type = process_arg_token(event, right, tok, type); arg->op.right = right; } else if (strcmp(token, "[") == 0) { left = alloc_arg(); + if (!left) + goto out_warn_free; + *left = *arg; arg->type = PRINT_OP; @@ -1847,7 +1878,9 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) return type; - out_free: +out_warn_free: + do_warning("%s: not enough memory!", __func__); +out_free: free_token(token); *tok = NULL; return EVENT_ERROR; @@ -2203,6 +2236,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** break; arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2229,6 +2264,8 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char ** free_arg(arg); arg = alloc_arg(); + if (!arg) + goto out_free; free_token(token); type = process_arg(event, arg, &token); @@ -2275,6 +2312,10 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_FLAGS; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); @@ -2324,6 +2365,10 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_SYMBOL; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2358,6 +2403,11 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) arg->type = PRINT_HEX; field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ",")) @@ -2368,6 +2418,12 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok) free_token(token); field = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, field, &token); if (test_type_token(type, token, EVENT_DELIM, ")")) @@ -2425,6 +2481,12 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char ** free_token(token); arg = alloc_arg(); + if (!field) { + do_warning("%s: not enough memory!", __func__); + *tok = NULL; + return EVENT_ERROR; + } + type = process_arg(event, arg, &token); if (type == EVENT_ERROR) goto out_free_arg; @@ -2484,6 +2546,10 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) } item_arg = alloc_arg(); + if (!item_arg) { + do_warning("%s: not enough memory!", __func__); + goto out_free; + } arg->type = PRINT_TYPE; arg->typecast.type = arg->atom.atom; @@ -2579,6 +2645,11 @@ process_func_handler(struct event_format *event, struct pevent_function_handler next_arg = &(arg->func.args); for (i = 0; i < func->nr_args; i++) { farg = alloc_arg(); + if (!farg) { + do_warning("%s: not enough memory!", __func__); + return EVENT_ERROR; + } + type = process_arg(event, farg, &token); if (i < (func->nr_args - 1)) test = ","; @@ -2745,6 +2816,10 @@ static int event_read_print_args(struct event_format *event, struct print_arg ** } arg = alloc_arg(); + if (!arg) { + do_warning("%s: not enough memory!", __func__); + return -1; + } type = process_arg(event, arg, &token); @@ -3643,6 +3718,10 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc * The first arg is the IP pointer. */ args = alloc_arg(); + if (!args) { + do_warning("%s(%d): not enough memory!", __func__, __LINE__); + return NULL; + } arg = args; arg->next = NULL; next = &arg->next; @@ -3705,6 +3784,11 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc val = pevent_read_number(pevent, bptr, vsize); bptr += vsize; arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_ATOM; 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 break; case 's': arg = alloc_arg(); + if (!arg) { + do_warning("%s(%d): not enough memory!", + __func__, __LINE__); + goto out_free; + } arg->next = NULL; arg->type = PRINT_BSTRING; arg->string.string = strdup(bptr); @@ -4878,6 +4967,10 @@ enum pevent_errno __pevent_parse_format(struct event_format **eventp, list = &event->print_fmt.args; for (field = event->format.fields; field; field = field->next) { arg = alloc_arg(); + if (!arg) { + event->flags |= EVENT_FL_FAILED; + return PEVENT_ERRNO__OLD_FTRACE_ARG_FAILED; + } arg->type = PRINT_FIELD; arg->field.name = strdup(field->name); if (!arg->field.name) { ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 3/4] tools lib traceevent: Fix afterlife gotos 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 1/4] tools lib traceevent: Use asprintf were applicable Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 2/4] tools lib traceevent: Use calloc " Arnaldo Carvalho de Melo @ 2012-09-17 20:50 ` Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 4/4] tools lib traceevent: Remove some die() calls Arnaldo Carvalho de Melo 2012-09-19 6:48 ` [RFC 0/4] Some libtraceevent cleanups/simplifications Namhyung Kim 4 siblings, 0 replies; 14+ messages in thread From: Arnaldo Carvalho de Melo @ 2012-09-17 20:50 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Arnaldo Carvalho de Melo, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Namhyung Kim, Paul Mackerras, Peter Zijlstra, Stephane Eranian From: Arnaldo Carvalho de Melo <acme@redhat.com> Instead of dying, just use do_warning and let the goto that is there to take place. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/n/tip-aoaus46ngnt9oc2pt7ckot5d@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/traceevent/event-parse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 5e38d2f..ecc9a17 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -1270,7 +1270,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f } if (!field->type) { - die("no type found"); + do_warning("%s: no type found", __func__); goto fail; } field->name = last_token; @@ -1317,7 +1317,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f free_token(token); type = read_token(&token); if (type == EVENT_NONE) { - die("failed to find token"); + do_warning("failed to find token"); goto fail; } } @@ -1670,7 +1670,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) if (arg->type == PRINT_OP && !arg->op.left) { /* handle single op */ if (token[1]) { - die("bad op token %s", token); + do_warning("bad op token %s", token); goto out_free; } switch (token[0]) { -- 1.7.9.2.358.g22243 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 4/4] tools lib traceevent: Remove some die() calls 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo ` (2 preceding siblings ...) 2012-09-17 20:50 ` [PATCH 3/4] tools lib traceevent: Fix afterlife gotos Arnaldo Carvalho de Melo @ 2012-09-17 20:50 ` Arnaldo Carvalho de Melo 2012-09-19 6:48 ` [RFC 0/4] Some libtraceevent cleanups/simplifications Namhyung Kim 4 siblings, 0 replies; 14+ messages in thread From: Arnaldo Carvalho de Melo @ 2012-09-17 20:50 UTC (permalink / raw) To: Steven Rostedt Cc: linux-kernel, Arnaldo Carvalho de Melo, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Namhyung Kim, Paul Mackerras, Peter Zijlstra, Stephane Eranian From: Arnaldo Carvalho de Melo <acme@redhat.com> Cleaned event-parse.c this time, just propagate the errors and in handle them the call sites. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-9ebpr2vgfk2qs2841i99sa8y@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> --- tools/lib/traceevent/event-parse.c | 249 +++++++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 74 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index ecc9a17..e8e0fe0 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -31,6 +31,7 @@ #include <ctype.h> #include <errno.h> #include <stdint.h> +#include <limits.h> #include "event-parse.h" #include "event-utils.h" @@ -151,7 +152,9 @@ static int cmdline_init(struct pevent *pevent) struct cmdline *cmdlines; int i; - cmdlines = malloc_or_die(sizeof(*cmdlines) * pevent->cmdline_count); + cmdlines = malloc(sizeof(*cmdlines) * pevent->cmdline_count); + if (!cmdlines) + return -1; i = 0; while (cmdlist) { @@ -179,8 +182,8 @@ static char *find_cmdline(struct pevent *pevent, int pid) if (!pid) return "<idle>"; - if (!pevent->cmdlines) - cmdline_init(pevent); + if (!pevent->cmdlines && cmdline_init(pevent)) + return "<not enough memory for cmdlines!>"; key.pid = pid; @@ -208,8 +211,8 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid) if (!pid) return 1; - if (!pevent->cmdlines) - cmdline_init(pevent); + if (!pevent->cmdlines && cmdline_init(pevent)) + return 0; key.pid = pid; @@ -251,10 +254,14 @@ static int add_new_comm(struct pevent *pevent, const char *comm, int pid) return -1; } - cmdlines[pevent->cmdline_count].pid = pid; cmdlines[pevent->cmdline_count].comm = strdup(comm); - if (!cmdlines[pevent->cmdline_count].comm) - die("malloc comm"); + if (!cmdlines[pevent->cmdline_count].comm) { + free(cmdlines); + errno = ENOMEM; + return -1; + } + + cmdlines[pevent->cmdline_count].pid = pid; if (cmdlines[pevent->cmdline_count].comm) pevent->cmdline_count++; @@ -281,10 +288,15 @@ int pevent_register_comm(struct pevent *pevent, const char *comm, int pid) if (pevent->cmdlines) return add_new_comm(pevent, comm, pid); - item = malloc_or_die(sizeof(*item)); + item = malloc(sizeof(*item)); + if (!item) + return -1; + item->comm = strdup(comm); - if (!item->comm) - die("malloc comm"); + if (!item->comm) { + free(item); + return -1; + } item->pid = pid; item->next = pevent->cmdlist; @@ -348,7 +360,10 @@ static int func_map_init(struct pevent *pevent) struct func_map *func_map; int i; - func_map = malloc_or_die(sizeof(*func_map) * (pevent->func_count + 1)); + func_map = malloc(sizeof(*func_map) * (pevent->func_count + 1)); + if (!func_map) + return -1; + funclist = pevent->funclist; i = 0; @@ -448,25 +463,36 @@ pevent_find_function_address(struct pevent *pevent, unsigned long long addr) int pevent_register_function(struct pevent *pevent, char *func, unsigned long long addr, char *mod) { - struct func_list *item; + struct func_list *item = malloc(sizeof(*item)); - item = malloc_or_die(sizeof(*item)); + if (!item) + return -1; item->next = pevent->funclist; item->func = strdup(func); - if (mod) + if (!item->func) + goto out_free; + + if (mod) { item->mod = strdup(mod); - else + if (!item->mod) + goto out_free_func; + } else item->mod = NULL; item->addr = addr; - if (!item->func || (mod && !item->mod)) - die("malloc func"); - pevent->funclist = item; pevent->func_count++; return 0; + +out_free_func: + free(item->func); + item->func = NULL; +out_free: + free(item); + errno = ENOMEM; + return -1; } /** @@ -517,14 +543,16 @@ static int printk_cmp(const void *a, const void *b) return 0; } -static void printk_map_init(struct pevent *pevent) +static int printk_map_init(struct pevent *pevent) { struct printk_list *printklist; struct printk_list *item; struct printk_map *printk_map; int i; - printk_map = malloc_or_die(sizeof(*printk_map) * (pevent->printk_count + 1)); + printk_map = malloc(sizeof(*printk_map) * (pevent->printk_count + 1)); + if (!printk_map) + return -1; printklist = pevent->printklist; @@ -542,6 +570,8 @@ static void printk_map_init(struct pevent *pevent) pevent->printk_map = printk_map; pevent->printklist = NULL; + + return 0; } static struct printk_map * @@ -550,8 +580,8 @@ find_printk(struct pevent *pevent, unsigned long long addr) struct printk_map *printk; struct printk_map key; - if (!pevent->printk_map) - printk_map_init(pevent); + if (!pevent->printk_map && printk_map_init(pevent)) + return NULL; key.addr = addr; @@ -573,21 +603,27 @@ find_printk(struct pevent *pevent, unsigned long long addr) int pevent_register_print_string(struct pevent *pevent, char *fmt, unsigned long long addr) { - struct printk_list *item; + struct printk_list *item = malloc(sizeof(*item)); - item = malloc_or_die(sizeof(*item)); + if (!item) + return -1; item->next = pevent->printklist; - item->printk = strdup(fmt); item->addr = addr; + item->printk = strdup(fmt); if (!item->printk) - die("malloc fmt"); + goto out_free; pevent->printklist = item; pevent->printk_count++; return 0; + +out_free: + free(item); + errno = ENOMEM; + return -1; } /** @@ -615,14 +651,15 @@ static struct event_format *alloc_event(void) return calloc(1, sizeof(struct event_format)); } -static void add_event(struct pevent *pevent, struct event_format *event) +static int add_event(struct pevent *pevent, struct event_format *event) { int i; + struct event_format **events = realloc(pevent->events, sizeof(event) * + (pevent->nr_events + 1)); + if (!events) + return -1; - pevent->events = realloc(pevent->events, sizeof(event) * - (pevent->nr_events + 1)); - if (!pevent->events) - die("Can not allocate events"); + pevent->events = events; for (i = 0; i < pevent->nr_events; i++) { if (pevent->events[i]->id > event->id) @@ -637,6 +674,8 @@ static void add_event(struct pevent *pevent, struct event_format *event) pevent->nr_events++; event->pevent = pevent; + + return 0; } static int event_item_type(enum event_type type) @@ -1750,8 +1789,10 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok) type == EVENT_DELIM && (strcmp(token, ")") == 0)) { char *new_atom; - if (left->type != PRINT_ATOM) - die("bad pointer type"); + if (left->type != PRINT_ATOM) { + do_warning("bad pointer type"); + goto out_free; + } new_atom = realloc(left->atom.atom, strlen(left->atom.atom) + 3); if (!new_atom) @@ -1868,7 +1909,11 @@ eval_type_str(unsigned long long val, const char *type, int pointer) return val; } - ref = malloc_or_die(len); + ref = malloc(len); + if (!ref) { + do_warning("%s: not enough memory!", __func__); + return val; + } memcpy(ref, type, len); /* chop off the " *" */ @@ -1945,8 +1990,10 @@ eval_type_str(unsigned long long val, const char *type, int pointer) static unsigned long long eval_type(unsigned long long val, struct print_arg *arg, int pointer) { - if (arg->type != PRINT_TYPE) - die("expected type argument"); + if (arg->type != PRINT_TYPE) { + do_warning("expected type argument"); + return 0; + } return eval_type_str(val, arg->typecast.type, pointer); } @@ -2131,7 +2178,7 @@ static char *arg_eval (struct print_arg *arg) case PRINT_STRING: case PRINT_BSTRING: default: - die("invalid eval type %d", arg->type); + do_warning("invalid eval type %d", arg->type); break; } @@ -2423,8 +2470,10 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok) /* make this a typecast and contine */ /* prevous must be an atom */ - if (arg->type != PRINT_ATOM) - die("previous needed to be PRINT_ATOM"); + if (arg->type != PRINT_ATOM) { + do_warning("previous needed to be PRINT_ATOM"); + goto out_free; + } item_arg = alloc_arg(); @@ -2666,7 +2715,8 @@ process_arg_token(struct event_format *event, struct print_arg *arg, case EVENT_ERROR ... EVENT_NEWLINE: default: - die("unexpected type %d", type); + do_warning("unexpected type %d", type); + return EVENT_ERROR; } *tok = token; @@ -2913,8 +2963,10 @@ static int get_common_info(struct pevent *pevent, * All events should have the same common elements. * Pick any event to find where the type is; */ - if (!pevent->events) - die("no event_list!"); + if (!pevent->events) { + do_warning("no event_list!"); + return -1; + } event = pevent->events[0]; field = pevent_find_common_field(event, type); @@ -3072,7 +3124,8 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg if (!arg->field.field) { arg->field.field = pevent_find_any_field(event, arg->field.name); if (!arg->field.field) - die("field %s not found", arg->field.name); + goto out_warning_field; + } /* must be a number */ val = pevent_read_number(pevent, data + arg->field.field->offset, @@ -3133,8 +3186,10 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg if (!larg->field.field) { larg->field.field = pevent_find_any_field(event, larg->field.name); - if (!larg->field.field) - die("field %s not found", larg->field.name); + if (!larg->field.field) { + arg = larg; + goto out_warning_field; + } } field_size = larg->field.field->elementsize; offset = larg->field.field->offset + @@ -3170,7 +3225,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg val = left != right; break; default: - die("unknown op '%s'", arg->op.op); + goto out_warning_op; } break; case '~': @@ -3200,7 +3255,7 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg val = left <= right; break; default: - die("unknown op '%s'", arg->op.op); + goto out_warning_op; } break; case '>': @@ -3215,12 +3270,13 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg val = left >= right; break; default: - die("unknown op '%s'", arg->op.op); + goto out_warning_op; } break; case '=': if (arg->op.op[1] != '=') - die("unknown op '%s'", arg->op.op); + goto out_warning_op; + val = left == right; break; case '-': @@ -3236,13 +3292,21 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg val = left * right; break; default: - die("unknown op '%s'", arg->op.op); + goto out_warning_op; } break; default: /* not sure what to do there */ return 0; } return val; + +out_warning_op: + do_warning("%s: unknown op '%s'", __func__, arg->op.op); + return 0; + +out_warning_field: + do_warning("%s: field %s not found", __func__, arg->field.name); + return 0; } struct flag { @@ -3319,8 +3383,10 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, field = arg->field.field; if (!field) { field = pevent_find_any_field(event, arg->field.name); - if (!field) - die("field %s not found", arg->field.name); + if (!field) { + str = arg->field.name; + goto out_warning_field; + } arg->field.field = field; } /* Zero sized fields, mean the rest of the data */ @@ -3337,7 +3403,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, trace_seq_printf(s, "%lx", addr); break; } - str = malloc_or_die(len + 1); + str = malloc(len + 1); + if (!str) { + do_warning("%s: not enough memory!", __func__); + return; + } memcpy(str, data + field->offset, len); str[len] = 0; print_str_to_seq(s, format, len_arg, str); @@ -3377,7 +3447,7 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, str = arg->hex.field->field.name; field = pevent_find_any_field(event, str); if (!field) - die("field %s not found", str); + goto out_warning_field; arg->hex.field->field.field = field; } hex = data + field->offset; @@ -3429,6 +3499,11 @@ static void print_str_arg(struct trace_seq *s, void *data, int size, /* well... */ break; } + + return; + +out_warning_field: + do_warning("%s: field %s not found", __func__, arg->field.name); } static unsigned long long @@ -3455,7 +3530,11 @@ process_defined_func(struct trace_seq *s, void *data, int size, farg = arg->func.args; param = func_handle->params; - args = malloc_or_die(sizeof(*args) * func_handle->nr_args); + ret = ULLONG_MAX; + args = malloc(sizeof(*args) * func_handle->nr_args); + if (!args) + goto out; + for (i = 0; i < func_handle->nr_args; i++) { switch (param->type) { case PEVENT_FUNC_ARG_INT: @@ -3467,12 +3546,18 @@ process_defined_func(struct trace_seq *s, void *data, int size, trace_seq_init(&str); print_str_arg(&str, data, size, event, "%s", -1, farg); trace_seq_terminate(&str); - string = malloc_or_die(sizeof(*string)); + string = malloc(sizeof(*string)); + if (!string) { + do_warning("%s(%d): malloc str", __func__, __LINE__); + goto out_free; + } string->next = strings; string->str = strdup(str.buffer); - if (!string->str) - die("malloc str"); - + if (!string->str) { + free(string); + do_warning("%s(%d): malloc str", __func__, __LINE__); + goto out_free; + } args[i] = (uintptr_t)string->str; strings = string; trace_seq_destroy(&str); @@ -3482,14 +3567,15 @@ process_defined_func(struct trace_seq *s, void *data, int size, * Something went totally wrong, this is not * an input error, something in this code broke. */ - die("Unexpected end of arguments\n"); - break; + do_warning("Unexpected end of arguments\n"); + goto out_free; } farg = farg->next; param = param->next; } ret = (*func_handle->func)(s, args); +out_free: free(args); while (strings) { string = strings; @@ -3530,11 +3616,15 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc if (!field) { field = pevent_find_field(event, "buf"); - if (!field) - die("can't find buffer field for binary printk"); + if (!field) { + do_warning("can't find buffer field for binary printk"); + return NULL; + } ip_field = pevent_find_field(event, "ip"); - if (!ip_field) - die("can't find ip field for binary printk"); + if (!ip_field) { + do_warning("can't find ip field for binary printk"); + return NULL; + } pevent->bprint_buf_field = field; pevent->bprint_ip_field = ip_field; } @@ -3629,7 +3719,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc arg->type = PRINT_BSTRING; arg->string.string = strdup(bptr); if (!arg->string.string) - break; + goto out_free; bptr += strlen(bptr) + 1; *next = arg; next = &arg->next; @@ -3661,8 +3751,10 @@ get_bprint_format(void *data, int size __maybe_unused, if (!field) { field = pevent_find_field(event, "fmt"); - if (!field) - die("can't find format field for binary printk"); + if (!field) { + do_warning("can't find format field for binary printk"); + return NULL; + } pevent->bprint_fmt_field = field; } @@ -3715,8 +3807,11 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size, if (!arg->field.field) { arg->field.field = pevent_find_any_field(event, arg->field.name); - if (!arg->field.field) - die("field %s not found", arg->field.name); + if (!arg->field.field) { + do_warning("%s: field %s not found", + __func__, arg->field.name); + return; + } } if (arg->field.field->size != 6) { trace_seq_printf(s, "INVALIDMAC"); @@ -4372,7 +4467,10 @@ get_event_fields(const char *type, const char *name, struct format_field *field; int i = 0; - fields = malloc_or_die(sizeof(*fields) * (count + 1)); + fields = malloc(sizeof(*fields) * (count + 1)); + if (!fields) + return NULL; + for (field = list; field; field = field->next) { fields[i++] = field; if (i == count + 1) { @@ -4767,7 +4865,8 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, } show_warning = 1; - add_event(pevent, event); + if (add_event(pevent, event)) + goto event_alloc_failed; if (!ret && (event->flags & EVENT_FL_ISFTRACE)) { struct format_field *field; @@ -4800,7 +4899,9 @@ enum pevent_errno pevent_parse_event(struct pevent *pevent, const char *buf, event_parse_failed: event->flags |= EVENT_FL_FAILED; /* still add it even if it failed */ - add_event(pevent, event); + if (add_event(pevent, event)) + goto event_alloc_failed; + return ret; event_alloc_failed: -- 1.7.9.2.358.g22243 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [RFC 0/4] Some libtraceevent cleanups/simplifications 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo ` (3 preceding siblings ...) 2012-09-17 20:50 ` [PATCH 4/4] tools lib traceevent: Remove some die() calls Arnaldo Carvalho de Melo @ 2012-09-19 6:48 ` Namhyung Kim 4 siblings, 0 replies; 14+ messages in thread From: Namhyung Kim @ 2012-09-19 6:48 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Steven Rostedt, linux-kernel, David Ahern, Frederic Weisbecker, Jiri Olsa, Mike Galbraith, Paul Mackerras, Peter Zijlstra, Stephane Eranian, arnaldo.melo On Mon, 17 Sep 2012 17:50:45 -0300, Arnaldo Carvalho de Melo wrote: > Hi Steven, > > Please take a look, while looking at how to do some stuff in 'perf > test' just for parsing the /format file I ended up with this series, lemme know > if I can add your Acked-by and push via my perf/core branch. With my add-on patch, the series looks good to me. You can add my Reviewed-by: Namhyung Kim <namhyung@kernel.org> if you want. :) Thanks, Namhyung ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2012-09-27 5:48 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-09-17 20:50 [RFC 0/4] Some libtraceevent cleanups/simplifications Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 1/4] tools lib traceevent: Use asprintf were applicable Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 2/4] tools lib traceevent: Use calloc " Arnaldo Carvalho de Melo 2012-09-19 2:54 ` Namhyung Kim 2012-09-19 6:45 ` [PATCH] tools lib traceevent: Handle alloc_arg failure Namhyung Kim 2012-09-19 11:42 ` Ingo Molnar 2012-09-19 12:26 ` Namhyung Kim 2012-09-19 12:41 ` Steven Rostedt 2012-09-19 13:30 ` Namhyung Kim 2012-09-20 2:09 ` [PATCH v2] " Namhyung Kim 2012-09-27 5:47 ` [tip:perf/core] " tip-bot for Namhyung Kim 2012-09-17 20:50 ` [PATCH 3/4] tools lib traceevent: Fix afterlife gotos Arnaldo Carvalho de Melo 2012-09-17 20:50 ` [PATCH 4/4] tools lib traceevent: Remove some die() calls Arnaldo Carvalho de Melo 2012-09-19 6:48 ` [RFC 0/4] Some libtraceevent cleanups/simplifications Namhyung Kim
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox