(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/