From: Namhyung Kim <namhyung@kernel.org>
To: Hemant Kumar <hkshaw@linux.vnet.ibm.com>
Cc: linux-kernel@vger.kernel.org, srikar@linux.vnet.ibm.com,
peterz@infradead.org, oleg@redhat.com, mingo@redhat.com,
anton@redhat.com, systemtap@sourceware.org,
masami.hiramatsu.pt@hitachi.com
Subject: Re: [PATCH 1/2] SDT markers listing by perf
Date: Wed, 04 Sep 2013 15:42:27 +0900 [thread overview]
Message-ID: <87ioyht7e4.fsf@sejong.aot.lge.com> (raw)
In-Reply-To: <20130903073655.4793.20013.stgit@hemant-fedora> (Hemant Kumar's message of "Tue, 03 Sep 2013 13:06:55 +0530")
On Tue, 03 Sep 2013 13:06:55 +0530, Hemant Kumar wrote:
[SNIP]
> diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
> index e8a66f9..3d8dcdf 100644
> --- a/tools/perf/builtin-probe.c
> +++ b/tools/perf/builtin-probe.c
> @@ -55,6 +55,7 @@ static struct {
> bool show_funcs;
> bool mod_events;
> bool uprobes;
> + bool sdt;
> int nevents;
> struct perf_probe_event events[MAX_PROBES];
> struct strlist *dellist;
> @@ -325,6 +326,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
> opt_set_filter),
> OPT_CALLBACK('x', "exec", NULL, "executable|path",
> "target executable name or path", opt_set_target),
> + OPT_BOOLEAN('S', "sdt", ¶ms.sdt,
> + "Show and probe on the SDT markers"),
You need to add it to Documentation/perf-probe.txt too. In addition if
the --sdt option is only able to work with libelf, it should be wrapped
into the #ifdef LIBELF_SUPPORT pair.
And I'm not sure that it's a good idea to have two behavior on a single
option (S) - show and probe (add). Maybe it can be separated into two
or the S option can be used as a flag with existing --list and --add
option?
> OPT_END()
> };
> int ret;
> @@ -355,6 +358,28 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
> */
> symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
>
> + if (params.sdt) {
> + if (params.show_lines) {
> + pr_err(" Error: Don't use --sdt with --line.\n");
> + usage_with_options(probe_usage, options);
> + }
> + if (params.show_vars) {
> + pr_err(" Error: Don't use --sdt with --vars.\n");
> + usage_with_options(probe_usage, options);
> + }
> + if (params.show_funcs) {
> + pr_err(" Error: Don't use --sdt with --funcs.\n");
> + usage_with_options(probe_usage, options);
> + }
> + if (params.list_events) {
> + ret = show_available_markers(params.target);
> + if (ret < 0)
> + pr_err(" Error: Failed to show markers."
> + " (%d)\n", ret);
> + return ret;
> + }
> + }
> +
> if (params.list_events) {
> if (params.mod_events) {
> pr_err(" Error: Don't use --list with --add/--del.\n");
> @@ -382,6 +407,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
> ret);
> return ret;
> }
> +
> if (params.show_funcs) {
> if (params.nevents != 0 || params.dellist) {
> pr_err(" Error: Don't use --funcs with"
> diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> index aa04bf9..7f846f9 100644
> --- a/tools/perf/util/probe-event.c
> +++ b/tools/perf/util/probe-event.c
> @@ -2372,3 +2372,9 @@ out:
> free(name);
> return ret;
> }
> +
> +int show_available_markers(const char *target)
> +{
> + setup_pager();
> + return list_markers(target);
> +}
Did you build it with NO_LIBELF=1 ? I guess not. At least you need a
dummy list_markers() function which just returns -1 for such case.
> diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
> index 4b12bf8..f3630f2 100644
> --- a/tools/perf/util/symbol-elf.c
> +++ b/tools/perf/util/symbol-elf.c
> @@ -846,6 +846,211 @@ out_elf_end:
> return err;
> }
>
> +/* Populate the name, type, offset and argument fields in the note structure */
> +static struct sdt_note *populate_note(Elf **elf, const char *data, size_t len,
> + int type)
Hmm.. I think the name needs to be changed more specific like
populate_sdt_note() or something?
> +{
> + const char *provider, *name, *args;
> + struct sdt_note *note;
> +
> + /*
> + * There are 3 address values to be obtained: marker offset, base address
> + * and semaphore
> + */
> + union {
> + Elf64_Addr a64[3];
> + Elf32_Addr a32[3];
> + } buf;
> +
> + /*
> + * dst and src (of Elf_Data) are required for translation from file
> + * to memory representation
> + */
> + Elf_Data dst = {
> + .d_buf = &buf, .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
> + .d_size = gelf_fsize((*elf), ELF_T_ADDR, 3, EV_CURRENT),
> + .d_off = 0, .d_align = 0
> + };
> +
> + Elf_Data src = {
> + .d_buf = (void *) data, .d_type = ELF_T_ADDR,
> + .d_version = EV_CURRENT, .d_size = dst.d_size, .d_off = 0,
> + .d_align = 0
> + };
> +
> + if (type != SDT_NOTE_TYPE)
> + goto out_ret;
> +
> + note = zalloc(sizeof(struct sdt_note));
> + if (note == NULL) {
> + pr_err("memory allocation error\n");
> + goto out_ret;
> + }
> + note->next = NULL;
> +
> + if (len < dst.d_size + 3)
> + goto out_free;
> + /*
> + * Translating from file representation to memory representation
> + * Data now points to the address (offset)
> + */
> + if (gelf_xlatetom((*elf), &dst, &src,
> + elf_getident((*elf), NULL)[EI_DATA]) == NULL)
> + pr_debug("gelf_xlatetom : %s", elf_errmsg(-1));
> +
> + /* Populate the fields of sdt_note */
> + provider = data + dst.d_size;
> +
> + name = (const char *)memchr(provider, '\0', data + len - provider);
> + if (name++ == NULL)
> + goto out_ret;
> +
> + args = (const char *)memchr(name, '\0', data + len - name);
> + if (args++ == NULL ||
> + memchr(args, '\0', data + len - name) != data + len - 1)
> + goto out_ret;
> + note->provider = provider;
> + note->name = name;
> +
> + /* Three addr's for location, base and semaphore addresses */
> + note->addr.a64[0] = (buf.a64[0]);
> + note->addr.a64[1] = (buf.a64[1]);
> + note->addr.a64[2] = (buf.a64[2]);
> + return note;
> +
> +out_free:
> + free(note);
> +out_ret:
> + return NULL;
> +}
> +
> +/*
> + * Traverse the elf of the object, find out the .note.stapsdt section
> + * and accordingly initialize the notes' list head
> + */
> +static struct sdt_note *get_elf_markers(Elf *elf, bool *exe, bool probe)
Ditto. How about get_sdt_markers() or get_sdt_notes()? I can see that
there are places those 'marker' and 'note' are used here and there. If
they indicate same thing it'd better to unify the term.
> +{
> + Elf_Scn *scn = NULL;
> + Elf_Data *data;
> + GElf_Shdr shdr;
> + GElf_Ehdr ehdr;
> + size_t shstrndx;
> + size_t next;
> + GElf_Nhdr nhdr;
> + size_t name_off, desc_off, offset;
> + struct sdt_note *note = NULL, *tmp, *head = NULL;
> +
> + if (gelf_getehdr(elf, &ehdr) == NULL) {
> + pr_debug("%s: cannot get elf header.\n", __func__);
> + goto out_end;
> + }
> +
> + if (elf_getshdrstrndx(elf, &shstrndx) != 0) {
> + pr_debug("getshdrstrndx failed\n");
> + goto out_end;
> + }
> +
> + /* library or exec */
> + if (probe) {
> + if (ehdr.e_type == ET_EXEC)
> + *exe = true;
> + }
> +
> + /*
> + * Look for Section type = SHT_NOTE, flags = no SHF_ALLOC
> + * and name = .note.stapsdt
> + */
> + scn = elf_section_by_name(elf, &ehdr, &shdr, NOTE_SCN, NULL);
> + if (scn == NULL) {
> + pr_err("%s section not found!\n", NOTE_SCN);
> + goto out_end;
> + }
> +
> + if (!(shdr.sh_type == SHT_NOTE) || (shdr.sh_flags & SHF_ALLOC))
> + goto out_end;
> +
> + data = elf_getdata(scn, NULL);
> +
> + /* Get the notes */
> + for (offset = 0; (next = gelf_getnote(data, offset, &nhdr, &name_off,
> + &desc_off)) > 0; offset = next) {
> + tmp = populate_note(&elf, (const char *)((long)(data->d_buf) +
> + (long)desc_off),
> + nhdr.n_descsz, nhdr.n_type);
Shouldn't we check the name of note being "stapsdt" as well as version
(type) 3?
Thanks,
Namhyung
> + /* For first note */
> + if (!head) {
> + note = tmp;
> + head = note;
> + continue;
> + }
> + note->next = tmp;
> + note = note->next;
> + }
> +
> + if (!head)
> + pr_err("No markers found\n");
> +
> +out_end:
> + return head;
> +}
> +
> +static void print_notes(struct sdt_note *start)
> +{
> + struct sdt_note *temp;
> + int c;
> +
> + for (temp = start, c = 0; temp != NULL; temp = temp->next, c++)
> + printf("%s:%s\n", temp->provider, temp->name);
> +
> + printf("\nTotal markers = %d\n", c);
> +}
> +
> +int list_markers(const char *name)
> +{
> + int fd, ret = -1;
> + Elf *elf;
> + struct sdt_note *head = NULL;
> +
> + fd = open(name, O_RDONLY);
> + if (fd < 0) {
> + pr_err("Failed to open %s\n", name);
> + goto out_ret;
> + }
> +
> + symbol__elf_init();
> + elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
> + if (elf == NULL) {
> + pr_err("%s: cannot read %s ELF file.\n", __func__, name);
> + goto out_close;
> + }
> +
> + head = get_elf_markers(elf, NULL, false);
> + if (head) {
> + print_notes(head);
> + cleanup_notes(head);
> + ret = 0;
> + } else {
> + pr_err("No SDT markers found in %s\n", name);
> + }
> + elf_end(elf);
> +
> +out_close:
> + close(fd);
> +out_ret:
> + return ret;
> +}
> +
> +void cleanup_notes(struct sdt_note *start)
> +{
> + struct sdt_note *tmp;
> +
> + while (start) {
> + tmp = start->next;
> + free(start);
> + start = tmp;
> + }
> +}
> +
> void symbol__elf_init(void)
> {
> elf_version(EV_CURRENT);
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 5f720dc..f2d17b7 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -197,6 +197,17 @@ struct symsrc {
> #endif
> };
>
> +/* Note structure */
> +struct sdt_note {
> + const char *name;
> + const char *provider;
> + union {
> + Elf64_Addr a64[3];
> + Elf32_Addr a32[3];
> + } addr;
> + struct sdt_note *next;
> +};
> +
> void symsrc__destroy(struct symsrc *ss);
> int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
> enum dso_binary_type type);
> @@ -247,4 +258,12 @@ void symbols__fixup_duplicate(struct rb_root *symbols);
> void symbols__fixup_end(struct rb_root *symbols);
> void __map_groups__fixup_end(struct map_groups *mg, enum map_type type);
>
> +/* For SDT markers */
> +int show_available_markers(const char *module);
> +int list_markers(const char *name);
> +void cleanup_notes(struct sdt_note *start);
> +
> +#define SDT_NOTE_TYPE 3
> +#define NOTE_SCN ".note.stapsdt"
> +
> #endif /* __PERF_SYMBOL */
next prev parent reply other threads:[~2013-09-04 6:42 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-03 7:36 [RFC PATCH 0/2] Perf support to SDT markers Hemant Kumar Shaw
2013-09-03 7:36 ` [PATCH 1/2] SDT markers listing by perf Hemant Kumar
2013-09-03 8:19 ` Hemant
2013-09-04 6:43 ` Namhyung Kim
2013-09-04 17:40 ` Hemant
2013-09-04 6:42 ` Namhyung Kim [this message]
2013-09-04 8:01 ` Masami Hiramatsu
2013-09-04 17:58 ` Hemant
2013-09-15 11:28 ` Hemant
2013-09-25 4:37 ` Masami Hiramatsu
2013-09-25 6:03 ` Hemant
2013-09-25 8:45 ` Masami Hiramatsu
2013-09-04 17:37 ` Hemant
2013-09-06 6:37 ` Namhyung Kim
2013-09-06 8:41 ` Hemant
2013-09-04 7:21 ` Masami Hiramatsu
2013-09-04 17:52 ` Hemant
2013-09-03 7:37 ` [PATCH 2/2] Support to perf to probe on SDT markers: Hemant Kumar
2013-09-03 9:14 ` Masami Hiramatsu
2013-09-04 7:00 ` Namhyung Kim
2013-09-04 8:10 ` Masami Hiramatsu
2013-09-04 18:00 ` Hemant
2013-09-04 17:50 ` Hemant
2013-09-03 8:25 ` [RFC PATCH 0/2] Perf support to SDT markers Ingo Molnar
2013-09-03 9:17 ` Masami Hiramatsu
2013-09-03 13:23 ` Hemant
2013-09-03 14:21 ` Ingo Molnar
2013-09-03 15:11 ` Mark Wielaard
2013-09-03 19:24 ` Ingo Molnar
2013-09-03 15:24 ` Hemant
2013-09-04 6:49 ` Namhyung Kim
2013-09-04 8:22 ` Masami Hiramatsu
2013-09-04 8:25 ` Mark Wielaard
2013-09-04 8:39 ` Masami Hiramatsu
2013-09-04 18:08 ` Hemant
2013-09-05 4:59 ` Masami Hiramatsu
2013-09-04 18:12 ` Hemant
2013-09-04 18:52 ` Mark Wielaard
2013-09-04 20:39 ` Hemant
2013-09-04 17:45 ` Hemant
2013-09-04 6:08 ` Namhyung Kim
2013-09-04 17:08 ` Hemant
2013-09-04 23:41 ` Andi Kleen
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=87ioyht7e4.fsf@sejong.aot.lge.com \
--to=namhyung@kernel.org \
--cc=anton@redhat.com \
--cc=hkshaw@linux.vnet.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=peterz@infradead.org \
--cc=srikar@linux.vnet.ibm.com \
--cc=systemtap@sourceware.org \
/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.