From patchwork Thu Nov 7 22:14:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191471 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="CKVDolWA"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478Hm04TW5z9sNH for ; Fri, 8 Nov 2019 09:15:44 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728340AbfKGWPn (ORCPT ); Thu, 7 Nov 2019 17:15:43 -0500 Received: from mail-pg1-f201.google.com ([209.85.215.201]:50924 "EHLO mail-pg1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727552AbfKGWOr (ORCPT ); Thu, 7 Nov 2019 17:14:47 -0500 Received: by mail-pg1-f201.google.com with SMTP id u197so2976543pgc.17 for ; Thu, 07 Nov 2019 14:14:44 -0800 (PST) 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=MhcLOxBt6GI4murNgPPZOQuJK8208fS1NR4UI6STB1U=; b=CKVDolWA+p3kkfPghwMaEeouiOr9zIFkoe4xVjnEevFStVKit+6ivCMCZpn4+mfibV LBrc+ynSi8RG2wAqe1GeNVe96B+wVnTT+eiCsCYcaiA7T0bKC8PHdsK5Unm2VVw1GrfN D4kNTjhdBXaJtrvyRElDYLf6P75BF4VahAnxwL2Qtfvs+7hqjCIN5k18gJv7NIkPRn22 r0raai/f0pY9TuHkx7j87N5iAIFKEhJAgP0Oh2Yj4iLmw/pbXuXZ85j+M7dKtaD6BhGZ tblk/U98we9bZTJrGFxUvL0dBZ0+hyg0wQp8pdBZXiEkMI2nbdpeRRqQhAj/3Z1y5htJ VkFg== 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=MhcLOxBt6GI4murNgPPZOQuJK8208fS1NR4UI6STB1U=; b=AWNnuIVUXnOxWOh5Q/gon8tpKPS/0Xr3kGre2YVw4xzYGUC7YZ170m/X+89F8BVAx6 RZh8nUXU+8i/E8+W0BrRutA+x32el5nVl8BYtbK5ytVWg9iWrFML5d+8cUj00N0reivN aCuy6uA3H2snUx28h5PH4I3mLW+pMpy34c56cWVNGE+d5Jv/ozwhNj0TXBD3nvtivVZv 48/YPnNH0+Iqop1sOl2E0eaLpicHrjll645sKqtEIwA7AIsaclwcdBYO8hBx0tZzAsWx gv3Hmr4yQLgsrp581QiL6+ppnv4a/ISU/JGl/cxPQvnPT9RLYLa/9/OoDMx5e0GBHEj+ E0mA== X-Gm-Message-State: APjAAAU3FgG5CDSxsXweyKgwkw+zcXqjsENVzRW5snIBHGap+08hONq7 pCpjjm4NhPZTHoIzTERX8M2/MNQst6ab X-Google-Smtp-Source: APXvYqxvZGbe/BmZIh/v10T741ET9dsJbeZX59ttedPmjzAJjSdkfqS8GpkPXwOnI/m6fEPPs2AF/3CAZPBk X-Received: by 2002:a63:4501:: with SMTP id s1mr7500493pga.5.1573164884254; Thu, 07 Nov 2019 14:14:44 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:19 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-2-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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 --- 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 Thu Nov 7 22:14:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191469 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="L1HDYXFy"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478Hlx3Llsz9sNH for ; Fri, 8 Nov 2019 09:15:41 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728051AbfKGWPk (ORCPT ); Thu, 7 Nov 2019 17:15:40 -0500 Received: from mail-pl1-f202.google.com ([209.85.214.202]:42777 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727569AbfKGWOr (ORCPT ); Thu, 7 Nov 2019 17:14:47 -0500 Received: by mail-pl1-f202.google.com with SMTP id 30so2692005plb.9 for ; Thu, 07 Nov 2019 14:14:47 -0800 (PST) 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=m81bmWQIede8mLR77rYb7ggK23+bOyTQ3+K/+A1s3nA=; b=L1HDYXFyI+X5PobsFN/FPH+2bt0tfUFEbEQJ+g3qnfDiFnK3PzVP1zgk1lbsSGOGcp Vd6LdVqmuB2+7CaiPJ9ojCFt/mdYxgF3MYybVrZspbkYFDi/WQI1hj/6/k9Z9p+W/wrt h1EpvleRM0jHKycshNoCeMovjN3ZBt8qCB+aVokQEPYJQV1rPMd6Sd+OU39IpDXcoLpx GXEFjH5YuckMoe0R7qjnNU0hmmF2KPgajri34SVaS1RyRp+2qvESzOOjFpR2oOlFaeqm mw01ZvDuxMuLz6H9UyEESWEBk2bNtMAz0fQNlBTUzWs0CM84X2vDTypATTGqovTIwvgr fLLQ== 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=m81bmWQIede8mLR77rYb7ggK23+bOyTQ3+K/+A1s3nA=; b=GFBediNxOEGV+Ch5uLMNuNu5YdY55h3io77A+/50fP6ac8Jo3cuwyDxF+dKRJ4obHF ZE8zekNa7nikXJWTpwq43tAkqritkuhhlIvR7dKNBn/1Ur9liJkKEboV33Kfwr0f/pls NCwxkn/4P7WubiYIC63NuP1TLOT2h2cnEI3nmWKe9MONcKWU16ceSyETDrZffPE7ZGb9 mpIWN6foVUK+S3o+FdshtBDDqrYZSvBLr47ObGgwbYqLIiYRN8Yzh3Vvb57jC0L4Ivx0 a7pSCMJxdAT4xmPMcTeaI0r1y9sKoPrsAHT2jD+W7dl+03DN75kYVLodeddbRiphwALu 7LyQ== X-Gm-Message-State: APjAAAUHF2kQLFvP4v8v0htL72gSuRcik6a8rH0pDlCu2CDCg5JGG3IH 0U1diZob2kZ/hG9arzhLlyR+cxef2bKI X-Google-Smtp-Source: APXvYqwIJiy2yID3VUzf36XPK8qZxgKmrgyFdnOr9x8K1MC5yoQIK7vJGxRgbmzzAr6dY2IDvvn8X4Bt/c5e X-Received: by 2002:a63:495b:: with SMTP id y27mr7487764pgk.438.1573164886774; Thu, 07 Nov 2019 14:14:46 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:20 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-3-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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 Thu Nov 7 22:14:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191465 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="bgQrPYHr"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478Hlq2kv0z9sPV for ; Fri, 8 Nov 2019 09:15:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727693AbfKGWOw (ORCPT ); Thu, 7 Nov 2019 17:14:52 -0500 Received: from mail-vk1-f201.google.com ([209.85.221.201]:42100 "EHLO mail-vk1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727582AbfKGWOv (ORCPT ); Thu, 7 Nov 2019 17:14:51 -0500 Received: by mail-vk1-f201.google.com with SMTP id t128so1782419vkb.9 for ; Thu, 07 Nov 2019 14:14:50 -0800 (PST) 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=Rdpklo87Cbnc0oQfbWbjnhJvVaMXzhYZMl0FgWRkGnU=; b=bgQrPYHrhKXSpGUFfX1LxbonrqWUext52v0flekqJvgvBguDLpbp7reGofJVCdC7L2 sM9MVXS9NETEurVbRr9UwLAfRlvw1WbnPDrdUhAcu6LJGt9HjxXnfprHm0rQZJjcAvMN OwHpTc6tGw5jyc4qsD2ealU5qtUpgLNpsbA5jfyHez4U0BbtI22f9ClSfu0kpcpAK+V0 Urq2Icc2Aa7LcZHTUzxVLQKaL2ZCZlA5DRTK8E9k9ucVLhyzEIfdICSTaj3QT9+j15ci 0s8eBcbDUjjXXt2x++C66Irs9zA8jOHuNYxE/raWoL68J7lx+t5+Fk9jxWZJliCStVjU ueIA== 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=Rdpklo87Cbnc0oQfbWbjnhJvVaMXzhYZMl0FgWRkGnU=; b=Wqrtjps1EfNbtGKVpnCRqzo+YXK2srdZtZIS2wCPLsvcHeEk7LECdape4j41WSxowp TlrAP7NRcmutpCtU7YBa+TVKTIdVGIIuPxxOdCPgrlhi98bJTEa6NRta1iJH2pyPgpnB 9k88nJamWgUy+Uy2xYbyfB5c86prAwY1pLXfrch6oz5EHnNxvMkBAY6OPO+aFvtAv9Cn N75z7HW54YwByYGJqHlZb8W9AjwLHmjdmKm82Ei165qqfUkxK78a4J4DLxUWqblddK/8 kb9i0tCy3Tw+9TPICJIc0o0OC8/aDAeRU/VrQrPb4hDzavXo3ijSaHLJLW+oVJAaxm9B qqhg== X-Gm-Message-State: APjAAAWXn40rMHIRmh7YRzrhh/qzi3lyhWlfJmUxifew46yzazJz/HNw fqurhykfOACzSgjvruTquNfkd8Y29o5p X-Google-Smtp-Source: APXvYqz5bNeOCzhT6Gi4ljfOAEEIKtiXk1Y/E29tiX0hIVNxqvj2G3LdSuVpD0YdwTVjUVgXfD7RJRp4RMQ2 X-Received: by 2002:ab0:63:: with SMTP id 90mr4121250uai.91.1573164889634; Thu, 07 Nov 2019 14:14:49 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:21 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-4-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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 Thu Nov 7 22:14:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191462 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="mKKIHHcP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478Hlm1ZRGz9sNH for ; Fri, 8 Nov 2019 09:15:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727751AbfKGWOy (ORCPT ); Thu, 7 Nov 2019 17:14:54 -0500 Received: from mail-pl1-f201.google.com ([209.85.214.201]:47927 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727720AbfKGWOx (ORCPT ); Thu, 7 Nov 2019 17:14:53 -0500 Received: by mail-pl1-f201.google.com with SMTP id v2so2675593plp.14 for ; Thu, 07 Nov 2019 14:14:53 -0800 (PST) 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=o8eDtK4XLT1yB0wxfi9aIxQpXeS3/ycmioxd58yIuN4=; b=mKKIHHcPsVgAONMoZXSGtLwt9SP+tD9wXU5Rr4ErMd4qk25xxGHIDhu0/Qj6blDSXu vw8yk435k0zSoO7r85MUWnIiDGrJKFGdKDK82Jw7m6NySbCo1Vauj2i4miFVTQu63CO2 lA2NNfwcoNrNMgMCR2EJDl6GnmqjppeRJr8OGLkbz4E3cUhsSmX7F6VsUKv6g416lBld ejPPz9FG0oGRPSlxptOA762PUJY1ysICvSgHASLoYEhjd4BKZ04jbyyLmhEgBxGvpZsR VTQmYTQpApuWnvWKLmyzGmGQ6t5rq1PWRG9ioiWslfV5INFn/whzTGswzoaPdX9PRlzp 1VWA== 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=o8eDtK4XLT1yB0wxfi9aIxQpXeS3/ycmioxd58yIuN4=; b=pWl8R0+E3Oz+1SmuMzcpB4BWnJAhOGviCKd6zBhZD9IKW/F+6FZl6CPOdL36wWp9jN W2WS2lRnD3u4KWpz3BVSEcIjJ1IOzDlOe5E2LAyspCk7v+bpPh82by1vyn0pltGRtbaw hU40B40OW5Bf6w9NArWS3cFbocY+NUiz5MVqHq4UeUcSxMFItiiHODUqgm64vBbvXAeu sHBD7ozl9uz736ctslr0himRalnYUhCgFzDUHKA2cBa9PSHI1to0H+/yw9+yeorkqV6z fnUcsPKY85rvLYWWmb9v5uncwUrvgyCA/wrA+s5tu2RnmFkB1NPv/7/GhMJ8OwMtxBGB kT8A== X-Gm-Message-State: APjAAAXzaaz8gNYTiHD5HOoo6lKQAufxOhbhenFr205CnHQNGsqvqu7r ZDtmNOoAnNZKSQNp8ybBhL2XStnWPGj1 X-Google-Smtp-Source: APXvYqwJ8VuG9hRWejetPkhG8pMOZtZDUOZmAuU7dpgY1u7aUXH4GS+ccoeO9Va6IB9QTmImhuarKgMRCuzR X-Received: by 2002:a63:2b84:: with SMTP id r126mr7381052pgr.77.1573164892310; Thu, 07 Nov 2019 14:14:52 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:22 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-5-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@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 Thu Nov 7 22:14:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191461 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="VEe+Gbab"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478Hlk2xWXz9sNH for ; Fri, 8 Nov 2019 09:15:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727827AbfKGWO5 (ORCPT ); Thu, 7 Nov 2019 17:14:57 -0500 Received: from mail-pf1-f201.google.com ([209.85.210.201]:55874 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727794AbfKGWO4 (ORCPT ); Thu, 7 Nov 2019 17:14:56 -0500 Received: by mail-pf1-f201.google.com with SMTP id u21so2978308pfm.22 for ; Thu, 07 Nov 2019 14:14:55 -0800 (PST) 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=TexSPagk/qPWLXB1RzSvRc/jlf08CXbHxdJXlTnMvco=; b=VEe+GbabvUQUCGQjQ0cFSPK/EMivJNfRV8phevAWwMQiHTIm2czJ1ctKmXYBOuDc3O JOUu0hFanG4X8lhfg5uBa19ZrBwMD1xEkqHTxrUZRnKopNnWYlhDqtyUhDrsU3V8Jlif ixU1rD365kH+9baQvNinFjVOn+lqaiiZsBCHLAtvnJlmLSlFW6/OpArU38Ngz+zbdl61 R0G/pnr/irlpLi70s/RVye6iOH0QTON41Qieru+j0XVJIGVU7kMmmjXQp77/HNWKtlRe BHq22/7qwzfeDKwmJPwGJRls0aJYCz9pWXPUMBPf165vVxtVomm2TRTKCxvSjN0Nw1qt f0FQ== 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=TexSPagk/qPWLXB1RzSvRc/jlf08CXbHxdJXlTnMvco=; b=SSrwCiOou9wFoSbIEdRXejpAX1Rk6P7RojSLA+wdkQlOIqxguwEiMMoND0VEU0JHtV Iaa7Hc9iYCM5OtEDGeJS5kLjrC3Cl1liBnZOhttJ2aqOVJUQYYLqXh/5jlhjdtmpWyHn Qu3n12cEJrKNj0NvQeb0t2bbzOcts2pcKs6Qi1CKWfBYemukFE6EvpLiG479pvg24pxs rrtrTZZZPKk68wXT5u+2wjwf6dqTrJ4UkTtYmwO4wvI4bciTxBd1SFlXG6Vj70XNrpYQ 68W0eL5Fcw+F6l4HRdj3TKGnog5NowlXoHiwKs06EMdh8WutoPGniP7vSjs2ke/Zr95E DMvQ== X-Gm-Message-State: APjAAAVBBIPhXW9SDIadluF4qsRQEzweuQlTjRmHwOmg5gVbfjP0vWjr e4kPkKeALHRYdZqv/AMvVKPYuYsBku1H X-Google-Smtp-Source: APXvYqyG8V+eCsVX20ca+Wic+DKWJe5wpasiGhn90ZTqB0FeX9VNDqtcpQKogQ000xsOdPfwYhAuYfersV6L X-Received: by 2002:a63:eb47:: with SMTP id b7mr7374005pgk.179.1573164894908; Thu, 07 Nov 2019 14:14:54 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:23 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-6-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@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 --- 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 Thu Nov 7 22:14:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191451 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="dDOQDYZG"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478HlD2jXLz9sQp for ; Fri, 8 Nov 2019 09:15:04 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727932AbfKGWPA (ORCPT ); Thu, 7 Nov 2019 17:15:00 -0500 Received: from mail-pl1-f202.google.com ([209.85.214.202]:48824 "EHLO mail-pl1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727872AbfKGWO6 (ORCPT ); Thu, 7 Nov 2019 17:14:58 -0500 Received: by mail-pl1-f202.google.com with SMTP id t5so2678266plz.15 for ; Thu, 07 Nov 2019 14:14:58 -0800 (PST) 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=GYsTOK8xYRxAzUxpL4TGFf0MCdaNxbX2unbIlv+2Rhk=; b=dDOQDYZGFPLwMGpwr2hhtnIpsHI7U4swqrRNpgAChvbsTVUGuZPenhcLJdGAIc11Du DVf7vUNvjhCLem50JEixRT600aTgf98lEkkLCaALXfUBeIYBf6sgHo1oSZ+2hrnRpkc6 EMEEi/i4dirlukS8+KCZaJqiKWTBwj4TEGn+0QA/YsNAr+POQ3RUWEiIPDxO+D8C8JZf hY6QUp463dJe29T/Ae5hJYc2Pj1ESimAza8tUSUoDcSAs55MGI0ibtBwtCmud6t4P09V W1TTT1MH4ITFTBziDbFKaLQIuoq92ICWKXYtDZUVdZIcSUZ7xnxYefMSp+a81J+l9ahW oc0w== 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=GYsTOK8xYRxAzUxpL4TGFf0MCdaNxbX2unbIlv+2Rhk=; b=NSun83HbWXnI5BShLiUSYM4Ug8OqcyxMFLIlVRGfcm/bXWqxZT+DlgMJQmvOYoDK9C hR5Cea8De8oXrkIC2iuUTtfYDnEZIDpZCQzGPy8wkwAdm9oxWqalp5t91MsYDKCDTDnV i497/akJCacM/sHPevhhhSZfY3VMm+BhzQAUPmjkYpIMs6Gnfon+yYtfkeLwkvGeOZ3R d/ySY8g3LzO7q8/mTawzy9mv7aq90HKhsQDGkpJmpIZZAOEiVZCWtMGjoLwNQ3IoJ0Ym PnhUzmQA9jNrALiPMb5udkMyxTLmRbtGuP+MHxhV94xnk4RhxpLzFY9DDuJcvWYK/Svt QLpg== X-Gm-Message-State: APjAAAVHIgIi3AohmXMXsPIeAQd8sB7iunXGrN4dIbFCFM+03xzIK412 Dizka+ZS/S2R2DRuP+zIozkB6Od3jfN1 X-Google-Smtp-Source: APXvYqyHnBkfFWSvF0SsHBpO7tRDjCvzidF9DaLZPcJPFcMSsf6lwjqg8g/em4GcJRBz9bO384nwjQLs08WO X-Received: by 2002:a63:f513:: with SMTP id w19mr7443214pgh.55.1573164897568; Thu, 07 Nov 2019 14:14:57 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:24 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-7-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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 --- 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 Thu Nov 7 22:14:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191452 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="fctkl74i"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478HlF61HJz9sPL for ; Fri, 8 Nov 2019 09:15:05 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728015AbfKGWPE (ORCPT ); Thu, 7 Nov 2019 17:15:04 -0500 Received: from mail-pg1-f202.google.com ([209.85.215.202]:50935 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727949AbfKGWPB (ORCPT ); Thu, 7 Nov 2019 17:15:01 -0500 Received: by mail-pg1-f202.google.com with SMTP id u197so2977103pgc.17 for ; Thu, 07 Nov 2019 14:15:01 -0800 (PST) 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=laQc1zyWbEvcb3m/Ga9I37nMi3ijv6X82hzmHQHwiLk=; b=fctkl74iJXHIkr9kY6ZydG2QxV80SlcKHzi2U4JxyHGJXTFC8h1rhuVW/PkAMEq0Q8 +yiIxUlanVfis5pOQivmSDEbUsWffa8Z+eEO9SU1IGWuXjvPQmWh6swfgCaNVgwn7EAF 3qkS/VwX+WeW5r2HhK8iKUwyojR08VCDkAQPT+A8JlMRmWNyRzB42o3necLvWG62RXLP +8M40zyO10aCfROSQdSUuSpJfU4x7SYfXe/XzOCHrjVPDjoGqcEa1XjMUt49ukO3xbg8 QB7zcc53YcEj0vAHXx1zVoR1w3sNQRpK+rFShTvdWtLWtachKErhTVq96dFQmcg9SBkd jbTg== 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=laQc1zyWbEvcb3m/Ga9I37nMi3ijv6X82hzmHQHwiLk=; b=PIkASBDcVF73ThxHgTRTSExKhyEjKMyG7eQglTU7btJ11UbVZNyzNe4XqWGKZ1kmHO s4sp35DmP/pxMo+v37HGExrXJUOXcBGMUttv7hX3Wq6BhY4jfK9D1Psg1F+PyDAK1rlY QGcsyNR0juB2t/pgStEOXcwjb3ufAhEZSp8iPlPblh8BI1MVH82IBdm1TXeHkmXhs0g9 HUz9jnylUBRbNd7paT62YgzQY4RKYFTRsnn0zz6UzxraImG5MstoTzsd0Q6SSlHk7JxB MNftqB6ouz0x68whWmj9XkuyQkYNKZkZ9S26IMj5XYokBJsNOXmS/b7IwZugYADMM59l aQqA== X-Gm-Message-State: APjAAAWo2hzhU34d/pzAqfgH9CivbfN4toQS+pOxmjRnx+sNafGpYl0u KWilWPONPUvVh36cG2RcXNDk7R7h1zrT X-Google-Smtp-Source: APXvYqx+DuLyMI4yoiaDMo8sILh/BtZxSwnNm3wqk9gFxnBhkeDrs/RcPdSUyCiUITXaCJsPn22sT1cqFQZK X-Received: by 2002:a63:7247:: with SMTP id c7mr7556097pgn.311.1573164900492; Thu, 07 Nov 2019 14:15:00 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:25 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-8-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Yyabort doesn't destruct inputs and so this must be done manually before using yyabort. Signed-off-by: Ian Rogers --- 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 Thu Nov 7 22:14:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191453 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="jrQORgPz"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478HlK6PyFz9sPL for ; Fri, 8 Nov 2019 09:15:09 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728080AbfKGWPG (ORCPT ); Thu, 7 Nov 2019 17:15:06 -0500 Received: from mail-pl1-f201.google.com ([209.85.214.201]:39696 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728041AbfKGWPF (ORCPT ); Thu, 7 Nov 2019 17:15:05 -0500 Received: by mail-pl1-f201.google.com with SMTP id w11so2696596ply.6 for ; Thu, 07 Nov 2019 14:15:04 -0800 (PST) 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=AdCqemr3Cpf7H//3sUI2jx4nwjMA/tcTnOzbDM/nvC0=; b=jrQORgPzeZELMCAxvGhKK+LNKIHx0lR7EPWzROuGYaZ+8MQcE47ixHonnM93zYy6Bb nqX5lHMzBwuMZf0i1kUDabzHy8kdEY46PjxcAApEcS91vHsUB6MfoINBzDy2G4B5wHaR HoXGNztVqF4MNmFNLonRL2ICkbGLFEhkXxnmnsKhAZyejQg+RxxIiKY7wNzIIewoeyCq THAE+F2X5AyEIIUIWWoU8vmV7zRhdAMlzpBlaCPqBwkFWjmJdNttL/Tlsua/9W6NL0JO f51/JAkOljq+y3t/Fd5eL9Rf/ZbXtyvMoyjb0iBJ/vFzTQOG4qe1MRJAyPoRNrzWYIp5 rs2A== 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=AdCqemr3Cpf7H//3sUI2jx4nwjMA/tcTnOzbDM/nvC0=; b=aCmrWW52S1RysQYCjmMW/xhZtCsA8KRQP4jj0/u5gndWv2ixSvt/y0iNm7Xwf3CeFH hAW+/qwzesr5oJdGstFZso+BNAQL9GVBg+/jFgoqwXkLbP7bH9RWzXvaJWnBp7F4KQ+b 3lfo3GTMVLymf86G7Deo6oNrQDT2lpzguDfZWNwG4qc6ls73mSo4ZptOIKSgpL9U9Siw LxwK8mn1nywHyi/RcDrAG7X6cnX6vi/NZL7qvgdCOCOfCRCGjki+YpTdATmQ2tQk+M10 ITiCQDVKwXL9/FnRHqTlQ/QVvJ5HA0lLYH/bck3VAFOjgqzaQpdBbrW1riGMyXvDCFBS KN1A== X-Gm-Message-State: APjAAAU9/ZremOJKmKyGOIqFHbg36P+Qdt0fOMusmYRVL9QYMwb6knE7 qAm7djenWtRtbL0ZG9g6G4k1tNlJzHW7 X-Google-Smtp-Source: APXvYqz/rkI814x4MOw4cAa7e4QfcUS64HmMtxPkZptIuD8Y+rQW1uOQ0spijoWFfSm8En8eJae60a5ns/vv X-Received: by 2002:a63:5848:: with SMTP id i8mr7445484pgm.217.1573164903292; Thu, 07 Nov 2019 14:15:03 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:26 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-9-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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: bpf-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org Avoid a memory leak when the configuration fails. Signed-off-by: Ian Rogers --- 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 Thu Nov 7 22:14:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191454 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="J9/+NcEb"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478HlL365gz9sR3 for ; Fri, 8 Nov 2019 09:15:10 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728124AbfKGWPJ (ORCPT ); Thu, 7 Nov 2019 17:15:09 -0500 Received: from mail-pl1-f201.google.com ([209.85.214.201]:43978 "EHLO mail-pl1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728097AbfKGWPJ (ORCPT ); Thu, 7 Nov 2019 17:15:09 -0500 Received: by mail-pl1-f201.google.com with SMTP id a3so2685344pls.10 for ; Thu, 07 Nov 2019 14:15:06 -0800 (PST) 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=RO+dD7fMF+loxfMI95W5obH94+g4tEmZJjELHIr1A/8=; b=J9/+NcEb0Kb22BIyBkNY+7VwZg9woXWFrvaMZFXW85+MhBiG237bWw1U0ZhvE8xkuN bNr2VuzYW+ew5V5jklCSScPNQjj70HUYaNX8L4d1UOyOS0g+EOxIYN6j3Re58QUUV8eP teu7dwsBfLX+xYzJRCUGzwrFeFcSffK/OhTTPV2bH6SUYxP/nKt9618kzrRIexYrJH2E UjU7ID9nyDhDZrFQzuM2pAtcOUe3P77rJUO3GsKLVlEG2HU1kJRY1fTfN4a8ZljQPCaD ZKR0Mp34IE519REzY3ql2LBG1nqaEsrkMQ2kD+scZReMhb7bk63w6wXeYNr0R+LxdzIV uRSg== 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=RO+dD7fMF+loxfMI95W5obH94+g4tEmZJjELHIr1A/8=; b=qOB3LzHRNuCV8vw5By5T0kxB1F9aaiEK6oIUm79sYTThVksPwfAMOctY1k+FuQebhs VTSwh4EVpOk1Buz7Jd0dbYanx24JMg2fTCeQ05oMo0ul/cBnIE7NHVxjBjkDntJ42shu bBy6Ez9efWkm03EKdCabputyzwkYwRV/qgxE0ppgq1KDqHCzAcX50EMNMJSguBXWGnOX 38shhFyI8O8DTL/mThRHwe91sxP5EODnmeidl/Zm08kRbVSaokQF9m9vo7uZEVVgS09o OA1CQavh2NeNhsk2ql/lA9925cjlF+wxZUff2J1+cIFPSijdafwO2MtxEom/1ZRQJjyA t11A== X-Gm-Message-State: APjAAAUEfKFgS7zhyilAvoc5pGiVbnWJqlAiEP/W/IV5U9ymIeZTz2oo T2Woyu1l68+m5lGSu9YrSky9s7GBF5NI X-Google-Smtp-Source: APXvYqybHLhQQANdsiyCaIR+0YTtQxwGzUhA+4YkjjUdck1HuzvRr+BhLHgukin1TNbdrakC56GGGTV+97Wd X-Received: by 2002:a65:624e:: with SMTP id q14mr7431914pgv.277.1573164905944; Thu, 07 Nov 2019 14:15:05 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:27 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-10-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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 --- 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 Thu Nov 7 22:14:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Rogers X-Patchwork-Id: 1191455 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="Yd0hw8vR"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 478HlN4Mpzz9sPL for ; Fri, 8 Nov 2019 09:15:12 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728191AbfKGWPL (ORCPT ); Thu, 7 Nov 2019 17:15:11 -0500 Received: from mail-pf1-f201.google.com ([209.85.210.201]:48640 "EHLO mail-pf1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728014AbfKGWPK (ORCPT ); Thu, 7 Nov 2019 17:15:10 -0500 Received: by mail-pf1-f201.google.com with SMTP id g186so2986760pfb.15 for ; Thu, 07 Nov 2019 14:15:09 -0800 (PST) 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=58/NaSHItT1fO9PMDMiALzFSxZk8aT8VSBXqv52dueM=; b=Yd0hw8vRIYCK3xrTh6HpFfXYURPjTfAmquZwrAzXMqIFEeHF3JHXuyQd9bDd/SajzS 6/BGHoB2Vvel1DEz13um+Ohzm+t8zRqDSh/atvC7vfPVNzO4ETZKogRZ5BOJaTrN+X9a 52daU3WmjjoU2h2TzJ9P6TGWe+lnZaF/HiFrTNVrqntHCSBDU3BTOYg8+jAJs0X+YJKk xJhfS9ZGuhEBNIVoqL4GBAICQH2GwVC0prwc+TXt2P69GnQrCSfXBG4j0f0DxdTf1MgN pDRExCSgXOSjFWwNDr08Ljjnl7N3N4YTVklhs+6GTq1JHXPJu1Z4CNkDoWpxlpBG9+yZ 5CKg== 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=58/NaSHItT1fO9PMDMiALzFSxZk8aT8VSBXqv52dueM=; b=JvwDlHOdLWCEYpV2FrziiW1+0rGtQDJ5Fj1AoMhSfqkE7uOAaijB9lTn9/ve06meuJ S1wJ50PFtlFtlkWBeiY9PLj0vY0p1wWH2JWR71SS/8UWn3a0hWwCmCRLJwBGNKWh7qrr dC4kut7mo5aqu8mXXf5eAvDN3XNS2vDka0Z/Z9kfLQU58GYrNfF+Mqh8ShwC559FDqo5 5hhG+3dybfAdQXIWMPwqTTeHVsaifohEz9xQL5kq30+Kl7ekuPFcNSXYoRObbeCr+jB9 i67xYi4DHQja1/MFj08oEQXNCD3iBn9mU3VExctFCr5QsK+eKiEZfpd2GoCeWVf2SCi0 O1CQ== X-Gm-Message-State: APjAAAWSaPskpNQBfCbtZAOilRjURdY/eW9FmEXAelNZcZ9xtSoxcQw9 X89hs4fAr8UOIetu97hPLPeQfmhVYpCs X-Google-Smtp-Source: APXvYqwNPIMGJVGrXcXttxXCL/rQ5ozqp/bDb24kBoxPC2Uu+DW047GG5SW8l1D8GGT/HYHi7v097gKKuWsU X-Received: by 2002:a63:1065:: with SMTP id 37mr7439170pgq.31.1573164908712; Thu, 07 Nov 2019 14:15:08 -0800 (PST) Date: Thu, 7 Nov 2019 14:14:28 -0800 In-Reply-To: <20191107221428.168286-1-irogers@google.com> Message-Id: <20191107221428.168286-11-irogers@google.com> Mime-Version: 1.0 References: <20191030223448.12930-1-irogers@google.com> <20191107221428.168286-1-irogers@google.com> X-Mailer: git-send-email 2.24.0.432.g9d3f5f5b63-goog Subject: [PATCH v6 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: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@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 | 76 ++++++++++++++++++------- tools/perf/util/parse-events.h | 4 ++ 7 files changed, 84 insertions(+), 28 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..a369bbc289b2 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,8 +2104,11 @@ 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, }; - int ret = parse_events(evlist, str, &err); + struct parse_events_error err; + int ret; + + bzero(&err, sizeof(err)); + ret = parse_events(evlist, str, &err); if (ret) { parse_events_print_error(&err, str); 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 {