lkml.org 
[lkml]   [2010]   [Dec]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[tip:perf/core] perf probe: Handle gracefully some stupid and buggy line syntaxes
    Commit-ID:  21dd9ae5a4e9f717f3957ec934dd3158129436b8
    Gitweb: http://git.kernel.org/tip/21dd9ae5a4e9f717f3957ec934dd3158129436b8
    Author: Franck Bui-Huu <fbuihuu@gmail.com>
    AuthorDate: Mon, 20 Dec 2010 15:18:05 +0100
    Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
    CommitDate: Tue, 21 Dec 2010 17:20:13 -0200

    perf probe: Handle gracefully some stupid and buggy line syntaxes

    Currently perf probe doesn't handle those incorrect syntaxes:

    $ perf probe -L sched.c:++13
    $ perf probe -L sched.c:-+13
    $ perf probe -L sched.c:10000000000000000000000000000+13

    This patches rewrites parse_line_range_desc() to handle them.

    As a bonus, it reports more useful error messages instead of: "Tailing
    with invalid character...".

    Acked-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    LKML-Reference: <1292854685-8230-7-git-send-email-fbuihuu@gmail.com>
    Signed-off-by: Franck Bui-Huu <fbuihuu@gmail.com>
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
    ---
    tools/perf/util/probe-event.c | 92 ++++++++++++++++++++++++++--------------
    1 files changed, 60 insertions(+), 32 deletions(-)

    diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
    index 80cc0bc..099336e 100644
    --- a/tools/perf/util/probe-event.c
    +++ b/tools/perf/util/probe-event.c
    @@ -529,6 +529,19 @@ int show_available_vars(struct perf_probe_event *pevs __unused,
    }
    #endif

    +static int parse_line_num(char **ptr, int *val, const char *what)
    +{
    + const char *start = *ptr;
    +
    + errno = 0;
    + *val = strtol(*ptr, ptr, 0);
    + if (errno || *ptr == start) {
    + semantic_error("'%s' is not a valid number.\n", what);
    + return -EINVAL;
    + }
    + return 0;
    +}
    +
    /*
    * Stuff 'lr' according to the line range described by 'arg'.
    * The line range syntax is described by:
    @@ -538,50 +551,65 @@ int show_available_vars(struct perf_probe_event *pevs __unused,
    */
    int parse_line_range_desc(const char *arg, struct line_range *lr)
    {
    - const char *ptr;
    - char *tmp;
    + char *range, *name = strdup(arg);
    + int err;
    +
    + if (!name)
    + return -ENOMEM;
    +
    + lr->start = 0;
    + lr->end = INT_MAX;
    +
    + range = strchr(name, ':');
    + if (range) {
    + *range++ = '\0';
    +
    + err = parse_line_num(&range, &lr->start, "start line");
    + if (err)
    + goto err;
    +
    + if (*range == '+' || *range == '-') {
    + const char c = *range++;
    +
    + err = parse_line_num(&range, &lr->end, "end line");
    + if (err)
    + goto err;
    +
    + if (c == '+') {
    + lr->end += lr->start;
    + /*
    + * Adjust the number of lines here.
    + * If the number of lines == 1, the
    + * the end of line should be equal to
    + * the start of line.
    + */
    + lr->end--;
    + }
    + }

    - ptr = strchr(arg, ':');
    - if (ptr) {
    - lr->start = (int)strtoul(ptr + 1, &tmp, 0);
    - if (*tmp == '+') {
    - lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
    - lr->end--; /*
    - * Adjust the number of lines here.
    - * If the number of lines == 1, the
    - * the end of line should be equal to
    - * the start of line.
    - */
    - } else if (*tmp == '-')
    - lr->end = (int)strtoul(tmp + 1, &tmp, 0);
    - else
    - lr->end = INT_MAX;
    pr_debug("Line range is %d to %d\n", lr->start, lr->end);
    +
    + err = -EINVAL;
    if (lr->start > lr->end) {
    semantic_error("Start line must be smaller"
    " than end line.\n");
    - return -EINVAL;
    + goto err;
    }
    - if (*tmp != '\0') {
    - semantic_error("Tailing with invalid character '%d'.\n",
    - *tmp);
    - return -EINVAL;
    + if (*range != '\0') {
    + semantic_error("Tailing with invalid str '%s'.\n", range);
    + goto err;
    }
    - tmp = strndup(arg, (ptr - arg));
    - } else {
    - tmp = strdup(arg);
    - lr->end = INT_MAX;
    }

    - if (tmp == NULL)
    - return -ENOMEM;
    -
    - if (strchr(tmp, '.'))
    - lr->file = tmp;
    + if (strchr(name, '.'))
    + lr->file = name;
    else
    - lr->function = tmp;
    + lr->function = name;

    return 0;
    +err:
    + free(name);
    + return err;
    }

    /* Check the name is good for event/group */

    \
     
     \ /
      Last update: 2010-12-22 12:35    [W:0.030 / U:89.272 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site