Messages in this thread | | | Date | Thu, 23 Jul 2015 17:35:24 -0400 | From | Steven Rostedt <> | Subject | Re: [RFC PATCH] tools lib traceevent: Allow setting an alternative symbol resolver |
| |
On Thu, 23 Jul 2015 18:25:36 -0300 Arnaldo Carvalho de Melo <acme@kernel.org> wrote:
> Like this?
Yep, but some comments.
> diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c > index cc25f059ab3d..7f9266225f11 100644 > --- a/tools/lib/traceevent/event-parse.c > +++ b/tools/lib/traceevent/event-parse.c > @@ -418,7 +418,7 @@ static int func_map_init(struct pevent *pevent) > } > > static struct func_map * > -find_func(struct pevent *pevent, unsigned long long addr) > +__find_func(struct pevent *pevent, unsigned long long addr) > { > struct func_map *func; > struct func_map key; > @@ -434,6 +434,60 @@ find_func(struct pevent *pevent, unsigned long long addr) > return func; > } > > +struct func_resolver { > + pevent_func_resolver_t *func; > + void *priv; > + struct func_map map; > +}; > + > +/** > + * pevent_set_function_resolver - set an alternative function resolver > + * @pevent: handle for the pevent > + * @resolver: function to be used > + * @priv: resolver function private state. > + * > + * Some tools may have already a way to resolve kernel functions, allow them to > + * keep using it instead of duplicating all the entries inside > + * pevent->funclist. > + */ > +int pevent_set_function_resolver(struct pevent *pevent, > + pevent_func_resolver_t *func, void *priv) > +{ > + struct func_resolver *resolver = malloc(sizeof(*resolver)); > + > + if (resolver == NULL) { > + errno = ENOMEM;
Why set errno, wont a failed malloc set it for us?
> + return -1; > + } > + > + resolver->func = func; > + resolver->priv = priv; > + > + free(pevent->func_resolver); > + pevent->func_resolver = resolver;
Also I wonder if we should add a way to clear the resolver. That is, you want to use the default resolver?
Not really a necessity, as I don't see any current programs using it, but it would complete the interface.
-- Steve
> + > + return 0; > +} > + > +static struct func_map * > +find_func(struct pevent *pevent, unsigned long long addr) > +{ > + struct func_map *map; > + > + if (!pevent->func_resolver) > + return __find_func(pevent, addr); > + > + map = &pevent->func_resolver->map; > + map->mod = NULL; > + map->addr = addr; > + map->func = pevent->func_resolver->func(pevent->func_resolver->priv, > + &map->addr, &map->mod); > + if (map->func == NULL) > + return NULL; > + > + return map; > +} > + > /** > * pevent_find_function - find a function by a given address > * @pevent: handle for the pevent > @@ -6564,6 +6618,7 @@ void pevent_free(struct pevent *pevent) > free(pevent->trace_clock); > free(pevent->events); > free(pevent->sort_events); > + free(pevent->func_resolver); > > free(pevent); > } > diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h > index 063b1971eb35..416e1bd9fe33 100644 > --- a/tools/lib/traceevent/event-parse.h > +++ b/tools/lib/traceevent/event-parse.h > @@ -453,6 +453,10 @@ struct cmdline_list; > struct func_map; > struct func_list; > struct event_handler; > +struct func_resolver; > + > +typedef char *(pevent_func_resolver_t)(void *priv, > + unsigned long long *addrp, char **modp); > > struct pevent { > int ref_count; > @@ -481,6 +485,7 @@ struct pevent { > int cmdline_count; > > struct func_map *func_map; > + struct func_resolver *func_resolver; > struct func_list *funclist; > unsigned int func_count; > > @@ -611,6 +616,8 @@ enum trace_flag_type { > TRACE_FLAG_SOFTIRQ = 0x10, > }; > > +int pevent_set_function_resolver(struct pevent *pevent, > + pevent_func_resolver_t *func, void *priv); > int pevent_register_comm(struct pevent *pevent, const char *comm, int pid); > int pevent_register_trace_clock(struct pevent *pevent, const char *trace_clock); > int pevent_register_function(struct pevent *pevent, char *name,
| |