From patchwork Wed Oct 30 22:34:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187006 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="ru313old"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NYt4sYGz9sPn for ; Thu, 31 Oct 2019 09:34:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727244AbfJ3We5 (ORCPT ); Wed, 30 Oct 2019 18:34:57 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:45152 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726803AbfJ3We4 (ORCPT ); Wed, 30 Oct 2019 18:34:56 -0400 Received: by mail-pf1-f201.google.com with SMTP id a14so2887032pfr.12 for ; Wed, 30 Oct 2019 15:34:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=JeMQyltmUCU8Ar0BgoXK1Jxj5wnahi83GTKOMO2N0jY=; b=ru313oldJgqkIizzlEgnT3aaaYb9y7d/hgO91Umlt3UhjL/XxJQpbhZ5CkgL+xFOr7 cdSeiebfonuLj7OS+LYfPMVXq+djCNtqWc7XZo0z2g0wtZ7x5nCN86qoygK9NN1P90Ct c/It+u54a2S9hlLm24suKuhkVqsMMsLejM2xgHWsTWdqZV35TyetbkVj6qhysaErPgux 3bTeuPTICcaW8uc6sp+Tunnhmra89a+hV5nHWLW4CJNPwVV1X1d1WUBjwp4zqZSq7xxo XKJnPoUQvmEmiEg6HUghsCiEhQjcqxf6yIENWo5UlUEE25HgApE3kzQfyTP12BAoMhOE Yw4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=JeMQyltmUCU8Ar0BgoXK1Jxj5wnahi83GTKOMO2N0jY=; b=Gsymjt83Ce9bzG8E0V90Rn3mI9p9fbLitikuZGamgPsRRco1YNoSGbt/f1QKhYE1As okIMcEkWOiWLNVvheDvxMtuXfNJXPD4eOPudJbza8hHKniVrvGDsn5juR/LA5VhElxtA Bd2mH/yFInHGCfjhrgFV5gwNHMNu39Cv/adagGnomw7aakdanVmMtDrAEcaUByvGkGk5 f1GKRqmf6UYUxdlC347NpsDPohQTVQm8fUs84Hifeb0pwSzlhqRIAQRfh/0FqrTVO9VZ Y1nY5nrhgWfKvUCI/Yp3wLwuVlHGjEq5DXCLlgC7+BXtTtcXSl0ilyaVQ92ZB2n5XzCG AStw== X-Gm-Message-State: APjAAAWa7uozJNLp3DLt0losLTjB4qM4oN5kNrHGZX66OI6TYko/rOeC gFKUhQ3QY499FuBRxV9nYL9C0nHDiH98 X-Google-Smtp-Source: APXvYqywt2mKqJzXeMxuT76kZ0gRQhs+hU0ly42ZoUHWzoRfaGXsUcc4oKIKykf2/HS88X6eZVLlyE0j5Rw5 X-Received: by 2002:a63:5a59:: with SMTP id k25mr1956115pgm.171.1572474895518; Wed, 30 Oct 2019 15:34:55 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:39 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-2-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 01/10] perf tools: add parse events handle error From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Parse event error handling may overwrite one error string with another creating memory leaks. Introduce a helper routine that warns about multiple error messages as well as avoiding the memory leak. A reproduction of this problem can be seen with: perf stat -e c/c/ After this change this produces: WARNING: multiple event parsing errors event syntax error: 'c/c/' \___ unknown term valid terms: event,filter_rem,filter_opc0,edge,filter_isoc,filter_tid,filter_loc,filter_nc,inv,umask,filter_opc1,tid_en,thresh,filter_all_op,filter_not_nm,filter_state,filter_nm,config,config1,config2,name,period,percore Run 'perf list' for a list of valid events Usage: perf stat [] [] -e, --event event selector. use 'perf list' to list available events Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.c | 82 +++++++++++++++++++++------------- tools/perf/util/parse-events.h | 2 + tools/perf/util/pmu.c | 30 ++++++++----- 3 files changed, 71 insertions(+), 43 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index db882f630f7e..e9b958d6c534 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -182,6 +182,20 @@ static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) #define MAX_EVENT_LENGTH 512 +void parse_events__handle_error(struct parse_events_error *err, int idx, + char *str, char *help) +{ + if (WARN(!str, "WARNING: failed to provide error string\n")) { + free(help); + return; + } + WARN_ONCE(err->str, "WARNING: multiple event parsing errors\n"); + err->idx = idx; + free(err->str); + err->str = str; + free(err->help); + err->help = help; +} struct tracepoint_path *tracepoint_id_to_path(u64 config) { @@ -932,11 +946,11 @@ static int check_type_val(struct parse_events_term *term, return 0; if (err) { - err->idx = term->err_val; - if (type == PARSE_EVENTS__TERM_TYPE_NUM) - err->str = strdup("expected numeric value"); - else - err->str = strdup("expected string value"); + parse_events__handle_error(err, term->err_val, + type == PARSE_EVENTS__TERM_TYPE_NUM + ? strdup("expected numeric value") + : strdup("expected string value"), + NULL); } return -EINVAL; } @@ -972,8 +986,11 @@ static bool config_term_shrinked; static bool config_term_avail(int term_type, struct parse_events_error *err) { + char *err_str; + if (term_type < 0 || term_type >= __PARSE_EVENTS__TERM_TYPE_NR) { - err->str = strdup("Invalid term_type"); + parse_events__handle_error(err, -1, + strdup("Invalid term_type"), NULL); return false; } if (!config_term_shrinked) @@ -992,9 +1009,9 @@ config_term_avail(int term_type, struct parse_events_error *err) return false; /* term_type is validated so indexing is safe */ - if (asprintf(&err->str, "'%s' is not usable in 'perf stat'", - config_term_names[term_type]) < 0) - err->str = NULL; + if (asprintf(&err_str, "'%s' is not usable in 'perf stat'", + config_term_names[term_type]) >= 0) + parse_events__handle_error(err, -1, err_str, NULL); return false; } } @@ -1036,17 +1053,20 @@ do { \ case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE: CHECK_TYPE_VAL(STR); if (strcmp(term->val.str, "no") && - parse_branch_str(term->val.str, &attr->branch_sample_type)) { - err->str = strdup("invalid branch sample type"); - err->idx = term->err_val; + parse_branch_str(term->val.str, + &attr->branch_sample_type)) { + parse_events__handle_error(err, term->err_val, + strdup("invalid branch sample type"), + NULL); return -EINVAL; } break; case PARSE_EVENTS__TERM_TYPE_TIME: CHECK_TYPE_VAL(NUM); if (term->val.num > 1) { - err->str = strdup("expected 0 or 1"); - err->idx = term->err_val; + parse_events__handle_error(err, term->err_val, + strdup("expected 0 or 1"), + NULL); return -EINVAL; } break; @@ -1080,8 +1100,9 @@ do { \ case PARSE_EVENTS__TERM_TYPE_PERCORE: CHECK_TYPE_VAL(NUM); if ((unsigned int)term->val.num > 1) { - err->str = strdup("expected 0 or 1"); - err->idx = term->err_val; + parse_events__handle_error(err, term->err_val, + strdup("expected 0 or 1"), + NULL); return -EINVAL; } break; @@ -1089,9 +1110,9 @@ do { \ CHECK_TYPE_VAL(NUM); break; default: - err->str = strdup("unknown term"); - err->idx = term->err_term; - err->help = parse_events_formats_error_string(NULL); + parse_events__handle_error(err, term->err_term, + strdup("unknown term"), + parse_events_formats_error_string(NULL)); return -EINVAL; } @@ -1142,9 +1163,9 @@ static int config_term_tracepoint(struct perf_event_attr *attr, return config_term_common(attr, term, err); default: if (err) { - err->idx = term->err_term; - err->str = strdup("unknown term"); - err->help = strdup("valid terms: call-graph,stack-size\n"); + parse_events__handle_error(err, term->err_term, + strdup("unknown term"), + strdup("valid terms: call-graph,stack-size\n")); } return -EINVAL; } @@ -1323,10 +1344,12 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, pmu = perf_pmu__find(name); if (!pmu) { - if (asprintf(&err->str, + char *err_str; + + if (asprintf(&err_str, "Cannot find PMU `%s'. Missing kernel support?", - name) < 0) - err->str = NULL; + name) >= 0) + parse_events__handle_error(err, -1, err_str, NULL); return -EINVAL; } @@ -2797,13 +2820,10 @@ void parse_events__clear_array(struct parse_events_array *a) void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str) { - struct parse_events_error *err = parse_state->error; - - if (!err) + if (!parse_state->error) return; - err->idx = idx; - err->str = strdup(str); - WARN_ONCE(!err->str, "WARNING: failed to allocate error string"); + + parse_events__handle_error(parse_state->error, idx, strdup(str), NULL); } static void config_terms_list(char *buf, size_t buf_sz) diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 769e07cddaa2..34f58d24a06a 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -124,6 +124,8 @@ struct parse_events_state { struct list_head *terms; }; +void parse_events__handle_error(struct parse_events_error *err, int idx, + char *str, char *help); void parse_events__shrink_config_terms(void); int parse_events__is_hardcoded_term(struct parse_events_term *term); int parse_events_term__num(struct parse_events_term **term, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index adbe97e941dd..f9f427d4c313 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1050,9 +1050,9 @@ static int pmu_config_term(struct list_head *formats, if (err) { char *pmu_term = pmu_formats_string(formats); - err->idx = term->err_term; - err->str = strdup("unknown term"); - err->help = parse_events_formats_error_string(pmu_term); + parse_events__handle_error(err, term->err_term, + strdup("unknown term"), + parse_events_formats_error_string(pmu_term)); free(pmu_term); } return -EINVAL; @@ -1080,8 +1080,9 @@ static int pmu_config_term(struct list_head *formats, if (term->no_value && bitmap_weight(format->bits, PERF_PMU_FORMAT_BITS) > 1) { if (err) { - err->idx = term->err_val; - err->str = strdup("no value assigned for term"); + parse_events__handle_error(err, term->err_val, + strdup("no value assigned for term"), + NULL); } return -EINVAL; } @@ -1094,8 +1095,9 @@ static int pmu_config_term(struct list_head *formats, term->config, term->val.str); } if (err) { - err->idx = term->err_val; - err->str = strdup("expected numeric value"); + parse_events__handle_error(err, term->err_val, + strdup("expected numeric value"), + NULL); } return -EINVAL; } @@ -1108,11 +1110,15 @@ static int pmu_config_term(struct list_head *formats, max_val = pmu_format_max_value(format->bits); if (val > max_val) { if (err) { - err->idx = term->err_val; - if (asprintf(&err->str, - "value too big for format, maximum is %llu", - (unsigned long long)max_val) < 0) - err->str = strdup("value too big for format"); + char *err_str; + + parse_events__handle_error(err, term->err_val, + asprintf(&err_str, + "value too big for format, maximum is %llu", + (unsigned long long)max_val) < 0 + ? strdup("value too big for format") + : err_str, + NULL); return -EINVAL; } /* From patchwork Wed Oct 30 22:34:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187024 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="g3m4sEJ5"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZv63CRz9sPj for ; Thu, 31 Oct 2019 09:35:51 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727429AbfJ3Wfv (ORCPT ); Wed, 30 Oct 2019 18:35:51 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:35994 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727317AbfJ3WfA (ORCPT ); Wed, 30 Oct 2019 18:35:00 -0400 Received: by mail-pf1-f202.google.com with SMTP id f21so2900579pfa.3 for ; Wed, 30 Oct 2019 15:34:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=H1WJqf6XxMblv8i9/DKNkxzkDXfEbE3x/vJu9p1A8xw=; b=g3m4sEJ5jwnrmt+zZOfUuZz+v1JI5a8KnzqNAAahpdXo67o9ioYWE3vEErDFMofT3C FClTMkwUFz+I8zpUd/gz+KGuk0s0/AfJOSSaoDs/yJABNd9GgoeY7PSExHVXcF/D/7VI DYOS7uU4IRzJ2zKgNysvAcLaDx+MEbnYk34Khs8vNK08NobDmKUzoczKCINXSFOUtaSf uA9mV6e8wV7runwv0eFbgovn2tA41WVa42hLq2uMHmxnXSpQkyGRJwe02OHsqY9Xw4xf wJB68g2k4YC/YLU+zZa2AcAvpysFB1nitKzHm1eU6hqpdQ6BtkgtvEb2jgczq8k0xFy5 glGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=H1WJqf6XxMblv8i9/DKNkxzkDXfEbE3x/vJu9p1A8xw=; b=cE84BNeGzbInEAVYdBX2gOZtBBEMCV/jwXHGHSLD9G97RS0/TdizbOXzCeJfC1fuX7 Kn11UI/SbsjO4Z1xE/b2jKvuM9L4jtdIuT+AAklCwry+9h9AfNV8HJP9PlG5Fui0gaxd tl1+uINhgdjlW3IXgCFK5LCCjCAtEvBPZeb0PyzjRq+FilLfn6qKvD9l9ufA7ylOhgiA UkQeoXqig6F745Pd5jBPqKGWH43IEqKBkbGuHds0FxdzejOYIijASm7rCj0Ctq6R0L7w 9Ai01IzzaL0TvQgzcIUENSqN8ERdF0mKlhVQFfSxYI5imoeOcvkZRXwk1ciWkg5L2KvW RXBQ== X-Gm-Message-State: APjAAAVt9cJmJpKfpNPeWd3OZPtbe/OfD0pekMhFlQGX4fdKDHtR7lVh 86bLnmoANDj2ewxDc12Ha9/jNapZ3/Kr X-Google-Smtp-Source: APXvYqyUlDswQjqzEtPv7XwrnsMfd06BBPsjusjyFKTiCsBd8k8j0G0zpBeKm+8FJzRHeIAV+FmaGjwWHB1j X-Received: by 2002:a63:595:: with SMTP id 143mr2006669pgf.45.1572474898197; Wed, 30 Oct 2019 15:34:58 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:40 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-3-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 02/10] perf tools: move ALLOC_LIST into a function From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Having a YYABORT in a macro makes it hard to free memory for components of a rule. Separate the logic out. Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.y | 65 ++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 48126ae4cd13..5863acb34780 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -25,12 +25,17 @@ do { \ YYABORT; \ } while (0) -#define ALLOC_LIST(list) \ -do { \ - list = malloc(sizeof(*list)); \ - ABORT_ON(!list); \ - INIT_LIST_HEAD(list); \ -} while (0) +static struct list_head* alloc_list() +{ + struct list_head *list; + + list = malloc(sizeof(*list)); + if (!list) + return NULL; + + INIT_LIST_HEAD(list); + return list; +} static void inc_group_count(struct list_head *list, struct parse_events_state *parse_state) @@ -238,7 +243,8 @@ PE_NAME opt_pmu_config if (error) error->idx = @1.first_column; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { struct perf_pmu *pmu = NULL; int ok = 0; @@ -306,7 +312,8 @@ value_sym '/' event_config '/' int type = $1 >> 16; int config = $1 & 255; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3)); parse_events_terms__delete($3); $$ = list; @@ -318,7 +325,8 @@ value_sym sep_slash_slash_dc int type = $1 >> 16; int config = $1 & 255; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, NULL)); $$ = list; } @@ -327,7 +335,8 @@ PE_VALUE_SYM_TOOL sep_slash_slash_dc { struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_tool(_parse_state, list, $1)); $$ = list; } @@ -339,7 +348,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_e struct parse_events_error *error = parse_state->error; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6)); parse_events_terms__delete($6); $$ = list; @@ -351,7 +361,8 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config struct parse_events_error *error = parse_state->error; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4)); parse_events_terms__delete($4); $$ = list; @@ -363,7 +374,8 @@ PE_NAME_CACHE_TYPE opt_event_config struct parse_events_error *error = parse_state->error; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2)); parse_events_terms__delete($2); $$ = list; @@ -375,7 +387,8 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc struct parse_events_state *parse_state = _parse_state; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $6, $4)); $$ = list; @@ -386,7 +399,8 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc struct parse_events_state *parse_state = _parse_state; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, $4)); $$ = list; @@ -397,7 +411,8 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc struct parse_events_state *parse_state = _parse_state; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, $4, 0)); $$ = list; @@ -408,7 +423,8 @@ PE_PREFIX_MEM PE_VALUE sep_dc struct parse_events_state *parse_state = _parse_state; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, (void *) $2, NULL, 0)); $$ = list; @@ -421,7 +437,8 @@ tracepoint_name opt_event_config struct parse_events_error *error = parse_state->error; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); if (error) error->idx = @1.first_column; @@ -457,7 +474,8 @@ PE_VALUE ':' PE_VALUE opt_event_config { struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4)); parse_events_terms__delete($4); $$ = list; @@ -468,7 +486,8 @@ PE_RAW opt_event_config { struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2)); parse_events_terms__delete($2); $$ = list; @@ -480,7 +499,8 @@ PE_BPF_OBJECT opt_event_config struct parse_events_state *parse_state = _parse_state; struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2)); parse_events_terms__delete($2); $$ = list; @@ -490,7 +510,8 @@ PE_BPF_SOURCE opt_event_config { struct list_head *list; - ALLOC_LIST(list); + list = alloc_list(); + ABORT_ON(!list); ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2)); parse_events_terms__delete($2); $$ = list; From patchwork Wed Oct 30 22:34:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187020 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="to6RZPB9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZn5xx4z9sPk for ; Thu, 31 Oct 2019 09:35:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727413AbfJ3WfD (ORCPT ); Wed, 30 Oct 2019 18:35:03 -0400 Received: from mail-pl1-f202.google.com ([209.85.214.202]:37527 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727387AbfJ3WfC (ORCPT ); Wed, 30 Oct 2019 18:35:02 -0400 Received: by mail-pl1-f202.google.com with SMTP id r13so2535364pls.4 for ; Wed, 30 Oct 2019 15:35:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=NBXoMPDHJVu6DlppqIY2kjj0WH1XM9PlNXSL9vxvGXc=; b=to6RZPB9HFoQbqmKAJUjZ3WJ1y220f1xnCCYFZnT8AHAyKvmI8iWBbzxYGOL4HqHKy 1PmW2Bk89kqcN/6509Ht4gbojZ5Fh0aN5BFvIX8S68OJJTJ6Mff6wholdeCtt3kTjz3U w3vdMLOcc7/CbI89RYUlJHak4evKhlgVd+Rl/3BbdoruqPitAijXNWl5sHkS4nBHdEab ZSgXoFbdZZJmfYz/5M/8PUltrW61Xa7L/5ZyDlkdvZ+7Ga6yzrmZFGykRxZ7ShYVNaNP NJf+XleoCHdf0X22IRjQJPcYBshJ+diy+lRANqX0xK7jRsmAUBhOKu7lRtlqL9tBWAGB 84HA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NBXoMPDHJVu6DlppqIY2kjj0WH1XM9PlNXSL9vxvGXc=; b=LK2UYTEPDbel3nuz2OrgwsRqS8PO7fIOyo4//kL4YfM7px3h/mhk3qvGsc8jfg8L1v wvV6zfiuDaOfv5IJuV3jVcKODYN792yVZGcq8/7pPfS7BjNuLpW4HOX+R4AjeOHnvt2G dIMVOKOeWFPOGoKGc+XCb3QsCfITl+DRtJPQajus19ObBuE9B+71jXlsMGNG+n4SlKlF +v3ELWACjVzj5gD6BGLjGJZOOtiOSNm4wt6PQh8x221RriM9wLanzEJVt841vVXFBAaz BVcLt1u3HWK7bTbQucRfXMRRQk68xXmHGm6onCIuqXzWgWXLah7IilBCOMDbMOzA2RN3 xfYQ== X-Gm-Message-State: APjAAAXH/p3eSXBTeQQKSlZmYEGOPzgZzB3PoGWNuQJGlnC1grkv8NH5 exqZ6Pm0Scnhmmr9nAtNMr0wtelo5vZ4 X-Google-Smtp-Source: APXvYqwFABu3kNyEZzoXKOLqzFswnHr6Oczw+2eZi3gXz92ar/LQWg0327BtdqSuK5s1slzmYFKaoRLbH4A8 X-Received: by 2002:a63:e145:: with SMTP id h5mr1976435pgk.447.1572474900839; Wed, 30 Oct 2019 15:35:00 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:41 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-4-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 03/10] perf tools: avoid a malloc for array events From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Use realloc rather than malloc+memcpy to possibly avoid a memory allocation when appending array elements. Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.y | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 5863acb34780..ffa1a1b63796 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -689,14 +689,12 @@ array_terms ',' array_term struct parse_events_array new_array; new_array.nr_ranges = $1.nr_ranges + $3.nr_ranges; - new_array.ranges = malloc(sizeof(new_array.ranges[0]) * - new_array.nr_ranges); + new_array.ranges = realloc($1.ranges, + sizeof(new_array.ranges[0]) * + new_array.nr_ranges); ABORT_ON(!new_array.ranges); - memcpy(&new_array.ranges[0], $1.ranges, - $1.nr_ranges * sizeof(new_array.ranges[0])); memcpy(&new_array.ranges[$1.nr_ranges], $3.ranges, $3.nr_ranges * sizeof(new_array.ranges[0])); - free($1.ranges); free($3.ranges); $$ = new_array; } From patchwork Wed Oct 30 22:34:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187021 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="CrSETiRq"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZn5GFsz9sPj for ; Thu, 31 Oct 2019 09:35:45 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727450AbfJ3WfG (ORCPT ); Wed, 30 Oct 2019 18:35:06 -0400 Received: from mail-yw1-f74.google.com ([209.85.161.74]:33212 "EHLO mail-yw1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727430AbfJ3WfG (ORCPT ); Wed, 30 Oct 2019 18:35:06 -0400 Received: by mail-yw1-f74.google.com with SMTP id p185so2884826ywb.0 for ; Wed, 30 Oct 2019 15:35:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=O46qQh0NfSafqZOQ3RB2bA5TlgUNmGeU07O7S2mDmp8=; b=CrSETiRqHMQOjdJ2lCCBT1pvusZ8sr35GXcohgUIb9pSfaqD9joqRIt248vJFuJbRn Vo/8A89RlQMQyyw7p0itwye5sPZNGqaR6KYv2mrmxYxgyzU5CzhJyaJEv5Z9hCpQXEM5 pU4tszddJsg2nDsmH9PEDvoJYMaMWgm8UPpKIornmNUdfmMNvW7eR8KzZM1jPlI3nnSz yhTxFqGUhGL5nyUgJwuEdiShi101PN6is0peh5f5Ms+MLom82m8fBaJPrR+FW3gnhEF0 z0ik5ClTfj81uwC34dQf42MrKwhBjUvsgJbS/OYcBWgpdn80siccizLp/y9mTyEsRamc ZSKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=O46qQh0NfSafqZOQ3RB2bA5TlgUNmGeU07O7S2mDmp8=; b=c7N6mwMLmkPaEB2C6gBSsB/r6UDjBdzX3CYiSUb+k7OKv7Rs0CyDDK+Se+IydtRITC lUDjIGPWgKStTpRnBzeFIahr2tO5oD88PDkO8I13EzN0m7Lh/xDXiu1QXUGC79+tA8cR 3zFdfVa7yNOjfrm3mgIM57ujV0Tg13xn3rF9reYJQfUqN/tdjhZkN/Zp94hm0TXasXQy EePydlqC63GAdRY5P3zn+eid56syihyv9ikKBL0ebYJa3s7rM9KK50AbZboUovnfuS1R d9wxXHI0jOuvB6PswH19lL2rtqR2p59bYu+x8phju4d+xLAi0hxx/woDbVlgWYklAwMZ Sh7w== X-Gm-Message-State: APjAAAWnCTnEf1IGoonLByOVRcLR8z8sFrVyAfQDIbbTh1COQrkPsrHN KN2VgCWwxvZKr9dJL29ZtpkUqH2EH8GY X-Google-Smtp-Source: APXvYqzX3t2nUPQZVTOUg6iHaQA+sKWtzQICOwxNqxdMb2uq625C2MYcu4zfy22ADO3aYpTWbjATa7LM2Bla X-Received: by 2002:a81:4948:: with SMTP id w69mr1570034ywa.404.1572474903817; Wed, 30 Oct 2019 15:35:03 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:42 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-5-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 04/10] perf tools: splice events onto evlist even on error From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org If event parsing fails the event list is leaked, instead splice the list onto the out result and let the caller cleanup. An example input for parse_events found by libFuzzer that reproduces this memory leak is 'm{'. Signed-off-by: Ian Rogers --- tools/perf/util/parse-events.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index e9b958d6c534..03e54a2d8685 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1950,15 +1950,20 @@ int parse_events(struct evlist *evlist, const char *str, ret = parse_events__scanner(str, &parse_state, PE_START_EVENTS); perf_pmu__parse_cleanup(); + + if (!ret && list_empty(&parse_state.list)) { + WARN_ONCE(true, "WARNING: event parser found nothing\n"); + return -1; + } + + /* + * Add list to the evlist even with errors to allow callers to clean up. + */ + perf_evlist__splice_list_tail(evlist, &parse_state.list); + if (!ret) { struct evsel *last; - if (list_empty(&parse_state.list)) { - WARN_ONCE(true, "WARNING: event parser found nothing\n"); - return -1; - } - - perf_evlist__splice_list_tail(evlist, &parse_state.list); evlist->nr_groups += parse_state.nr_groups; last = evlist__last(evlist); last->cmdline_group_boundary = true; From patchwork Wed Oct 30 22:34:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187008 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="s97DVd+l"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZ55t7wz9sPj for ; Thu, 31 Oct 2019 09:35:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727462AbfJ3WfI (ORCPT ); Wed, 30 Oct 2019 18:35:08 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:39112 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727452AbfJ3WfH (ORCPT ); Wed, 30 Oct 2019 18:35:07 -0400 Received: by mail-pf1-f201.google.com with SMTP id l20so2890711pff.6 for ; Wed, 30 Oct 2019 15:35:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=32WJHD/sh+KDR1QXtWKrcNgurpa55lJDgOM8dIR2hMs=; b=s97DVd+l4q9eCHtPWRoTjcTZxOalac+C+ekD4YByMpb18sCc9jkYRJyNPPv5XYfIBs L5De6Rnih9Deqc9k6uljrfccJ8qiFWpiQp8qqUhuDdRc3Gaah3m48nn4v082qLROsB7E 881jZzNjnihLAoy7POw9DU9qsihxOq7GWkGaujbCh7YXadKWyPNbWzghbL+Fr0lWfbhe gKR/MSjTVtem3S+gcAx0418KrcgxgFb8iyg941U1D4xKvbYeIf3Hq6W0+a1mUyJt1OuT ZBUghnNKygR1rpItwqBrLbOkhUaJ7K/7ABMKRdZ2+BhGrZCZ2ArLlhRYGCHGPf+UFdCy MaTQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=32WJHD/sh+KDR1QXtWKrcNgurpa55lJDgOM8dIR2hMs=; b=Kq0M6+vUUh7FKw952I1rsb+us34Tpz2oOt34fv7Fucyck2H+zxA4FkV0HFDEwUt91N G29OD5meCKCvYY6E/0Bozf98tzhy47Z97H5KjqXBYA12n8nvtniIkfjH+zNhGCOTEJGe fHigBsBSNKyb5cFTRjLQLYhYIbujLgv9oqaL3mNDPgndAUgiDDdpKE9cJREejD9S/No8 kRnyUGEi3AAM6CS6ca1Kcvr/cavPDip6q+hPCSrH7CT+vLG+ilwLdxewbLEs9MswuDhL AHOXNlZ0+ZjyD+Yo5qjZIZz65ZXrjO0pZ9Ytp7PsPl8bRHZR4MoyiQH9EZRbx5mG61AW OUXw== X-Gm-Message-State: APjAAAU7eHEQEX6iWTtZjOb2kCxgoY+UdPyEoWPBwtT53RP2FlRwUn8p o2eaDfFBR1QgTbFzGOvjuuD1XREzK/1d X-Google-Smtp-Source: APXvYqzjsKauaAqON3oPEFGh9TSt63PMuWrGOFptRGGUmXaJr8YeoqpKCpfPx7QC2mj9JHUzQZzIFMI4+CMr X-Received: by 2002:a63:e255:: with SMTP id y21mr1918782pgj.353.1572474906428; Wed, 30 Oct 2019 15:35:06 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:43 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-6-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 05/10] perf tools: ensure config and str in terms are unique From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Make it easier to release memory associated with parse event terms by duplicating the string for the config name and ensuring the val string is a duplicate. Currently the parser may memory leak terms and this is addressed in a later patch. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.c | 51 ++++++++++++++++++++++++++++------ tools/perf/util/parse-events.y | 4 ++- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 03e54a2d8685..578288c94d2a 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1412,7 +1412,6 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, int parse_events_multi_pmu_add(struct parse_events_state *parse_state, char *str, struct list_head **listp) { - struct list_head *head; struct parse_events_term *term; struct list_head *list; struct perf_pmu *pmu = NULL; @@ -1429,19 +1428,30 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state, list_for_each_entry(alias, &pmu->aliases, list) { if (!strcasecmp(alias->name, str)) { + struct list_head *head; + char *config; + head = malloc(sizeof(struct list_head)); if (!head) return -1; INIT_LIST_HEAD(head); - if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - str, 1, false, &str, NULL) < 0) + config = strdup(str); + if (!config) + return -1; + if (parse_events_term__num(&term, + PARSE_EVENTS__TERM_TYPE_USER, + config, 1, false, &config, + NULL) < 0) { + free(list); + free(config); return -1; + } list_add_tail(&term->list, head); if (!parse_events_add_pmu(parse_state, list, pmu->name, head, true, true)) { - pr_debug("%s -> %s/%s/\n", str, + pr_debug("%s -> %s/%s/\n", config, pmu->name, alias->str); ok++; } @@ -1450,8 +1460,10 @@ int parse_events_multi_pmu_add(struct parse_events_state *parse_state, } } } - if (!ok) + if (!ok) { + free(list); return -1; + } *listp = list; return 0; } @@ -2746,30 +2758,51 @@ int parse_events_term__sym_hw(struct parse_events_term **term, char *config, unsigned idx) { struct event_symbol *sym; + char *str; struct parse_events_term temp = { .type_val = PARSE_EVENTS__TERM_TYPE_STR, .type_term = PARSE_EVENTS__TERM_TYPE_USER, - .config = config ?: (char *) "event", + .config = config, }; + if (!temp.config) { + temp.config = strdup("event"); + if (!temp.config) + return -ENOMEM; + } BUG_ON(idx >= PERF_COUNT_HW_MAX); sym = &event_symbols_hw[idx]; - return new_term(term, &temp, (char *) sym->symbol, 0); + str = strdup(sym->symbol); + if (!str) + return -ENOMEM; + return new_term(term, &temp, str, 0); } int parse_events_term__clone(struct parse_events_term **new, struct parse_events_term *term) { + char *str; struct parse_events_term temp = { .type_val = term->type_val, .type_term = term->type_term, - .config = term->config, + .config = NULL, .err_term = term->err_term, .err_val = term->err_val, }; - return new_term(new, &temp, term->val.str, term->val.num); + if (term->config) { + temp.config = strdup(term->config); + if (!temp.config) + return -ENOMEM; + } + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) + return new_term(new, &temp, NULL, term->val.num); + + str = strdup(term->val.str); + if (!str) + return -ENOMEM; + return new_term(new, &temp, str, 0); } int parse_events_copy_term_list(struct list_head *old, diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index ffa1a1b63796..545ab7cefc20 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -665,9 +665,11 @@ PE_NAME array '=' PE_VALUE PE_DRV_CFG_TERM { struct parse_events_term *term; + char *config = strdup($1); + ABORT_ON(!config); ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, - $1, $1, &@1, NULL)); + config, $1, &@1, NULL)); $$ = term; } From patchwork Wed Oct 30 22:34:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187017 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="nBLJpE0g"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZj4jRzz9sPp for ; Thu, 31 Oct 2019 09:35:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727490AbfJ3WfM (ORCPT ); Wed, 30 Oct 2019 18:35:12 -0400 Received: from mail-pf1-f201.google.com ([209.85.210.201]:56616 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727474AbfJ3WfM (ORCPT ); Wed, 30 Oct 2019 18:35:12 -0400 Received: by mail-pf1-f201.google.com with SMTP id v11so2865159pfm.23 for ; Wed, 30 Oct 2019 15:35:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=cbqRFkpgp0LqoXpVxOykKhy7SlGV56CiUpFn5dWk7NY=; b=nBLJpE0g/ZVoC7ShENaqxZVPeLvGSWpaJmA50SeqHlW8D+Etu4dx5ZdGRAXUdKtX+7 7CC1qJbxJiDGrkag+JB4mnBLlB2hs6OVOPojeZ4VBvCqeMhscuCA0uGGmOCOsbcYN5Ye f9uIMNa8yhmPwZhP5NiHLY5hzzmKjw9mGfIlXCEm8ggoonzz+DAbtrtJXUjKKjxB4TMi NASSzux/93nz22ZxcK+ZWdztWdpzcw95hDgdCvUM0pJWeznazuBiPZFXOyhkPDCV/29c ErUHe15HAwDziswCbRs1sz68809jIFKvU0zLjgbmquOzb2LTS4cFACfTcYcPds7PSYFe rPEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=cbqRFkpgp0LqoXpVxOykKhy7SlGV56CiUpFn5dWk7NY=; b=BTrUs8EJ7GZYAV5RFqkX0sAPQMtQ2cPLaClpJ/L+j4degZt40YVMgsQkfRGAUi50oV 3eIp2PBAOJwi0OmtLVI5BBXYyRkKkEiPDya7AhWZmZ/UTUso/zAwOVrHtQ056f/zzpyk wkVObQlJb32KLKmWA/CL9DaBH5QETB5Ayc4HNgOe+XA4eunO1p0VADYcK5B1nzfII90z qmgKU/UooJ1BYqGBnRfwekQzz3f6oqbjWPycn8Ejuc94LVGZPCCDEqQ+Fb9QjrPHY5y8 56mQufRg5ikyC9bjzwbP45Fj/+cfmar+o8eXegX81R2gIT11rI/kMrsJk243sXZowGeC GI5A== X-Gm-Message-State: APjAAAVQlmy/Qghfx/8wsx68FvqCf1xBkwLKtn0c5uUpKr3aXdDdZeFz h75R8R38Zl/O8l+F3R98BvGLXICfV8Xj X-Google-Smtp-Source: APXvYqyQnHcVWf6ZPpgnVyGXIxRZ2R8sABJ/NEAIvqJtk32ZaWH/nqnfSn6GZMhpoFB97VXD61NU+TPNAmZx X-Received: by 2002:a63:f923:: with SMTP id h35mr2019061pgi.323.1572474908998; Wed, 30 Oct 2019 15:35:08 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:44 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-7-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 06/10] perf tools: add destructors for parse event terms From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If parsing fails then destructors are ran to clean the up the stack. Rename the head union member to make the term and evlist use cases more distinct, this simplifies matching the correct destructor. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.y | 69 +++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 545ab7cefc20..035edfa8d42e 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -12,6 +12,7 @@ #include #include #include +#include #include "pmu.h" #include "evsel.h" #include "parse-events.h" @@ -37,6 +38,25 @@ static struct list_head* alloc_list() return list; } +static void free_list_evsel(struct list_head* list_evsel) +{ + struct evsel *evsel, *tmp; + + list_for_each_entry_safe(evsel, tmp, list_evsel, core.node) { + list_del_init(&evsel->core.node); + perf_evsel__delete(evsel); + } + free(list_evsel); +} + +static void free_term(struct parse_events_term *term) +{ + if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) + free(term->val.str); + zfree(&term->array.ranges); + free(term); +} + static void inc_group_count(struct list_head *list, struct parse_events_state *parse_state) { @@ -66,6 +86,7 @@ static void inc_group_count(struct list_head *list, %type PE_VALUE_SYM_TOOL %type PE_RAW %type PE_TERM +%type value_sym %type PE_NAME %type PE_BPF_OBJECT %type PE_BPF_SOURCE @@ -76,37 +97,43 @@ static void inc_group_count(struct list_head *list, %type PE_EVENT_NAME %type PE_PMU_EVENT_PRE PE_PMU_EVENT_SUF PE_KERNEL_PMU_EVENT %type PE_DRV_CFG_TERM -%type value_sym -%type event_config -%type opt_event_config -%type opt_pmu_config +%destructor { free ($$); } %type event_term -%type event_pmu -%type event_legacy_symbol -%type event_legacy_cache -%type event_legacy_mem -%type event_legacy_tracepoint +%destructor { free_term ($$); } +%type event_config +%type opt_event_config +%type opt_pmu_config +%destructor { parse_events_terms__delete ($$); } +%type event_pmu +%type event_legacy_symbol +%type event_legacy_cache +%type event_legacy_mem +%type event_legacy_tracepoint +%type event_legacy_numeric +%type event_legacy_raw +%type event_bpf_file +%type event_def +%type event_mod +%type event_name +%type event +%type events +%type group_def +%type group +%type groups +%destructor { free_list_evsel ($$); } %type tracepoint_name -%type event_legacy_numeric -%type event_legacy_raw -%type event_bpf_file -%type event_def -%type event_mod -%type event_name -%type event -%type events -%type group_def -%type group -%type groups +%destructor { free ($$.sys); free ($$.event); } %type array %type array_term %type array_terms +%destructor { free ($$.ranges); } %union { char *str; u64 num; - struct list_head *head; + struct list_head *list_evsel; + struct list_head *list_terms; struct parse_events_term *term; struct tracepoint_name { char *sys; From patchwork Wed Oct 30 22:34:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187009 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="jeP0KC58"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZC6SSZz9sQp for ; Thu, 31 Oct 2019 09:35:15 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727506AbfJ3WfN (ORCPT ); Wed, 30 Oct 2019 18:35:13 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:50868 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727489AbfJ3WfN (ORCPT ); Wed, 30 Oct 2019 18:35:13 -0400 Received: by mail-pg1-f202.google.com with SMTP id r24so2717147pgj.17 for ; Wed, 30 Oct 2019 15:35:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=XBR+LBIO8UwhtIFgRGeRHsyC7SP8OsXmQpo/yiQxcx4=; b=jeP0KC58lwMIbpA1jDbbGJucE9/RK7tMjDPU3JnpWci1v803G6/p73N28/TgtGaSP6 lfu/E4pTKtNYRM7QtNAxdlfZ0nFAsC+vIqYksAOqB0FWw4W1j/TlummG2HpYo0zymOkb ehNACuxtsv/HJsgdibi/K+3VQGL0rMDek+iX9iPLyiJlMDXkmeRsQVfKTN2yrddajZEk y60Jv+wq24bOFDUFw7XjTTFYUEQjkk5+lRAKFH9ejSBaUQrQkYKi+EhIXM9TwM6hnGph AULgkXWPjSJFbzgXStgUxphQUR4TeSlt+5yVMT3dGKtna41Kgm9Hj8vfxiwkZz39FT1Q S/CA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=XBR+LBIO8UwhtIFgRGeRHsyC7SP8OsXmQpo/yiQxcx4=; b=SkNN4S4CI1yaxzFCJb/9ZfeTOVnimtleNTDP96RS/r2AgJSq/mE0foDZHiP/CgL/sh a+TIDWsWa/+nZGyvFnWz4KZ8IEvVcpMmIJRXfbrgGmhcVD41Nv51azribX0vdTMAforl yIsWSdI8UVbO14FOhKAm74fzRMxLp8PH4jf96wx3JoWWVYr200Kuyg77VKHxCAT1GHNw qdmSV41f3gc3fWt+YLCnAjHY9ZX8ThvdUUIzy8IP1hoxD9hHgy+5cq24H/DhN/5rZb0X pgCit0RGISyBWSpT/hxX9RP5ZskKGulGjMAX6veMFyb5a5j0Qv+3QiVHLMbT2hnd7q6m tDNg== X-Gm-Message-State: APjAAAWuQrABxnujRuNBWgoALJC/skHgBNV6iojUxw9BSePPMOkb70B5 FtJYUxbDTteWcpLbpnVTqse6chxmYrAw X-Google-Smtp-Source: APXvYqyN6D2cz7ERmBa0fMmhzNzSS+ISrUjf+kwHhxIs44P6eG/XvqhBW6AY0QGPp1aJHtlhGIxKMBWdxvee X-Received: by 2002:a63:e055:: with SMTP id n21mr1936911pgj.411.1572474911501; Wed, 30 Oct 2019 15:35:11 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:45 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-8-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 07/10] perf tools: before yyabort-ing free components From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Yyabort doesn't destruct inputs and so this must be done manually before using yyabort. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.y | 252 ++++++++++++++++++++++++++------- 1 file changed, 197 insertions(+), 55 deletions(-) diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 035edfa8d42e..376b19855470 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -152,6 +152,7 @@ start_events: groups { struct parse_events_state *parse_state = _parse_state; + /* frees $1 */ parse_events_update_lists($1, &parse_state->list); } @@ -161,6 +162,7 @@ groups ',' group struct list_head *list = $1; struct list_head *group = $3; + /* frees $3 */ parse_events_update_lists(group, list); $$ = list; } @@ -170,6 +172,7 @@ groups ',' event struct list_head *list = $1; struct list_head *event = $3; + /* frees $3 */ parse_events_update_lists(event, list); $$ = list; } @@ -182,8 +185,14 @@ group: group_def ':' PE_MODIFIER_EVENT { struct list_head *list = $1; + int err; - ABORT_ON(parse_events__modifier_group(list, $3)); + err = parse_events__modifier_group(list, $3); + free($3); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } | @@ -196,6 +205,7 @@ PE_NAME '{' events '}' inc_group_count(list, _parse_state); parse_events__set_leader($1, list, _parse_state); + free($1); $$ = list; } | @@ -214,6 +224,7 @@ events ',' event struct list_head *event = $3; struct list_head *list = $1; + /* frees $3 */ parse_events_update_lists(event, list); $$ = list; } @@ -226,13 +237,19 @@ event_mod: event_name PE_MODIFIER_EVENT { struct list_head *list = $1; + int err; /* * Apply modifier on all events added by single event definition * (there could be more events added for multiple tracepoint * definitions via '*?'. */ - ABORT_ON(parse_events__modifier_event(list, $2, false)); + err = parse_events__modifier_event(list, $2, false); + free($2); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } | @@ -241,8 +258,14 @@ event_name event_name: PE_EVENT_NAME event_def { - ABORT_ON(parse_events_name($2, $1)); + int err; + + err = parse_events_name($2, $1); free($1); + if (err) { + free_list_evsel($2); + YYABORT; + } $$ = $2; } | @@ -262,23 +285,33 @@ PE_NAME opt_pmu_config { struct parse_events_state *parse_state = _parse_state; struct parse_events_error *error = parse_state->error; - struct list_head *list, *orig_terms, *terms; + struct list_head *list = NULL, *orig_terms = NULL, *terms= NULL; + char *pattern = NULL; + +#define CLEANUP_YYABORT \ + do { \ + parse_events_terms__delete($2); \ + parse_events_terms__delete(orig_terms); \ + free($1); \ + free(pattern); \ + YYABORT; \ + } while(0) if (parse_events_copy_term_list($2, &orig_terms)) - YYABORT; + CLEANUP_YYABORT; if (error) error->idx = @1.first_column; list = alloc_list(); - ABORT_ON(!list); + if (!list) + CLEANUP_YYABORT; if (parse_events_add_pmu(_parse_state, list, $1, $2, false, false)) { struct perf_pmu *pmu = NULL; int ok = 0; - char *pattern; if (asprintf(&pattern, "%s*", $1) < 0) - YYABORT; + CLEANUP_YYABORT; while ((pmu = perf_pmu__scan(pmu)) != NULL) { char *name = pmu->name; @@ -287,31 +320,32 @@ PE_NAME opt_pmu_config strncmp($1, "uncore_", 7)) name += 7; if (!fnmatch(pattern, name, 0)) { - if (parse_events_copy_term_list(orig_terms, &terms)) { - free(pattern); - YYABORT; - } + if (parse_events_copy_term_list(orig_terms, &terms)) + CLEANUP_YYABORT; if (!parse_events_add_pmu(_parse_state, list, pmu->name, terms, true, false)) ok++; parse_events_terms__delete(terms); } } - free(pattern); - if (!ok) - YYABORT; + CLEANUP_YYABORT; } parse_events_terms__delete($2); parse_events_terms__delete(orig_terms); + free($1); $$ = list; +#undef CLEANUP_YYABORT } | PE_KERNEL_PMU_EVENT sep_dc { struct list_head *list; + int err; - if (parse_events_multi_pmu_add(_parse_state, $1, &list) < 0) + err = parse_events_multi_pmu_add(_parse_state, $1, &list); + free($1); + if (err < 0) YYABORT; $$ = list; } @@ -322,6 +356,8 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc char pmu_name[128]; snprintf(&pmu_name, 128, "%s-%s", $1, $3); + free($1); + free($3); if (parse_events_multi_pmu_add(_parse_state, pmu_name, &list) < 0) YYABORT; $$ = list; @@ -338,11 +374,16 @@ value_sym '/' event_config '/' struct list_head *list; int type = $1 >> 16; int config = $1 & 255; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_numeric(_parse_state, list, type, config, $3)); + err = parse_events_add_numeric(_parse_state, list, type, config, $3); parse_events_terms__delete($3); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } | @@ -374,11 +415,19 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT '-' PE_NAME_CACHE_OP_RESULT opt_e struct parse_events_state *parse_state = _parse_state; struct parse_events_error *error = parse_state->error; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6)); + err = parse_events_add_cache(list, &parse_state->idx, $1, $3, $5, error, $6); parse_events_terms__delete($6); + free($1); + free($3); + free($5); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } | @@ -387,11 +436,18 @@ PE_NAME_CACHE_TYPE '-' PE_NAME_CACHE_OP_RESULT opt_event_config struct parse_events_state *parse_state = _parse_state; struct parse_events_error *error = parse_state->error; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4)); + err = parse_events_add_cache(list, &parse_state->idx, $1, $3, NULL, error, $4); parse_events_terms__delete($4); + free($1); + free($3); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } | @@ -400,11 +456,17 @@ PE_NAME_CACHE_TYPE opt_event_config struct parse_events_state *parse_state = _parse_state; struct parse_events_error *error = parse_state->error; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2)); + err = parse_events_add_cache(list, &parse_state->idx, $1, NULL, NULL, error, $2); parse_events_terms__delete($2); + free($1); + if (err) { + free_list_evsel(list); + YYABORT; + } $$ = list; } @@ -413,11 +475,17 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE ':' PE_MODIFIER_BP sep_dc { struct parse_events_state *parse_state = _parse_state; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, - (void *) $2, $6, $4)); + err = parse_events_add_breakpoint(list, &parse_state->idx, + (void *) $2, $6, $4); + free($6); + if (err) { + free(list); + YYABORT; + } $$ = list; } | @@ -428,8 +496,11 @@ PE_PREFIX_MEM PE_VALUE '/' PE_VALUE sep_dc list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, - (void *) $2, NULL, $4)); + if (parse_events_add_breakpoint(list, &parse_state->idx, + (void *) $2, NULL, $4)) { + free(list); + YYABORT; + } $$ = list; } | @@ -437,11 +508,17 @@ PE_PREFIX_MEM PE_VALUE ':' PE_MODIFIER_BP sep_dc { struct parse_events_state *parse_state = _parse_state; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, - (void *) $2, $4, 0)); + err = parse_events_add_breakpoint(list, &parse_state->idx, + (void *) $2, $4, 0); + free($4); + if (err) { + free(list); + YYABORT; + } $$ = list; } | @@ -452,8 +529,11 @@ PE_PREFIX_MEM PE_VALUE sep_dc list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_breakpoint(list, &parse_state->idx, - (void *) $2, NULL, 0)); + if (parse_events_add_breakpoint(list, &parse_state->idx, + (void *) $2, NULL, 0)) { + free(list); + YYABORT; + } $$ = list; } @@ -463,29 +543,35 @@ tracepoint_name opt_event_config struct parse_events_state *parse_state = _parse_state; struct parse_events_error *error = parse_state->error; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); if (error) error->idx = @1.first_column; - if (parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, - error, $2)) - return -1; + err = parse_events_add_tracepoint(list, &parse_state->idx, $1.sys, $1.event, + error, $2); + parse_events_terms__delete($2); + free($1.sys); + free($1.event); + if (err) { + free(list); + return -1; + } $$ = list; } tracepoint_name: PE_NAME '-' PE_NAME ':' PE_NAME { - char sys_name[128]; struct tracepoint_name tracepoint; - snprintf(&sys_name, 128, "%s-%s", $1, $3); - tracepoint.sys = &sys_name; + ABORT_ON(asprintf(&tracepoint.sys, "%s-%s", $1, $3) < 0); tracepoint.event = $5; - + free($1); + free($3); $$ = tracepoint; } | @@ -500,11 +586,16 @@ event_legacy_numeric: PE_VALUE ':' PE_VALUE opt_event_config { struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4)); + err = parse_events_add_numeric(_parse_state, list, (u32)$1, $3, $4); parse_events_terms__delete($4); + if (err) { + free(list); + YYABORT; + } $$ = list; } @@ -512,11 +603,16 @@ event_legacy_raw: PE_RAW opt_event_config { struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2)); + err = parse_events_add_numeric(_parse_state, list, PERF_TYPE_RAW, $1, $2); parse_events_terms__delete($2); + if (err) { + free(list); + YYABORT; + } $$ = list; } @@ -525,22 +621,33 @@ PE_BPF_OBJECT opt_event_config { struct parse_events_state *parse_state = _parse_state; struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_load_bpf(parse_state, list, $1, false, $2)); + err = parse_events_load_bpf(parse_state, list, $1, false, $2); parse_events_terms__delete($2); + free($1); + if (err) { + free(list); + YYABORT; + } $$ = list; } | PE_BPF_SOURCE opt_event_config { struct list_head *list; + int err; list = alloc_list(); ABORT_ON(!list); - ABORT_ON(parse_events_load_bpf(_parse_state, list, $1, true, $2)); + err = parse_events_load_bpf(_parse_state, list, $1, true, $2); parse_events_terms__delete($2); + if (err) { + free(list); + YYABORT; + } $$ = list; } @@ -573,6 +680,10 @@ opt_pmu_config: start_terms: event_config { struct parse_events_state *parse_state = _parse_state; + if (parse_state->terms) { + parse_events_terms__delete ($1); + YYABORT; + } parse_state->terms = $1; } @@ -582,7 +693,10 @@ event_config ',' event_term struct list_head *head = $1; struct parse_events_term *term = $3; - ABORT_ON(!head); + if (!head) { + free_term(term); + YYABORT; + } list_add_tail(&term->list, head); $$ = $1; } @@ -603,8 +717,12 @@ PE_NAME '=' PE_NAME { struct parse_events_term *term; - ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $3, &@1, &@3)); + if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $3, &@1, &@3)) { + free($1); + free($3); + YYABORT; + } $$ = term; } | @@ -612,8 +730,11 @@ PE_NAME '=' PE_VALUE { struct parse_events_term *term; - ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $3, false, &@1, &@3)); + if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $3, false, &@1, &@3)) { + free($1); + YYABORT; + } $$ = term; } | @@ -622,7 +743,10 @@ PE_NAME '=' PE_VALUE_SYM_HW struct parse_events_term *term; int config = $3 & 255; - ABORT_ON(parse_events_term__sym_hw(&term, $1, config)); + if (parse_events_term__sym_hw(&term, $1, config)) { + free($1); + YYABORT; + } $$ = term; } | @@ -630,8 +754,11 @@ PE_NAME { struct parse_events_term *term; - ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, 1, true, &@1, NULL)); + if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, 1, true, &@1, NULL)) { + free($1); + YYABORT; + } $$ = term; } | @@ -648,7 +775,10 @@ PE_TERM '=' PE_NAME { struct parse_events_term *term; - ABORT_ON(parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)); + if (parse_events_term__str(&term, (int)$1, NULL, $3, &@1, &@3)) { + free($3); + YYABORT; + } $$ = term; } | @@ -672,9 +802,13 @@ PE_NAME array '=' PE_NAME { struct parse_events_term *term; - ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $4, &@1, &@4)); - + if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $4, &@1, &@4)) { + free($1); + free($4); + free($2.ranges); + YYABORT; + } term->array = $2; $$ = term; } @@ -683,8 +817,12 @@ PE_NAME array '=' PE_VALUE { struct parse_events_term *term; - ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, - $1, $4, false, &@1, &@4)); + if (parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER, + $1, $4, false, &@1, &@4)) { + free($1); + free($2.ranges); + YYABORT; + } term->array = $2; $$ = term; } @@ -695,8 +833,12 @@ PE_DRV_CFG_TERM char *config = strdup($1); ABORT_ON(!config); - ABORT_ON(parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, - config, $1, &@1, NULL)); + if (parse_events_term__str(&term, PARSE_EVENTS__TERM_TYPE_DRV_CFG, + config, $1, &@1, NULL)) { + free($1); + free(config); + YYABORT; + } $$ = term; } From patchwork Wed Oct 30 22:34:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187011 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="l05WTTft"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZH4Mk4z9sQr for ; Thu, 31 Oct 2019 09:35:19 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727532AbfJ3WfS (ORCPT ); Wed, 30 Oct 2019 18:35:18 -0400 Received: from mail-pl1-f201.google.com ([209.85.214.201]:39966 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727513AbfJ3WfQ (ORCPT ); Wed, 30 Oct 2019 18:35:16 -0400 Received: by mail-pl1-f201.google.com with SMTP id f10so2530292plr.7 for ; Wed, 30 Oct 2019 15:35:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=n/kunXFB8a17/1SeufduY2AZP1in+T/Iq/GsFxRYzfY=; b=l05WTTftzkwYenk8bVJ16EaTRciLaUtMqRbwlXpBBRfNqUlrXbXG4d2kZVDod0qRT1 QemSRI2R6pFqjC4xssA9CHv+kG/6uajvIMIsjgW+UAtcEE4Igy3skTCMlF98kAlD8Izb aQFaGZAijkQJNO1Kct0mO3IvLAquBqnGS9p01Ule3gft9yLkTaoAXn/+i9HLvlrXiDXI u3Z04Nw2FArAfEpqco3sOzW8OPJQt/OzNTRjyUjfjB/x4IQDvX3Z3QhuwAQ6TGeM6klG cFo5rdzhOyrSoDwt6GgcM3h6jfLO92wn/vckvlNJab9Bx1/4qg41pEkmJkobejSh+9hE xzKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=n/kunXFB8a17/1SeufduY2AZP1in+T/Iq/GsFxRYzfY=; b=gH3tIcpGNiCvGmH8Y7MtKjqVLcDqRoODM985gmBasNWelETkIWb0nSbDfb/RhFI+mg 2cPAYVRkEnuN88I/IsvOaWMen5MA/BOZT2YIW0+d8Vbbp+jE776oxfegpyY/dzQ3OATY 6VguTazXcTmLXtaxnQwfdDdAMYKo5eDxKTXlde+KAD6FROQN2FKxPkXm0kNF75vXy7Um 3jQAu5rpWVQK45b9nw8fsYGO0raP/oDt89wco78c+JIh15enCGZpfUNfxhVR1zkA+ULF dsUYOqhtfFp+W/S1me8N6+rEErR5/6nk8ZKya1KF9AdMr8pmARhDpW/QTJG+3CWY9SFa jr+w== X-Gm-Message-State: APjAAAUy959qCUSYauGlbtoMUJnuTkEYvaL9XIHAwIvnzprvRzMhna04 ZjV1rG9LEj82V86EO1Taik+PGvNW1lH4 X-Google-Smtp-Source: APXvYqyUXDTP+AZ2NyPn5itLqJLExzhTopKCQLn1yYFozbb1JDl/bquUPF6RFStOo1v+cOvusy5TPWMDPE6z X-Received: by 2002:a63:4b52:: with SMTP id k18mr1971001pgl.394.1572474914325; Wed, 30 Oct 2019 15:35:14 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:46 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-9-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 08/10] perf tools: if pmu configuration fails free terms From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Avoid a memory leak when the configuration fails. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 578288c94d2a..a0a80f4e7038 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -1388,8 +1388,15 @@ int parse_events_add_pmu(struct parse_events_state *parse_state, if (get_config_terms(head_config, &config_terms)) return -ENOMEM; - if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) + if (perf_pmu__config(pmu, &attr, head_config, parse_state->error)) { + struct perf_evsel_config_term *pos, *tmp; + + list_for_each_entry_safe(pos, tmp, &config_terms, list) { + list_del_init(&pos->list); + free(pos); + } return -EINVAL; + } evsel = __add_event(list, &parse_state->idx, &attr, get_config_name(head_config), pmu, From patchwork Wed Oct 30 22:34:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187014 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="BKymhZUZ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZc0HGBz9sPp for ; Thu, 31 Oct 2019 09:35:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727585AbfJ3Wfe (ORCPT ); Wed, 30 Oct 2019 18:35:34 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:42742 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727537AbfJ3WfU (ORCPT ); Wed, 30 Oct 2019 18:35:20 -0400 Received: by mail-pg1-f202.google.com with SMTP id k12so2679945pgj.9 for ; Wed, 30 Oct 2019 15:35:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=p9FVirzTzYKaiGv+x7/Rx/zUK46UD8R9gJICu3l/Lr8=; b=BKymhZUZ7xaDlDvS89wo1zhChJLnMb2wZLQ2xiOsUEwqPL2rfzCSAlAVtxmZ1JgIB6 EOh4p8N4ksRVf6Kyxr9oRX+SXbxyWj8ZVsXg1lvDNn0P1DOy/bIgHvhkMkKFnphFUzVd UJytedKiCghegTR5QQcGRxQI4O5NXiJkmbJ21WcqnnWWyHJ4FK+oKMdMTb3S6QL+WJYg 8Xq1Gl7jL/5AjSBKqiWVbfqoXGFa0vhnyQGHEFqWgmlTUwrCdnm3RfKYh6efGRxjtN0M SAUdVYCmZAKCwijkAFoyqIXnc9Ss+N0tMa/+2br8djBilJM3Pw+j6DahJbK95MaTiVL1 D6Eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=p9FVirzTzYKaiGv+x7/Rx/zUK46UD8R9gJICu3l/Lr8=; b=LIFBqwdx/kGcN/Q6At/Jqy+5t0iZkPP6SFEvG0BXb5NOT1bsnBwX7UwwnJLt91m6/V xNRjfthZ6feO2ZLP4peTcoNTnsxOLGQ6gmjjtjqD7ys6NdC2ue2jit1rNmejqqnCKYgE 6z2r9ao+FeaXudSUYv1S+QKbRIfpcO94C2Bj5yDE3L4TGAfqN9G82DHosk8XMXP4oBWD 24yTj+ZBoQTUwyQPj9MY7F0H+nwRjlGQti3OVte/RzXXfflL9+8ml+2vLuSg07TliCyA K6JuoqmM3sFwqxtxUZvjF2wMWriCQMniWvpTswhktt7GYxgLZyh9OXTyT73WKBa6kyYQ 33xw== X-Gm-Message-State: APjAAAUpuVDchM08mj6lOvE38IfOr3Ti7FscckgW8zYD6w4Z4sasES9U yELSSDTsrTQ996PyOeHC3GMSyebFLMYL X-Google-Smtp-Source: APXvYqzRsOFDWsM7cxUzRHzzOvsVAPisUEnAQL8FNzENf20i+hYWQuBS8kbaiVsNxi94sN33CUCfnQtOoEgb X-Received: by 2002:a63:3445:: with SMTP id b66mr1958323pga.177.1572474917209; Wed, 30 Oct 2019 15:35:17 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:47 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-10-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 09/10] perf tools: add a deep delete for parse event terms From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Add a parse_events_term deep delete function so that owned strings and arrays are freed. Signed-off-by: Ian Rogers Acked-by: Jiri Olsa --- tools/perf/util/parse-events.c | 16 +++++++++++++--- tools/perf/util/parse-events.h | 1 + tools/perf/util/parse-events.y | 12 ++---------- tools/perf/util/pmu.c | 2 +- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index a0a80f4e7038..6d18ff9bce49 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -2812,6 +2812,18 @@ int parse_events_term__clone(struct parse_events_term **new, return new_term(new, &temp, str, 0); } +void parse_events_term__delete(struct parse_events_term *term) +{ + if (term->array.nr_ranges) + zfree(&term->array.ranges); + + if (term->type_val != PARSE_EVENTS__TERM_TYPE_NUM) + zfree(&term->val.str); + + zfree(&term->config); + free(term); +} + int parse_events_copy_term_list(struct list_head *old, struct list_head **new) { @@ -2842,10 +2854,8 @@ void parse_events_terms__purge(struct list_head *terms) struct parse_events_term *term, *h; list_for_each_entry_safe(term, h, terms, list) { - if (term->array.nr_ranges) - zfree(&term->array.ranges); list_del_init(&term->list); - free(term); + parse_events_term__delete(term); } } diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 34f58d24a06a..5ee8ac93840c 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -139,6 +139,7 @@ int parse_events_term__sym_hw(struct parse_events_term **term, char *config, unsigned idx); int parse_events_term__clone(struct parse_events_term **new, struct parse_events_term *term); +void parse_events_term__delete(struct parse_events_term *term); void parse_events_terms__delete(struct list_head *terms); void parse_events_terms__purge(struct list_head *terms); void parse_events__clear_array(struct parse_events_array *a); diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 376b19855470..4cac830015be 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y @@ -49,14 +49,6 @@ static void free_list_evsel(struct list_head* list_evsel) free(list_evsel); } -static void free_term(struct parse_events_term *term) -{ - if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) - free(term->val.str); - zfree(&term->array.ranges); - free(term); -} - static void inc_group_count(struct list_head *list, struct parse_events_state *parse_state) { @@ -99,7 +91,7 @@ static void inc_group_count(struct list_head *list, %type PE_DRV_CFG_TERM %destructor { free ($$); } %type event_term -%destructor { free_term ($$); } +%destructor { parse_events_term__delete ($$); } %type event_config %type opt_event_config %type opt_pmu_config @@ -694,7 +686,7 @@ event_config ',' event_term struct parse_events_term *term = $3; if (!head) { - free_term(term); + parse_events_term__delete(term); YYABORT; } list_add_tail(&term->list, head); diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index f9f427d4c313..db1e57113f4b 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1260,7 +1260,7 @@ int perf_pmu__check_alias(struct perf_pmu *pmu, struct list_head *head_terms, info->metric_name = alias->metric_name; list_del_init(&term->list); - free(term); + parse_events_term__delete(term); } /* From patchwork Wed Oct 30 22:34:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1187012 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: incoming-bpf@patchwork.ozlabs.org Delivered-To: patchwork-incoming-bpf@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=bpf-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="qs68OdZO"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 473NZR3T9yz9sPv for ; Thu, 31 Oct 2019 09:35:27 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727511AbfJ3WfW (ORCPT ); Wed, 30 Oct 2019 18:35:22 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:52406 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727545AbfJ3WfV (ORCPT ); Wed, 30 Oct 2019 18:35:21 -0400 Received: by mail-pg1-f202.google.com with SMTP id e15so2716575pgh.19 for ; Wed, 30 Oct 2019 15:35:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=OX6v9W/RwB1FnmAHi/ViJDv088XbC8QO/KsWRubigJ8=; b=qs68OdZO/1E8+EnsBJL8qC5UADwWYoU/47eaqwh13IAkQxpkYS6gaL+TVBy5iS9bHa e5xGY8JSXPgM9foQrYIe+ORYfpgZqK8sykheVScwAQF8IbPpmO3MMyKma17YDgMJZaIL VE6VQQdhmtFi+KB1uW2iR/v+qAlrY8dyjftmjuECbv3yLMzHfdyp0SKeIXZL2nyvfgsg iPgX0kjGkYf5M5jK4IIz+WHxTFaMxL+/+VYpiHVAHmUNRW/sIJetRKg3Amy4nijXy0sD GOluW8L3rB8UFvNVV9JVhz1gJyRGvPJvnSH36dcfj7cosQAnjeUpLKef9kBjUt9tPKyl O4WA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=OX6v9W/RwB1FnmAHi/ViJDv088XbC8QO/KsWRubigJ8=; b=XJZqDxi3YH5ZHXywZ1SpBXpVHrLLYi4mUqJNkQWywhI03RNgcFcM25emEf+zHQgsJX MzZxVTBtdwLml4oWvEqFHUOxdY7yqNCz8+oVxOvm8tubDeSHN12BPAu7ucVwJq/jwCA1 Tj81WuzpolyW+Fp/VqWIyhl4AYwWW4pFFlI2MzzEoOVZ9zo94DV+7n1x65xfivG1pRN2 J+ckMxxzL9HlmVx0LT4p8jKW8+a8IPbz3ttNaCDtD2UGHb/k+2MuuNu7czn+kSZjY2ga lud3EBjhqEg6aIi/Xz6AVdGJmYnuzyVPMk+ybGvBXd94YhE1/d9qNTrmdVcT5YwWpJqx ZtUw== X-Gm-Message-State: APjAAAWm3ruXPxxjvJXrwKk5GVCz4BOn4JoDnS7kNjBJ9TxBB1T0///G 8srkWNi9EwujmWQxrNtpQOJMsFqSdZ8q X-Google-Smtp-Source: APXvYqxqO5FmFDL8ghx5pAsFXGsDqyGM6xp7zRxXz1v0pQzg86XC4lN28u7HhWhsxPe2WPZHZBp+OM+SZtf0 X-Received: by 2002:a63:5847:: with SMTP id i7mr1868803pgm.387.1572474920146; Wed, 30 Oct 2019 15:35:20 -0700 (PDT) Date: Wed, 30 Oct 2019 15:34:48 -0700 In-Reply-To: <20191030223448.12930-1-irogers@google.com> Message-Id: <20191030223448.12930-11-irogers@google.com> Mime-Version: 1.0 References: <20191025180827.191916-1-irogers@google.com> <20191030223448.12930-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.rc1.363.gb1bccd3e3d-goog Subject: [PATCH v5 10/10] perf tools: report initial event parsing error From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Alexei Starovoitov , Daniel Borkmann , Martin KaFai Lau , Song Liu , Yonghong Song , Andi Kleen , Jin Yao , Adrian Hunter , Kan Liang , John Garry , linux-kernel@vger.kernel.org, netdev@vger.kernel.org, bpf@vger.kernel.org, clang-built-linux@googlegroups.com Cc: Stephane Eranian , Ian Rogers Sender: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Record the first event parsing error and report. Implementing feedback from Jiri Olsa: https://lkml.org/lkml/2019/10/28/680 An example error is: $ tools/perf/perf stat -e c/c/ WARNING: multiple event parsing errors event syntax error: 'c/c/' \___ unknown term valid terms: event,filter_rem,filter_opc0,edge,filter_isoc,filter_tid,filter_loc,filter_nc,inv,umask,filter_opc1,tid_en,thresh,filter_all_op,filter_not_nm,filter_state,filter_nm,config,config1,config2,name,period,percore Initial error: event syntax error: 'c/c/' \___ Cannot find PMU `c'. Missing kernel support? Run 'perf list' for a list of valid events Usage: perf stat [] [] -e, --event event selector. use 'perf list' to list available events Signed-off-by: Ian Rogers --- tools/perf/arch/powerpc/util/kvm-stat.c | 9 ++- tools/perf/builtin-stat.c | 2 + tools/perf/builtin-trace.c | 16 ++++-- tools/perf/tests/parse-events.c | 3 +- tools/perf/util/metricgroup.c | 2 +- tools/perf/util/parse-events.c | 73 ++++++++++++++++++------- tools/perf/util/parse-events.h | 4 ++ 7 files changed, 82 insertions(+), 27 deletions(-) diff --git a/tools/perf/arch/powerpc/util/kvm-stat.c b/tools/perf/arch/powerpc/util/kvm-stat.c index 9cc1c4a9dec4..30f5310373ca 100644 --- a/tools/perf/arch/powerpc/util/kvm-stat.c +++ b/tools/perf/arch/powerpc/util/kvm-stat.c @@ -113,10 +113,15 @@ static int is_tracepoint_available(const char *str, struct evlist *evlist) struct parse_events_error err; int ret; - err.str = NULL; + bzero(&err, sizeof(err)); ret = parse_events(evlist, str, &err); - if (err.str) + if (err.str) { pr_err("%s : %s\n", str, err.str); + free(&err->str); + free(&err->help); + free(&err->first_str); + free(&err->first_help); + } return ret; } diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index c88d4e118409..5d2fc8bed5f8 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -1260,6 +1260,7 @@ static int add_default_attributes(void) if (stat_config.null_run) return 0; + bzero(&errinfo, sizeof(errinfo)); if (transaction_run) { /* Handle -T as -M transaction. Once platform specific metrics * support has been added to the json files, all archictures @@ -1317,6 +1318,7 @@ static int add_default_attributes(void) return -1; } if (err) { + parse_events_print_error(&errinfo, smi_cost_attrs); fprintf(stderr, "Cannot set up SMI cost events\n"); return -1; } diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 43c05eae1768..46a72ecac427 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -3016,11 +3016,18 @@ static bool evlist__add_vfs_getname(struct evlist *evlist) { bool found = false; struct evsel *evsel, *tmp; - struct parse_events_error err = { .idx = 0, }; - int ret = parse_events(evlist, "probe:vfs_getname*", &err); + struct parse_events_error err; + int ret; - if (ret) + bzero(&err, sizeof(err)); + ret = parse_events(evlist, "probe:vfs_getname*", &err); + if (ret) { + free(err.str); + free(err.help); + free(err.first_str); + free(err.first_help); return false; + } evlist__for_each_entry_safe(evlist, evsel, tmp) { if (!strstarts(perf_evsel__name(evsel), "probe:vfs_getname")) @@ -4832,8 +4839,9 @@ int cmd_trace(int argc, const char **argv) * wrong in more detail. */ if (trace.perfconfig_events != NULL) { - struct parse_events_error parse_err = { .idx = 0, }; + struct parse_events_error parse_err; + bzero(&parse_err, sizeof(parse_err)); err = parse_events(trace.evlist, trace.perfconfig_events, &parse_err); if (err) { parse_events_print_error(&parse_err, trace.perfconfig_events); diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 25e0ed2eedfc..091c3aeccc27 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -1768,10 +1768,11 @@ static struct terms_test test__terms[] = { static int test_event(struct evlist_test *e) { - struct parse_events_error err = { .idx = 0, }; + struct parse_events_error err; struct evlist *evlist; int ret; + bzero(&err, sizeof(err)); if (e->valid && !e->valid()) { pr_debug("... SKIP"); return 0; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index a7c0424dbda3..6a4d350d5cdb 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -523,7 +523,7 @@ int metricgroup__parse_groups(const struct option *opt, if (ret) return ret; pr_debug("adding %s\n", extra_events.buf); - memset(&parse_error, 0, sizeof(struct parse_events_error)); + bzero(&parse_error, sizeof(parse_error)); ret = parse_events(perf_evlist, extra_events.buf, &parse_error); if (ret) { parse_events_print_error(&parse_error, extra_events.buf); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 6d18ff9bce49..28fa6ec7d2a2 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -189,12 +189,29 @@ void parse_events__handle_error(struct parse_events_error *err, int idx, free(help); return; } - WARN_ONCE(err->str, "WARNING: multiple event parsing errors\n"); - err->idx = idx; - free(err->str); - err->str = str; - free(err->help); - err->help = help; + switch (err->num_errors) { + case 0: + err->idx = idx; + err->str = str; + err->help = help; + break; + case 1: + err->first_idx = err->idx; + err->idx = idx; + err->first_str = err->str; + err->str = str; + err->first_help = err->help; + err->help = help; + break; + default: + WARN_ONCE(1, "WARNING: multiple event parsing errors\n"); + free(err->str); + err->str = str; + free(err->help); + err->help = help; + break; + } + err->num_errors++; } struct tracepoint_path *tracepoint_id_to_path(u64 config) @@ -2007,15 +2024,14 @@ static int get_term_width(void) return ws.ws_col > MAX_WIDTH ? MAX_WIDTH : ws.ws_col; } -void parse_events_print_error(struct parse_events_error *err, - const char *event) +static void __parse_events_print_error(int err_idx, const char *err_str, + const char *err_help, const char *event) { const char *str = "invalid or unsupported event: "; char _buf[MAX_WIDTH]; char *buf = (char *) event; int idx = 0; - - if (err->str) { + if (err_str) { /* -2 for extra '' in the final fprintf */ int width = get_term_width() - 2; int len_event = strlen(event); @@ -2038,8 +2054,8 @@ void parse_events_print_error(struct parse_events_error *err, buf = _buf; /* We're cutting from the beginning. */ - if (err->idx > max_err_idx) - cut = err->idx - max_err_idx; + if (err_idx > max_err_idx) + cut = err_idx - max_err_idx; strncpy(buf, event + cut, max_len); @@ -2052,16 +2068,33 @@ void parse_events_print_error(struct parse_events_error *err, buf[max_len] = 0; } - idx = len_str + err->idx - cut; + idx = len_str + err_idx - cut; } fprintf(stderr, "%s'%s'\n", str, buf); if (idx) { - fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err->str); - if (err->help) - fprintf(stderr, "\n%s\n", err->help); - zfree(&err->str); - zfree(&err->help); + fprintf(stderr, "%*s\\___ %s\n", idx + 1, "", err_str); + if (err_help) + fprintf(stderr, "\n%s\n", err_help); + } +} + +void parse_events_print_error(struct parse_events_error *err, + const char *event) +{ + if (!err->num_errors) + return; + + __parse_events_print_error(err->idx, err->str, err->help, event); + zfree(&err->str); + zfree(&err->help); + + if (err->num_errors > 1) { + fputs("\nInitial error:\n", stderr); + __parse_events_print_error(err->first_idx, err->first_str, + err->first_help, event); + zfree(&err->first_str); + zfree(&err->first_help); } } @@ -2071,7 +2104,9 @@ int parse_events_option(const struct option *opt, const char *str, int unset __maybe_unused) { struct evlist *evlist = *(struct evlist **)opt->value; - struct parse_events_error err = { .idx = 0, }; + struct parse_events_error err; + + bzero(&err, sizeof(err)); int ret = parse_events(evlist, str, &err); if (ret) { diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 5ee8ac93840c..ff367f248fe8 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -110,9 +110,13 @@ struct parse_events_term { }; struct parse_events_error { + int num_errors; /* number of errors encountered */ int idx; /* index in the parsed string */ char *str; /* string to display at the index */ char *help; /* optional help string */ + int first_idx;/* as above, but for the first encountered error */ + char *first_str; + char *first_help; }; struct parse_events_state {