public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Wang Nan <wangnan0@huawei.com>
Cc: jolsa@redhat.com, masami.hiramatsu.pt@hitachi.com,
	namhyung@kernel.org, lizefan@huawei.com,
	linux-kernel@vger.kernel.org, pi3orama@163.com
Subject: Re: [PATCH] perf probe: Fix segfault when glob matching function without debuginfo
Date: Fri, 29 May 2015 10:34:00 -0300	[thread overview]
Message-ID: <20150529133400.GT24859@kernel.org> (raw)
In-Reply-To: <1432892747-232506-1-git-send-email-wangnan0@huawei.com>

Em Fri, May 29, 2015 at 09:45:47AM +0000, Wang Nan escreveu:
> Commit 4c859351226c920b227fec040a3b447f0d482af3 ("perf probe: Support
> glob wildcards for function name") introduces segfault problems when
> debuginfo is not available:
> 
>  # perf probe 'sys_w*'
>   Added new events:
>   Segmentation fault
> 
> The first problem resides in find_probe_trace_events_from_map(). In
> that function, find_probe_functions() is called to match each symbol
> against glob to find the number of matching functions, but still use
> map__for_each_symbol_by_name() to find 'struct symbol' for matching
> functions. Unfortunately, map__for_each_symbol_by_name() does
> exact matching by searching in an rbtree. It doesn't know glob
> matching, and not easy for it to support it because it use rbtree based
> binary search, but we are unable to ensure all names matched by the
> glob (any glob passed by user) reside in one subtree.
> 
> This patch drops map__for_each_symbol_by_name(). Since there is no
> rbtree again, re-matching all symbols costs a lot. This patch avoid it
> by saving all matching results into an array (syms).
> 
> The second problem is the lost of tp->realname. In
> __add_probe_trace_events(), if pev->point.function is glob, the event
> name should be set to tev->point.realname. This patch ensures its
> existence by strdup sym->name instead of leaving a NULL pointer there.
> 
> After this patch:
> 
>  # perf probe 'sys_w*'
>  Added new events:
>    probe:sys_waitid     (on sys_w*)

The second part looks strange :-\ Masami?

>    probe:sys_wait4      (on sys_w*)
>    probe:sys_waitpid    (on sys_w*)
>    probe:sys_write      (on sys_w*)
>    probe:sys_writev     (on sys_w*)
> 
>  You can now use it in all perf tools, such as:
> 
>          perf record -e probe:sys_writev -aR sleep 1
> 
> Signed-off-by: Wang Nan <wangnan0@huawei.com>
> ---
>  tools/perf/util/probe-event.c | 26 +++++++++++++++++++++-----
>  1 file changed, 21 insertions(+), 5 deletions(-)
> 
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 9052e7b..4f1bc78 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -2493,7 +2493,8 @@ close_out:
>  	return ret;
>  }
>  
> -static int find_probe_functions(struct map *map, char *name)
> +static int find_probe_functions(struct map *map, char *name,
> +				struct symbol **syms)
>  {
>  	int found = 0;
>  	struct symbol *sym;
> @@ -2503,8 +2504,11 @@ static int find_probe_functions(struct map *map, char *name)
>  		return 0;
>  
>  	map__for_each_symbol(map, sym, tmp) {
> -		if (strglobmatch(sym->name, name))
> +		if (strglobmatch(sym->name, name)) {
>  			found++;
> +			if (syms && found < probe_conf.max_probes)
> +				syms[found - 1] = sym;
> +		}
>  	}
>  
>  	return found;
> @@ -2527,11 +2531,12 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  	struct map *map = NULL;
>  	struct ref_reloc_sym *reloc_sym = NULL;
>  	struct symbol *sym;
> +	struct symbol **syms = NULL;
>  	struct probe_trace_event *tev;
>  	struct perf_probe_point *pp = &pev->point;
>  	struct probe_trace_point *tp;
>  	int num_matched_functions;
> -	int ret, i;
> +	int ret, i, j;
>  
>  	map = get_target_map(pev->target, pev->uprobes);
>  	if (!map) {
> @@ -2539,11 +2544,17 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  		goto out;
>  	}
>  
> +	syms = malloc(sizeof(struct symbol *) * probe_conf.max_probes);
> +	if (!syms) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
>  	/*
>  	 * Load matched symbols: Since the different local symbols may have
>  	 * same name but different addresses, this lists all the symbols.
>  	 */
> -	num_matched_functions = find_probe_functions(map, pp->function);
> +	num_matched_functions = find_probe_functions(map, pp->function, syms);
>  	if (num_matched_functions == 0) {
>  		pr_err("Failed to find symbol %s in %s\n", pp->function,
>  			pev->target ? : "kernel");
> @@ -2574,7 +2585,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  
>  	ret = 0;
>  
> -	map__for_each_symbol_by_name(map, pp->function, sym) {
> +	for (j = 0; j < num_matched_functions; j++) {
> +		sym = syms[j];
> +
>  		tev = (*tevs) + ret;
>  		tp = &tev->point;
>  		if (ret == num_matched_functions) {
> @@ -2598,6 +2611,8 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  			tp->symbol = strdup_or_goto(sym->name, nomem_out);
>  			tp->offset = pp->offset;
>  		}
> +		tp->realname = strdup_or_goto(sym->name, nomem_out);
> +
>  		tp->retprobe = pp->retprobe;
>  		if (pev->target)
>  			tev->point.module = strdup_or_goto(pev->target,
> @@ -2628,6 +2643,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
>  
>  out:
>  	put_target_map(map, pev->uprobes);
> +	free(syms);
>  	return ret;
>  
>  nomem_out:
> -- 
> 1.8.3.4

  reply	other threads:[~2015-05-29 13:34 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-29  9:45 [PATCH] perf probe: Fix segfault when glob matching function without debuginfo Wang Nan
2015-05-29 13:34 ` Arnaldo Carvalho de Melo [this message]
2015-05-29 23:10 ` Masami Hiramatsu
2015-06-04 14:10 ` [tip:perf/core] " tip-bot for Wang Nan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150529133400.GT24859@kernel.org \
    --to=acme@kernel.org \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=namhyung@kernel.org \
    --cc=pi3orama@163.com \
    --cc=wangnan0@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox