diff options
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 117 |
1 files changed, 64 insertions, 53 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 198e09ff611e..eea132f512b0 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -1,22 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * probe-event.c : perf-probe definition to probe_events format converter * * Written by Masami Hiramatsu <mhiramat@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * */ #include <inttypes.h> @@ -33,18 +19,17 @@ #include <limits.h> #include <elf.h> -#include "util.h" +#include "build-id.h" #include "event.h" #include "namespaces.h" #include "strlist.h" #include "strfilter.h" #include "debug.h" -#include "cache.h" +#include "dso.h" #include "color.h" #include "map.h" -#include "map_groups.h" +#include "maps.h" #include "symbol.h" -#include "thread.h" #include <api/fs/fs.h> #include "trace-event.h" /* For __maybe_unused */ #include "probe-event.h" @@ -52,13 +37,16 @@ #include "probe-file.h" #include "session.h" #include "string2.h" +#include "strbuf.h" -#include "sane_ctype.h" +#include <subcmd/pager.h> +#include <linux/ctype.h> +#include <linux/zalloc.h> #define PERFPROBE_GROUP "probe" bool probe_event_dry_run; /* Dry run flag */ -struct probe_conf probe_conf; +struct probe_conf probe_conf = { .magic_num = DEFAULT_PROBE_MAGIC_NUM }; #define semantic_error(msg ...) pr_err("Semantic error :" msg) @@ -165,7 +153,7 @@ static struct map *kernel_get_module_map(const char *module) return map__get(pos); } - for (pos = maps__first(maps); pos; pos = map__next(pos)) { + maps__for_each_entry(maps, pos) { /* short_name is "[module]" */ if (strncmp(pos->dso->short_name + 1, module, pos->dso->short_name_len - 2) == 0 && @@ -228,9 +216,9 @@ out: static void clear_perf_probe_point(struct perf_probe_point *pp) { - free(pp->file); - free(pp->function); - free(pp->lazy_line); + zfree(&pp->file); + zfree(&pp->function); + zfree(&pp->lazy_line); } static void clear_probe_trace_events(struct probe_trace_event *tevs, int ntevs) @@ -333,7 +321,7 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) char module_name[128]; snprintf(module_name, sizeof(module_name), "[%s]", module); - map = map_groups__find_by_name(&host_machine->kmaps, module_name); + map = maps__find_by_name(&host_machine->kmaps, module_name); if (map) { dso = map->dso; goto found; @@ -1189,12 +1177,11 @@ int show_available_vars(struct perf_probe_event *pevs __maybe_unused, void line_range__clear(struct line_range *lr) { - free(lr->function); - free(lr->file); - free(lr->path); - free(lr->comp_dir); + zfree(&lr->function); + zfree(&lr->file); + zfree(&lr->path); + zfree(&lr->comp_dir); intlist__delete(lr->line_list); - memset(lr, 0, sizeof(*lr)); } int line_range__init(struct line_range *lr) @@ -1577,6 +1564,17 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg) str = tmp + 1; } + tmp = strchr(str, '@'); + if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */ + if (!user_access_is_supported()) { + semantic_error("ftrace does not support user access\n"); + return -EINVAL; + } + *tmp = '\0'; + arg->user_access = true; + pr_debug("user_access "); + } + tmp = strchr(str, ':'); if (tmp) { /* Type setting */ *tmp = '\0'; @@ -1681,6 +1679,14 @@ int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) if (ret < 0) goto out; + /* Generate event name if needed */ + if (!pev->event && pev->point.function && pev->point.line + && !pev->point.lazy_line && !pev->point.offset) { + if (asprintf(&pev->event, "%s_L%d", pev->point.function, + pev->point.line) < 0) + return -ENOMEM; + } + /* Copy arguments and ensure return probe has no C argument */ pev->nargs = argc - 1; pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); @@ -2217,15 +2223,15 @@ void clear_perf_probe_event(struct perf_probe_event *pev) struct perf_probe_arg_field *field, *next; int i; - free(pev->event); - free(pev->group); - free(pev->target); + zfree(&pev->event); + zfree(&pev->group); + zfree(&pev->target); clear_perf_probe_point(&pev->point); for (i = 0; i < pev->nargs; i++) { - free(pev->args[i].name); - free(pev->args[i].var); - free(pev->args[i].type); + zfree(&pev->args[i].name); + zfree(&pev->args[i].var); + zfree(&pev->args[i].type); field = pev->args[i].field; while (field) { next = field->next; @@ -2234,8 +2240,8 @@ void clear_perf_probe_event(struct perf_probe_event *pev) field = next; } } - free(pev->args); - memset(pev, 0, sizeof(*pev)); + pev->nargs = 0; + zfree(&pev->args); } #define strdup_or_goto(str, label) \ @@ -2316,15 +2322,15 @@ void clear_probe_trace_event(struct probe_trace_event *tev) struct probe_trace_arg_ref *ref, *next; int i; - free(tev->event); - free(tev->group); - free(tev->point.symbol); - free(tev->point.realname); - free(tev->point.module); + zfree(&tev->event); + zfree(&tev->group); + zfree(&tev->point.symbol); + zfree(&tev->point.realname); + zfree(&tev->point.module); for (i = 0; i < tev->nargs; i++) { - free(tev->args[i].name); - free(tev->args[i].value); - free(tev->args[i].type); + zfree(&tev->args[i].name); + zfree(&tev->args[i].value); + zfree(&tev->args[i].type); ref = tev->args[i].ref; while (ref) { next = ref->next; @@ -2332,8 +2338,8 @@ void clear_probe_trace_event(struct probe_trace_event *tev) ref = next; } } - free(tev->args); - memset(tev, 0, sizeof(*tev)); + zfree(&tev->args); + tev->nargs = 0; } struct kprobe_blacklist_node { @@ -2350,8 +2356,8 @@ static void kprobe_blacklist__delete(struct list_head *blacklist) while (!list_empty(blacklist)) { node = list_first_entry(blacklist, struct kprobe_blacklist_node, list); - list_del(&node->list); - free(node->symbol); + list_del_init(&node->list); + zfree(&node->symbol); free(node); } } @@ -2732,8 +2738,13 @@ static int probe_trace_event__set_name(struct probe_trace_event *tev, if (tev->event == NULL || tev->group == NULL) return -ENOMEM; - /* Add added event name to namelist */ - strlist__add(namelist, event); + /* + * Add new event name to namelist if multiprobe event is NOT + * supported, since we have to use new event name for following + * probes in that case. + */ + if (!multiprobe_event_is_supported()) + strlist__add(namelist, event); return 0; } |