On Tue, Oct 22, 2019 at 05:53:31PM -0700, Ian Rogers wrote: SNIP > 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++; > } > @@ -1462,8 +1472,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; > } > @@ -2761,13 +2773,13 @@ int parse_events_term__sym_hw(struct parse_events_term **term, > 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 ?: strdup("event"), there's no check if this succeeds > }; > > BUG_ON(idx >= PERF_COUNT_HW_MAX); > sym = &event_symbols_hw[idx]; > > - return new_term(term, &temp, (char *) sym->symbol, 0); > + return new_term(term, &temp, strdup(sym->symbol), 0); > } > > int parse_events_term__clone(struct parse_events_term **new, > @@ -2776,12 +2788,15 @@ int parse_events_term__clone(struct parse_events_term **new, > struct parse_events_term temp = { > .type_val = term->type_val, > .type_term = term->type_term, > - .config = term->config, > + .config = term->config ? strdup(term->config) : NULL, ditto also how is this released when term is freed? thanks, jirka