From: Hemant Kumar <hemant@linux.vnet.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: acme@kernel.org, masami.hiramatsu.pt@hitachi.com, mjw@redhat.com,
sukadev@linux.vnet.ibm.com, linuxppc-dev@lists.ozlabs.org,
srikar@linux.vnet.ibm.com, naveen.n.rao@linux.vnet.ibm.com,
hemant@linux.vnet.ibm.com
Subject: [PATCH] perf/probe: Search both .eh_frame and .debug_frame sections for probe location
Date: Thu, 24 Sep 2015 07:46:30 +0530 [thread overview]
Message-ID: <1443060990-10313-1-git-send-email-hemant@linux.vnet.ibm.com> (raw)
perf probe through debuginfo__find_probes() in util/probe-finder.c
checks for the functions' frame descriptions in either .eh_frame section
of an ELF or the .debug_frame. The check is based on whether either one
of these sections is present. But sometimes, it may happen that,
.eh_frame, even if present, may not be complete and may miss some
descriptions. For e.g., in powerpc, this may happen :
$ gcc -g bin.c -o bin
$ objdump --dwarf ./bin
<1><145>: Abbrev Number: 7 (DW_TAG_subprogram)
<146> DW_AT_external : 1
<146> DW_AT_name : (indirect string, offset: 0x9e): main
<14a> DW_AT_decl_file : 1
<14b> DW_AT_decl_line : 39
<14c> DW_AT_prototyped : 1
<14c> DW_AT_type : <0x57>
<150> DW_AT_low_pc : 0x100007b8
If the .eh_frame and .debug_frame are checked for the same binary, we
will find that, .eh_frame (although present) doesn't contain a
description for "main" function.
But, .debug_frame has a description :
000000d8 00000024 00000000 FDE cie=00000000 pc=100007b8..10000838
DW_CFA_advance_loc: 16 to 100007c8
DW_CFA_def_cfa_offset: 144
DW_CFA_offset_extended_sf: r65 at cfa+16
...
Due to this (since, perf checks whether .eh_frame is present and goes on
searching for that address inside that frame), perf is unable to process
the probes :
# perf probe -x ./bin main
Failed to get call frame on 0x100007b8
Error: Failed to add events.
To avoid this issue, we need to check both the sections (.eh_frame and
.debug_frame), which is done in this patch.
Note that, we can always force everything into both .eh_frame and
.debug_frame by :
$ gcc bin.c -fasynchronous-unwind-tables -fno-dwarf2-cfi-asm -g -o bin
Signed-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>
---
tools/perf/util/probe-finder.c | 59 +++++++++++++++++++++++++-----------------
1 file changed, 35 insertions(+), 24 deletions(-)
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 2da65a7..7ce02b9 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -1022,9 +1022,8 @@ static int pubname_search_cb(Dwarf *dbg, Dwarf_Global *gl, void *data)
return DWARF_CB_OK;
}
-/* Find probe points from debuginfo */
-static int debuginfo__find_probes(struct debuginfo *dbg,
- struct probe_finder *pf)
+static int debuginfo__find_probe_location(struct debuginfo *dbg,
+ struct probe_finder *pf)
{
struct perf_probe_point *pp = &pf->pev->point;
Dwarf_Off off, noff;
@@ -1032,27 +1031,6 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
Dwarf_Die *diep;
int ret = 0;
-#if _ELFUTILS_PREREQ(0, 142)
- Elf *elf;
- GElf_Ehdr ehdr;
- GElf_Shdr shdr;
-
- /* Get the call frame information from this dwarf */
- elf = dwarf_getelf(dbg->dbg);
- if (elf == NULL)
- return -EINVAL;
-
- if (gelf_getehdr(elf, &ehdr) == NULL)
- return -EINVAL;
-
- if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
- shdr.sh_type == SHT_PROGBITS) {
- pf->cfi = dwarf_getcfi_elf(elf);
- } else {
- pf->cfi = dwarf_getcfi(dbg->dbg);
- }
-#endif
-
off = 0;
pf->lcache = intlist__new(NULL);
if (!pf->lcache)
@@ -1115,6 +1093,39 @@ found:
return ret;
}
+/* Find probe points from debuginfo */
+static int debuginfo__find_probes(struct debuginfo *dbg,
+ struct probe_finder *pf)
+{
+ int ret = 0;
+
+#if _ELFUTILS_PREREQ(0, 142)
+ Elf *elf;
+ GElf_Ehdr ehdr;
+ GElf_Shdr shdr;
+
+ /* Get the call frame information from this dwarf */
+ elf = dwarf_getelf(dbg->dbg);
+ if (elf == NULL)
+ return -EINVAL;
+
+ if (gelf_getehdr(elf, &ehdr) == NULL)
+ return -EINVAL;
+
+ if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) &&
+ shdr.sh_type == SHT_PROGBITS) {
+ pf->cfi = dwarf_getcfi_elf(elf);
+ ret = debuginfo__find_probe_location(dbg, pf);
+ if (ret >= 0)
+ return ret;
+ }
+ pf->cfi = dwarf_getcfi(dbg->dbg);
+#endif
+
+ ret = debuginfo__find_probe_location(dbg, pf);
+ return ret;
+}
+
struct local_vars_finder {
struct probe_finder *pf;
struct perf_probe_arg *args;
--
1.9.3
next reply other threads:[~2015-09-24 2:17 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-24 2:16 Hemant Kumar [this message]
2015-09-24 9:59 ` Mark Wielaard
2015-09-24 10:56 ` 平松雅巳 / HIRAMATU,MASAMI
2015-09-24 11:23 ` Mark Wielaard
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=1443060990-10313-1-git-send-email-hemant@linux.vnet.ibm.com \
--to=hemant@linux.vnet.ibm.com \
--cc=acme@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mjw@redhat.com \
--cc=naveen.n.rao@linux.vnet.ibm.com \
--cc=srikar@linux.vnet.ibm.com \
--cc=sukadev@linux.vnet.ibm.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®