Re: [PATCH v2 5/5] perf-probe: Support escaped character in parser

2017-12-08 Thread Masami Hiramatsu
On Fri, 8 Dec 2017 12:45:45 +0100
Thomas-Mich Richter  wrote:

> On 12/07/2017 08:21 AM, Masami Hiramatsu wrote:
> > Support the special characters escaped by '\' in parser.
> > This allows user to specify versions directly like below.
> > 
> >   =
> >   # ./perf probe -x /lib64/libc-2.25.so malloc_get_state\\@GLIBC_2.2.5
> >   Added new event:
> > probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
> > /usr/lib64/libc-2.25.so)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> >   perf record -e probe_libc:malloc_get_state -aR sleep 1
> > 
> >   =
> > 
> > Or, you can use separators in source filename, e.g.
> > 
> >   =
> >   # ./perf probe -x /opt/test/a.out foo+bar.c:3
> >   Semantic error :There is non-digit character in offset.
> > Error: Command Parse Error.
> >   =
> > 
> > Usually "+" in source file cause parser error, but
> > 
> >   =
> >   # ./perf probe -x /opt/test/a.out foo\\+bar.c:4
> >   Added new event:
> > probe_a:main (on @foo+bar.c:4 in /opt/test/a.out)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> >   perf record -e probe_a:main -aR sleep 1
> >   =
> > 
> > escaped "\+" allows you to specify that.
> > 
> > Signed-off-by: Masami Hiramatsu 
> > ---
> >  Changes in v2:
> >   - Add a description and samples in Documentation/perf-probe.txt
> > ---
> >  tools/perf/Documentation/perf-probe.txt |   16 +
> >  tools/perf/util/probe-event.c   |   54 
> > +++
> >  tools/perf/util/string.c|   46 ++
> >  tools/perf/util/string2.h   |2 +
> >  4 files changed, 97 insertions(+), 21 deletions(-)
> > 
> > diff --git a/tools/perf/Documentation/perf-probe.txt 
> > b/tools/perf/Documentation/perf-probe.txt
> > index f96382692f42..b6866a05edd2 100644
> > --- a/tools/perf/Documentation/perf-probe.txt
> > +++ b/tools/perf/Documentation/perf-probe.txt
> > @@ -182,6 +182,14 @@ Note that before using the SDT event, the target 
> > binary (on which SDT events are
> >  For details of the SDT, see below.
> >  https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
> > 
> > +ESCAPED CHARACTER
> > +-
> > +
> > +In the probe syntax, '=', '@', '+', ':' and ';' are treated as a special 
> > character. You can use a backslash ('\') to escape the special characters.
> > +This is useful if you need to probe on a specific versioned symbols, like 
> > @GLIBC_... suffixes, or also you need to specify a source file which 
> > includes the special characters.
> > +Note that usually single backslash is consumed by shell, so you might need 
> > to pass double backslash (\\) or wrapping with single quotes (\'AAA\@BBB').
> > +See EXAMPLES how it is used.
> > +
> >  PROBE ARGUMENT
> >  --
> >  Each probe argument follows below syntax.
> > @@ -277,6 +285,14 @@ Add a USDT probe to a target process running in a 
> > different mount namespace
> > 
> >   ./perf probe --target-ns  -x 
> > /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/amd64/server/libjvm.so
> >  %sdt_hotspot:thread__sleep__end
> > 
> > +Add a probe on specific versioned symbol by backslash escape
> > +
> > + ./perf probe -x /lib64/libc-2.25.so 'malloc_get_state\@GLIBC_2.2.5'
> > +
> > +Add a probe in a source file using special characters by backslash escape
> > +
> > + ./perf probe -x /opt/test/a.out 'foo\+bar.c:4'
> > +
> > 
> >  SEE ALSO
> >  
> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> > index 94acc5846e2a..c082a27982e5 100644
> > --- a/tools/perf/util/probe-event.c
> > +++ b/tools/perf/util/probe-event.c
> > @@ -1325,27 +1325,30 @@ static int parse_perf_probe_event_name(char **arg, 
> > struct perf_probe_event *pev)
> >  {
> > char *ptr;
> > 
> > -   ptr = strchr(*arg, ':');
> > +   ptr = strpbrk_esc(*arg, ":");
> > if (ptr) {
> > *ptr = '\0';
> > if (!pev->sdt && !is_c_func_name(*arg))
> > goto ng_name;
> > -   pev->group = strdup(*arg);
> > +   pev->group = strdup_esc(*arg);
> > if (!pev->group)
> > return -ENOMEM;
> > *arg = ptr + 1;
> > } else
> > pev->group = NULL;
> > -   if (!pev->sdt && !is_c_func_name(*arg)) {
> > +
> > +   pev->event = strdup_esc(*arg);
> > +   if (pev->event == NULL)
> > +   return -ENOMEM;
> > +
> > +   if (!pev->sdt && !is_c_func_name(pev->event)) {
> > +   zfree(&pev->event);
> >  ng_name:
> > +   zfree(&pev->group);
> > semantic_error("%s is bad for event name -it must "
> >"follow C symbol-naming rule.\n", *arg);
> > return -EINVAL;
> > }
> > -   pev->event = strdup(*arg);
> > -   if (pev->event == NULL)
> > -   return -ENOMEM;
> > -
> > return 0;
> >  }
> > 
> > @@ -1373,7 +1376,7 @@ static int parse_perf_probe_point(char

Re: [PATCH v2 5/5] perf-probe: Support escaped character in parser

2017-12-08 Thread Thomas-Mich Richter
On 12/07/2017 08:21 AM, Masami Hiramatsu wrote:
> Support the special characters escaped by '\' in parser.
> This allows user to specify versions directly like below.
> 
>   =
>   # ./perf probe -x /lib64/libc-2.25.so malloc_get_state\\@GLIBC_2.2.5
>   Added new event:
> probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
> /usr/lib64/libc-2.25.so)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe_libc:malloc_get_state -aR sleep 1
> 
>   =
> 
> Or, you can use separators in source filename, e.g.
> 
>   =
>   # ./perf probe -x /opt/test/a.out foo+bar.c:3
>   Semantic error :There is non-digit character in offset.
> Error: Command Parse Error.
>   =
> 
> Usually "+" in source file cause parser error, but
> 
>   =
>   # ./perf probe -x /opt/test/a.out foo\\+bar.c:4
>   Added new event:
> probe_a:main (on @foo+bar.c:4 in /opt/test/a.out)
> 
>   You can now use it in all perf tools, such as:
> 
> perf record -e probe_a:main -aR sleep 1
>   =
> 
> escaped "\+" allows you to specify that.
> 
> Signed-off-by: Masami Hiramatsu 
> ---
>  Changes in v2:
>   - Add a description and samples in Documentation/perf-probe.txt
> ---
>  tools/perf/Documentation/perf-probe.txt |   16 +
>  tools/perf/util/probe-event.c   |   54 
> +++
>  tools/perf/util/string.c|   46 ++
>  tools/perf/util/string2.h   |2 +
>  4 files changed, 97 insertions(+), 21 deletions(-)
> 
> diff --git a/tools/perf/Documentation/perf-probe.txt 
> b/tools/perf/Documentation/perf-probe.txt
> index f96382692f42..b6866a05edd2 100644
> --- a/tools/perf/Documentation/perf-probe.txt
> +++ b/tools/perf/Documentation/perf-probe.txt
> @@ -182,6 +182,14 @@ Note that before using the SDT event, the target binary 
> (on which SDT events are
>  For details of the SDT, see below.
>  https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
> 
> +ESCAPED CHARACTER
> +-
> +
> +In the probe syntax, '=', '@', '+', ':' and ';' are treated as a special 
> character. You can use a backslash ('\') to escape the special characters.
> +This is useful if you need to probe on a specific versioned symbols, like 
> @GLIBC_... suffixes, or also you need to specify a source file which includes 
> the special characters.
> +Note that usually single backslash is consumed by shell, so you might need 
> to pass double backslash (\\) or wrapping with single quotes (\'AAA\@BBB').
> +See EXAMPLES how it is used.
> +
>  PROBE ARGUMENT
>  --
>  Each probe argument follows below syntax.
> @@ -277,6 +285,14 @@ Add a USDT probe to a target process running in a 
> different mount namespace
> 
>   ./perf probe --target-ns  -x 
> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/amd64/server/libjvm.so
>  %sdt_hotspot:thread__sleep__end
> 
> +Add a probe on specific versioned symbol by backslash escape
> +
> + ./perf probe -x /lib64/libc-2.25.so 'malloc_get_state\@GLIBC_2.2.5'
> +
> +Add a probe in a source file using special characters by backslash escape
> +
> + ./perf probe -x /opt/test/a.out 'foo\+bar.c:4'
> +
> 
>  SEE ALSO
>  
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 94acc5846e2a..c082a27982e5 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -1325,27 +1325,30 @@ static int parse_perf_probe_event_name(char **arg, 
> struct perf_probe_event *pev)
>  {
>   char *ptr;
> 
> - ptr = strchr(*arg, ':');
> + ptr = strpbrk_esc(*arg, ":");
>   if (ptr) {
>   *ptr = '\0';
>   if (!pev->sdt && !is_c_func_name(*arg))
>   goto ng_name;
> - pev->group = strdup(*arg);
> + pev->group = strdup_esc(*arg);
>   if (!pev->group)
>   return -ENOMEM;
>   *arg = ptr + 1;
>   } else
>   pev->group = NULL;
> - if (!pev->sdt && !is_c_func_name(*arg)) {
> +
> + pev->event = strdup_esc(*arg);
> + if (pev->event == NULL)
> + return -ENOMEM;
> +
> + if (!pev->sdt && !is_c_func_name(pev->event)) {
> + zfree(&pev->event);
>  ng_name:
> + zfree(&pev->group);
>   semantic_error("%s is bad for event name -it must "
>  "follow C symbol-naming rule.\n", *arg);
>   return -EINVAL;
>   }
> - pev->event = strdup(*arg);
> - if (pev->event == NULL)
> - return -ENOMEM;
> -
>   return 0;
>  }
> 
> @@ -1373,7 +1376,7 @@ static int parse_perf_probe_point(char *arg, struct 
> perf_probe_event *pev)
>   arg++;
>   }
> 
> - ptr = strpbrk(arg, ";=@+%");
> + ptr = strpbrk_esc(arg, ";=@+%");
>   if (pev->sdt) {
>   if (ptr) {
>   if (*ptr != '@') {
> @@ -1387,7 +1390,

[PATCH v2 5/5] perf-probe: Support escaped character in parser

2017-12-06 Thread Masami Hiramatsu
Support the special characters escaped by '\' in parser.
This allows user to specify versions directly like below.

  =
  # ./perf probe -x /lib64/libc-2.25.so malloc_get_state\\@GLIBC_2.2.5
  Added new event:
probe_libc:malloc_get_state (on malloc_get_state@GLIBC_2.2.5 in 
/usr/lib64/libc-2.25.so)

  You can now use it in all perf tools, such as:

  perf record -e probe_libc:malloc_get_state -aR sleep 1

  =

Or, you can use separators in source filename, e.g.

  =
  # ./perf probe -x /opt/test/a.out foo+bar.c:3
  Semantic error :There is non-digit character in offset.
Error: Command Parse Error.
  =

Usually "+" in source file cause parser error, but

  =
  # ./perf probe -x /opt/test/a.out foo\\+bar.c:4
  Added new event:
probe_a:main (on @foo+bar.c:4 in /opt/test/a.out)

  You can now use it in all perf tools, such as:

  perf record -e probe_a:main -aR sleep 1
  =

escaped "\+" allows you to specify that.

Signed-off-by: Masami Hiramatsu 
---
 Changes in v2:
  - Add a description and samples in Documentation/perf-probe.txt
---
 tools/perf/Documentation/perf-probe.txt |   16 +
 tools/perf/util/probe-event.c   |   54 +++
 tools/perf/util/string.c|   46 ++
 tools/perf/util/string2.h   |2 +
 4 files changed, 97 insertions(+), 21 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt 
b/tools/perf/Documentation/perf-probe.txt
index f96382692f42..b6866a05edd2 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -182,6 +182,14 @@ Note that before using the SDT event, the target binary 
(on which SDT events are
 For details of the SDT, see below.
 https://sourceware.org/gdb/onlinedocs/gdb/Static-Probe-Points.html
 
+ESCAPED CHARACTER
+-
+
+In the probe syntax, '=', '@', '+', ':' and ';' are treated as a special 
character. You can use a backslash ('\') to escape the special characters.
+This is useful if you need to probe on a specific versioned symbols, like 
@GLIBC_... suffixes, or also you need to specify a source file which includes 
the special characters.
+Note that usually single backslash is consumed by shell, so you might need to 
pass double backslash (\\) or wrapping with single quotes (\'AAA\@BBB').
+See EXAMPLES how it is used.
+
 PROBE ARGUMENT
 --
 Each probe argument follows below syntax.
@@ -277,6 +285,14 @@ Add a USDT probe to a target process running in a 
different mount namespace
 
  ./perf probe --target-ns  -x 
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.121-0.b13.el7_3.x86_64/jre/lib/amd64/server/libjvm.so
 %sdt_hotspot:thread__sleep__end
 
+Add a probe on specific versioned symbol by backslash escape
+
+ ./perf probe -x /lib64/libc-2.25.so 'malloc_get_state\@GLIBC_2.2.5'
+
+Add a probe in a source file using special characters by backslash escape
+
+ ./perf probe -x /opt/test/a.out 'foo\+bar.c:4'
+
 
 SEE ALSO
 
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 94acc5846e2a..c082a27982e5 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1325,27 +1325,30 @@ static int parse_perf_probe_event_name(char **arg, 
struct perf_probe_event *pev)
 {
char *ptr;
 
-   ptr = strchr(*arg, ':');
+   ptr = strpbrk_esc(*arg, ":");
if (ptr) {
*ptr = '\0';
if (!pev->sdt && !is_c_func_name(*arg))
goto ng_name;
-   pev->group = strdup(*arg);
+   pev->group = strdup_esc(*arg);
if (!pev->group)
return -ENOMEM;
*arg = ptr + 1;
} else
pev->group = NULL;
-   if (!pev->sdt && !is_c_func_name(*arg)) {
+
+   pev->event = strdup_esc(*arg);
+   if (pev->event == NULL)
+   return -ENOMEM;
+
+   if (!pev->sdt && !is_c_func_name(pev->event)) {
+   zfree(&pev->event);
 ng_name:
+   zfree(&pev->group);
semantic_error("%s is bad for event name -it must "
   "follow C symbol-naming rule.\n", *arg);
return -EINVAL;
}
-   pev->event = strdup(*arg);
-   if (pev->event == NULL)
-   return -ENOMEM;
-
return 0;
 }
 
@@ -1373,7 +1376,7 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
arg++;
}
 
-   ptr = strpbrk(arg, ";=@+%");
+   ptr = strpbrk_esc(arg, ";=@+%");
if (pev->sdt) {
if (ptr) {
if (*ptr != '@') {
@@ -1387,7 +1390,7 @@ static int parse_perf_probe_point(char *arg, struct 
perf_probe_event *pev)
pev->target = build_id_cache__origname(tmp);
free(tmp);
} else
-