From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: "平松雅巳 / HIRAMATU,MASAMI" <masami.hiramatsu.pt@hitachi.com>
Cc: Ingo Molnar <mingo@kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
Wang Nan <wangnan0@huawei.com>,
Namhyung Kim <namhyung@kernel.org>,
"pi3orama@163.com" <pi3orama@163.com>
Subject: Re: [PATCH 16/16] perf probe: Support probing at absolute addresses
Date: Wed, 26 Aug 2015 09:58:35 -0300 [thread overview]
Message-ID: <20150826125835.GL19203@kernel.org> (raw)
In-Reply-To: <50399556C9727B4D88A595C8584AAB37524EA468@GSjpTKYDCembx32.service.hitachi.net>
Em Wed, Aug 26, 2015 at 12:00:56AM +0000, 平松雅巳 / HIRAMATU,MASAMI escreveu:
> Arnaldo, I don't think we need "+".
What would be the problem? When we write
perf probe /lib/x86_64-linux-gnu/libc-2.19.so +0xeb860
What we're meaning is: Take the address where libc-2.19.so is loaded, in
each process, add (+) to that address the number 0xeb860 (an offset),
and when that probe is enabled, put a breakpoint there.
I saw it that way and thus to me it seemed really natural, thus I
applied.
> So, Nak it.
I don't have strong feelings about that one and I saw that there was a
long discussion, so I'll read it and process the patches, if I don't see
anything questionable.
Next time I'll try not to process perf probe patches so fast :-)
- Arnaldo
> > -----Original Message-----
> > From: Arnaldo Carvalho de Melo [mailto:acme@kernel.org]
> > Sent: Wednesday, August 26, 2015 1:15 AM
> > To: Ingo Molnar
> > Cc: linux-kernel@vger.kernel.org; Wang Nan; 平松雅巳 / HIRAMATU,MASAMI; Namhyung Kim; pi3orama@163.com; Arnaldo Carvalho
> > de Melo
> > Subject: [!][PATCH 16/16] perf probe: Support probing at absolute addresses
> >
> > From: Wang Nan <wangnan0@huawei.com>
> >
> > It should be useful to allow 'perf probe' probe at absolute offsets of a
> > target.
> >
> > For example, when (u)probing at a instruction of a shared object in an
> > embedded system where debuginfo is not available but we know the offset
> > of that instruction by manually digging.
> >
> > This patch enables following perf probe command syntax:
> >
> > # perf probe +0xffffffff811e6615
> >
> > And
> >
> > # perf probe /lib/x86_64-linux-gnu/libc-2.19.so +0xeb860
> >
> > In the above example, we don't need a anchor symbol, so it is possible
> > to compute absolute addresses using other methods and then use 'perf
> > probe' to create the probing points.
> >
> > Committer note:
> >
> > One can as well specify a name, so that the probe doesn't get assigned a
> > generic one starting with abs_, i.e. if we use as described above we
> > get:
> >
> > [root@zoo ~]# readelf -sW /lib64/libc-2.20.so | grep -w malloc
> > 1175: 00000000000830f0 300 FUNC GLOBAL DEFAULT 12 malloc@@GLIBC_2.2.5
> > 813: 0000000000000000 0 FILE LOCAL DEFAULT ABS malloc.c
> > 5276: 00000000000830f0 300 FUNC GLOBAL DEFAULT 12 malloc
> > [root@zoo ~]#
> > [root@zoo ~]# perf probe /lib64/libc-2.20.so +0x830f0
> > Added new event:
> > probe_libc:abs_830f0 (on 0x830f0 in /lib64/libc-2.20.so)
> >
> > You can now use it in all perf tools, such as:
> >
> > perf record -e probe_libc:abs_830f0 -aR sleep 1
> >
> > [root@zoo ~]#
> > [root@zoo ~]# perf probe -l
> > probe_libc:abs_830f0 (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> > [root@zoo ~]#
> >
> > Whereas if we assign it a name it gets more manageable:
> >
> > [root@zoo ~]# perf probe /lib64/libc-2.20.so malloc=+0x830f0
> > Added new event:
> > probe_libc:malloc (on 0x830f0 in /lib64/libc-2.20.so)
> >
> > You can now use it in all perf tools, such as:
> >
> > perf record -e probe_libc:malloc -aR sleep 1
> >
> > [root@zoo ~]# perf probe -l
> > probe_libc:malloc (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> > [root@zoo ~]#
> >
> > Both, of course, will produce the same results, and we can use a
> > non canonical name, if the need arises:
> >
> > [root@zoo ~]# perf probe /lib64/libc-2.20.so memory_allocation=+0x830f0
> > Added new event:
> > probe_libc:memory_allocation (on 0x830f0 in /lib64/libc-2.20.so)
> >
> > You can now use it in all perf tools, such as:
> >
> > perf record -e probe_libc:memory_allocation -aR sleep 1
> >
> > [root@zoo ~]# perf probe -l
> > probe_libc:memory_allocation (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> > [root@zoo ~]#
> >
> > Signed-off-by: Wang Nan <wangnan0@huawei.com>
> > Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: pi3orama@163.com
> > Link: http://lkml.kernel.org/r/1440509256-193590-2-git-send-email-wangnan0@huawei.com
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> > tools/perf/util/probe-event.c | 144 +++++++++++++++++++++++++++++++++++++----
> > tools/perf/util/probe-event.h | 3 +
> > tools/perf/util/probe-finder.c | 21 +-----
> > 3 files changed, 138 insertions(+), 30 deletions(-)
> >
> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> > index 6c7e538c9b8b..59de69a4e3ac 100644
> > --- a/tools/perf/util/probe-event.c
> > +++ b/tools/perf/util/probe-event.c
> > @@ -1194,9 +1194,13 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> > *ptr++ = '\0';
> > }
> >
> > - tmp = strdup(arg);
> > - if (tmp == NULL)
> > - return -ENOMEM;
> > + if (arg[0] == '\0')
> > + tmp = NULL;
> > + else {
> > + tmp = strdup(arg);
> > + if (tmp == NULL)
> > + return -ENOMEM;
> > + }
> >
> > if (file_spec)
> > pp->file = tmp;
> > @@ -1283,11 +1287,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> > return -EINVAL;
> > }
> >
> > - if (pp->offset && !pp->function) {
> > - semantic_error("Offset requires an entry function.\n");
> > - return -EINVAL;
> > - }
> > -
> > if (pp->retprobe && !pp->function) {
> > semantic_error("Return probe requires an entry function.\n");
> > return -EINVAL;
> > @@ -1299,6 +1298,11 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> > return -EINVAL;
> > }
> >
> > + if (!pp->function && !pp->offset && !pp->file) {
> > + semantic_error("Absolute address should not be zero.\n");
> > + return -EINVAL;
> > + }
> > +
> > pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
> > pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
> > pp->lazy_line);
> > @@ -1609,7 +1613,7 @@ error:
> > static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> > {
> > char *buf, *tmp;
> > - char offs[32] = "", line[32] = "", file[32] = "";
> > + char offs[32] = "", line[32] = "", file[32] = "", addr[32] = "";
> > int ret, len;
> >
> > buf = zalloc(MAX_CMDLEN);
> > @@ -1622,6 +1626,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> > if (ret <= 0)
> > goto error;
> > }
> > + if (!pp->function) {
> > + ret = e_snprintf(addr, 32, "0x%lx", pp->offset);
> > + if (ret <= 0)
> > + goto error;
> > + }
> > if (pp->line) {
> > ret = e_snprintf(line, 32, ":%d", pp->line);
> > if (ret <= 0)
> > @@ -1639,9 +1648,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> > goto error;
> > }
> >
> > - if (pp->function)
> > - ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
> > - offs, pp->retprobe ? "%return" : "", line,
> > + if (pp->function || pp->offset)
> > + ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s",
> > + pp->function ? : addr,
> > + pp->function ? offs : "",
> > + pp->retprobe ? "%return" : "", line,
> > file);
> > else
> > ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
> > @@ -1786,6 +1797,11 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
> > if (tev->uprobes)
> > ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
> > tp->module, tp->address);
> > + else if (tp->symbol[0] == '0' && tp->symbol[1] == 'x')
> > + /* Absolute address. See try_to_find_absolute_address() */
> > + ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
> > + tp->module ?: "", tp->module ? ":" : "",
> > + tp->address);
> > else
> > ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
> > tp->module ?: "", tp->module ? ":" : "",
> > @@ -2572,6 +2588,87 @@ err_out:
> > goto out;
> > }
> >
> > +static int try_to_find_absolute_address(struct perf_probe_event *pev,
> > + struct probe_trace_event **tevs)
> > +{
> > + struct perf_probe_point *pp = &pev->point;
> > + struct probe_trace_event *tev;
> > + struct probe_trace_point *tp;
> > + int i, err;
> > +
> > + if (perf_probe_event_need_dwarf(pev) || pev->point.function)
> > + return -EINVAL;
> > +
> > + /*
> > + * This is 'perf probe /lib/libc.so +0xabcd'. Try to probe at
> > + * absolute address.
> > + *
> > + * Only one tev can be generated by this.
> > + */
> > + *tevs = zalloc(sizeof(*tev));
> > + if (!*tevs)
> > + return -ENOMEM;
> > +
> > + tev = *tevs;
> > + tp = &tev->point;
> > +
> > + /*
> > + * Don't use tp->offset, use address directly, because
> > + * in synthesize_probe_trace_command() address cannot be
> > + * zero.
> > + */
> > + tp->address = pev->point.offset;
> > + tp->retprobe = pp->retprobe;
> > + tev->uprobes = pev->uprobes;
> > +
> > + err = -ENOMEM;
> > + /* Give it a '0x' leading symbol name */
> > + if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
> > + goto errout;
> > +
> > + /* For kprobe, check range */
> > + if ((!tev->uprobes) &&
> > + (kprobe_warn_out_range(tev->point.symbol,
> > + tev->point.address))) {
> > + err = -EACCES;
> > + goto errout;
> > + }
> > +
> > + if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
> > + goto errout;
> > +
> > + if (pev->target) {
> > + tp->module = strdup(pev->target);
> > + if (!tp->module)
> > + goto errout;
> > + }
> > +
> > + if (tev->group) {
> > + tev->group = strdup(pev->group);
> > + if (!tev->group)
> > + goto errout;
> > + }
> > +
> > + if (pev->event) {
> > + tev->event = strdup(pev->event);
> > + if (!tev->event)
> > + goto errout;
> > + }
> > +
> > + tev->nargs = pev->nargs;
> > + for (i = 0; i < tev->nargs; i++)
> > + copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
> > +
> > + return 1;
> > +
> > +errout:
> > + if (*tevs) {
> > + clear_probe_trace_events(*tevs, 1);
> > + *tevs = NULL;
> > + }
> > + return err;
> > +}
> > +
> > bool __weak arch__prefers_symtab(void) { return false; }
> >
> > static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> > @@ -2588,6 +2685,10 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> > }
> > }
> >
> > + ret = try_to_find_absolute_address(pev, tevs);
> > + if (ret > 0)
> > + return ret;
> > +
> > if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
> > ret = find_probe_trace_events_from_map(pev, tevs);
> > if (ret > 0)
> > @@ -2758,3 +2859,22 @@ end:
> > return ret;
> > }
> >
> > +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> > + struct perf_probe_arg *pvar)
> > +{
> > + tvar->value = strdup(pvar->var);
> > + if (tvar->value == NULL)
> > + return -ENOMEM;
> > + if (pvar->type) {
> > + tvar->type = strdup(pvar->type);
> > + if (tvar->type == NULL)
> > + return -ENOMEM;
> > + }
> > + if (pvar->name) {
> > + tvar->name = strdup(pvar->name);
> > + if (tvar->name == NULL)
> > + return -ENOMEM;
> > + } else
> > + tvar->name = NULL;
> > + return 0;
> > +}
> > diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> > index 83ee95e9743b..174a3cf6c03d 100644
> > --- a/tools/perf/util/probe-event.h
> > +++ b/tools/perf/util/probe-event.h
> > @@ -156,4 +156,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
> > /* Maximum index number of event-name postfix */
> > #define MAX_EVENT_INDEX 1024
> >
> > +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> > + struct perf_probe_arg *pvar);
> > +
> > #endif /*_PROBE_EVENT_H */
> > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > index 7b80f8cb62b9..29c43c0680a8 100644
> > --- a/tools/perf/util/probe-finder.c
> > +++ b/tools/perf/util/probe-finder.c
> > @@ -553,24 +553,9 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
> > char buf[32], *ptr;
> > int ret = 0;
> >
> > - if (!is_c_varname(pf->pvar->var)) {
> > - /* Copy raw parameters */
> > - pf->tvar->value = strdup(pf->pvar->var);
> > - if (pf->tvar->value == NULL)
> > - return -ENOMEM;
> > - if (pf->pvar->type) {
> > - pf->tvar->type = strdup(pf->pvar->type);
> > - if (pf->tvar->type == NULL)
> > - return -ENOMEM;
> > - }
> > - if (pf->pvar->name) {
> > - pf->tvar->name = strdup(pf->pvar->name);
> > - if (pf->tvar->name == NULL)
> > - return -ENOMEM;
> > - } else
> > - pf->tvar->name = NULL;
> > - return 0;
> > - }
> > + /* Copy raw parameters */
> > + if (!is_c_varname(pf->pvar->var))
> > + return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
> >
> > if (pf->pvar->name)
> > pf->tvar->name = strdup(pf->pvar->name);
> > --
> > 2.1.0
>
next prev parent reply other threads:[~2015-08-26 12:58 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-25 16:14 [GIT PULL 00/16] perf/core improvements and fixes Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 01/16] perf tools: Fix tarball build broken by pt/bts Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 02/16] perf annotate: Reset the dso find_symbol cache when removing symbols Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 03/16] perf ui tui progress: Implement the ui_progress_ops->finish() method Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 04/16] perf ordered_events: Clear the progress bar at the end of a flush Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 05/16] perf tools: Fix Intel PT 'instructions' sample period Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 06/16] perf tools: Add Intel PT support for PSB periods Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 07/16] perf tools: Add new Intel PT packet definitions Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 08/16] perf tools: Pass Intel PT information for decoding MTC and CYC Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 09/16] perf tools: Add Intel PT support for decoding MTC packets Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 10/16] perf tools: Add Intel PT support for using " Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 11/16] perf tools: Add Intel PT support for decoding CYC packets Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 12/16] perf tools: Add Intel PT support for using " Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 13/16] perf tools: Add Intel PT support for decoding TRACESTOP packets Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 14/16] perf tools: Update Intel PT documentation Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 15/16] perf probe: Prevent segfault when reading probe point with absolute address Arnaldo Carvalho de Melo
2015-08-25 16:14 ` [PATCH 16/16] perf probe: Support probing at absolute addresses Arnaldo Carvalho de Melo
2015-08-26 0:00 ` 平松雅巳 / HIRAMATU,MASAMI
2015-08-26 12:58 ` Arnaldo Carvalho de Melo [this message]
2015-08-26 13:39 ` [GIT PULL 00/16] perf/core improvements and fixes Arnaldo Carvalho de Melo
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=20150826125835.GL19203@kernel.org \
--to=acme@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.