(2013/09/03 16:37), Hemant Kumar wrote:
> This patch enables perf to probe on the marker name specified on the command 
> line.

At least you must show how this works, and how to use in the comment.

Thank you,

> ---
>  tools/perf/builtin-probe.c    |    7 +++
>  tools/perf/util/probe-event.c |   11 ++++
>  tools/perf/util/symbol-elf.c  |  112 
> +++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/symbol.h      |    5 ++
>  4 files changed, 135 insertions(+)
> 
> diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
> index 3d8dcdf..8382853 100644
> --- a/tools/perf/builtin-probe.c
> +++ b/tools/perf/builtin-probe.c
> @@ -378,6 +378,13 @@ int cmd_probe(int argc, const char **argv, const char 
> *prefix __maybe_unused)
>                                      " (%d)\n", ret);
>                       return ret;
>               }
> +             params.uprobes = true;
> +             ret = probe_marker(params.target,
> +                                params.events[0].point.function);
> +             if (ret < 0)
> +                     pr_err("Could not probe at %s marker\n",
> +                            params.events[0].point.function);
> +             return ret;
>       }
>  
>       if (params.list_events) {
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index 7f846f9..014d642 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -2378,3 +2378,14 @@ int show_available_markers(const char *target)
>       setup_pager();
>       return list_markers(target);
>  }
> +
> +int probe_marker(const char *name, char *mark)
> +{
> +     int fd;
> +
> +     fd = open_uprobe_events(true);
> +     if (fd == -1)
> +             return fd;
> +     else
> +             return probe__marker(name, mark, fd);
> +}
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index f3630f2..60938a5 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -1040,6 +1040,118 @@ out_ret:
>       return ret;
>  }
>  
> +static void extract_first_name(const char *target, char *fname)
> +{
> +     int i, len;
> +     char *file;
> +
> +     file = strrchr(target, DIR_SEP);
> +     file++;
> +     len = strlen(file);
> +     for (i = 0; i <= len; i++) {
> +             if (!isalpha(file[i]))
> +                     break;
> +             fname[i] = file[i];
> +     }
> +     fname[i] = '\0';
> +}
> +
> +static int probe_at_note(struct sdt_note *r_note, const char *target, bool 
> exec,
> +                      int fd)
> +{
> +     char buf[MAX_CMDLEN];
> +     int len, err = -1;
> +     Elf64_Addr offset;
> +     char *fname = NULL;
> +
> +     if (exec)
> +             offset = r_note->addr.a64[0] - TEXT_SCN;
> +     else
> +             offset = r_note->addr.a64[0];
> +
> +     fname = (char *)zalloc(sizeof(char) * strlen(target));
> +     if (fname == NULL) {
> +             pr_err("Error in allocating memory to fname\n");
> +             goto out_ret;
> +     }
> +
> +     extract_first_name(target, fname);
> +     len = snprintf(buf, MAX_CMDLEN, "%c:%s%s/%s %s:0x%x", 'p', "probe_",
> +                    fname, r_note->name, target, (unsigned)offset);
> +
> +     len = write(fd, buf, MAX_CMDLEN);
> +     if (len < 0) {
> +             pr_err("Couldn't write into uprobe_events!\n");
> +             goto out_close;
> +     } else {
> +             printf("Added new event :\n");
> +             printf("event = %s \t (on 0x%x)\n\n", r_note->name,
> +                    (unsigned)offset);
> +             printf("You can now use it on all perf tools such as :\n\n");
> +             printf("\t perf record -e %s%s:%s -aR sleep 1\n\n", "probe_", 
> fname, r_note->name);
> +             err = 0;
> +     }
> +
> +out_close:
> +     close(fd);
> +     free(fname);
> +out_ret:
> +     return err;
> +}
> +
> +static int search_and_probe_at_note(char *key, struct sdt_note **start,
> +                                 const char *target, bool exec, int fd)
> +{
> +     int ret = -1;
> +     struct sdt_note *req;
> +
> +     for (req = (*start); req != NULL; req = req->next) {
> +             if (!strcmp(key, req->name))
> +                     break;
> +     }
> +     if (!req) {
> +             pr_err("Could not find marker %s\n", key);
> +             return ret;
> +     }
> +
> +     ret = probe_at_note(req, target, exec, fd);
> +     return ret;
> +}
> +
> +int probe__marker(const char *name, char *mark, int evfd)
> +{
> +     int ret = -1, fd;
> +     Elf *elf;
> +     bool exec = false;
> +     struct sdt_note *head = NULL;
> +
> +     fd = open(name, O_RDONLY);
> +     if (fd < 0) {
> +             pr_err("Failed to open the file\n");
> +             goto out_ret;
> +     }
> +
> +     symbol__elf_init();
> +     elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
> +     if (elf == NULL) {
> +             pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
> +             goto out_close;
> +     }
> +
> +     head = get_elf_markers(elf, &exec, true);
> +     if (head) {
> +             ret = search_and_probe_at_note(mark, &head, name, exec, evfd);
> +             cleanup_notes(head);
> +     }
> +
> +     elf_end(elf);
> +
> +out_close:
> +     close(fd);
> +out_ret:
> +     return ret;
> +}
> +
>  void cleanup_notes(struct sdt_note *start)
>  {
>       struct sdt_note *tmp;
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index f2d17b7..95289fd 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -262,8 +262,13 @@ void __map_groups__fixup_end(struct map_groups *mg, enum 
> map_type type);
>  int show_available_markers(const char *module);
>  int list_markers(const char *name);
>  void cleanup_notes(struct sdt_note *start);
> +int probe_marker(const char *name, char *mark);
> +int probe__marker(const char *name, char *mark, int fd);
>  
>  #define SDT_NOTE_TYPE 3
>  #define NOTE_SCN ".note.stapsdt"
> +#define TEXT_SCN 0x400000
> +#define DIR_SEP '/'
> +#define MAX_CMDLEN 256
>  
>  #endif /* __PERF_SYMBOL */
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majord...@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


-- 
Masami HIRAMATSU
IT Management Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: masami.hiramatsu...@hitachi.com


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to