On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead, in dwarf format.
This patch set uses libunwind to load and parse the dwarf debug info from
the .debug_frame section if no .eh_frame_hdr section is found; also it
sets the hooks in the perf_regs and libunwind code for ARMv7.
Dependencies:
. if present, libunwind >= 1.1 is needed to prevent a segfault when
parsing the dwarf info,
. libunwind needs to be configured with --enable-debug-frame
to prevent a linkage error. Note: --enable-debug-frame is automatically
selected on ARM).
The generated perf has been tested on ARMv7 (OMAP4, Marvell Armada XP) and
x86_64, using the following commands:
perf record -g [dwarf] -- <binary>
perf report --sort symbol --call-graph --stdio
Jean Pihet (2):
perf tools: Check libunwind for availability of dwarf parsing feature
perf: parse the .debug_frame section in case .eh_frame is not present
Will Deacon (2):
ARM: perf: add support for perf registers API
ARM: perf: wire up perf_regs and unwind support for ARM
arch/arm/Kconfig | 2 +
arch/arm/include/uapi/asm/Kbuild | 1 +
arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/perf_regs.c | 30 ++++++++++++++
tools/perf/arch/arm/Makefile | 3 ++
tools/perf/arch/arm/include/perf_regs.h | 54 +++++++++++++++++++++++++
tools/perf/arch/arm/util/unwind.c | 48 ++++++++++++++++++++++
tools/perf/config/Makefile | 7 +++-
tools/perf/config/feature-tests.mak | 11 ++++-
tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++--------
11 files changed, 232 insertions(+), 19 deletions(-)
create mode 100644 arch/arm/include/uapi/asm/perf_regs.h
create mode 100644 arch/arm/kernel/perf_regs.c
create mode 100644 tools/perf/arch/arm/include/perf_regs.h
create mode 100644 tools/perf/arch/arm/util/unwind.c
--
1.7.11.7
From: Will Deacon <[email protected]>
This patch hooks in the perf_regs and libunwind code for ARM.
Signed-off-by: Will Deacon <[email protected]>
Cc: Jean Pihet <[email protected]>
---
tools/perf/arch/arm/Makefile | 3 ++
tools/perf/arch/arm/include/perf_regs.h | 54 +++++++++++++++++++++++++++++++++
tools/perf/arch/arm/util/unwind.c | 48 +++++++++++++++++++++++++++++
tools/perf/config/Makefile | 7 +++--
4 files changed, 110 insertions(+), 2 deletions(-)
create mode 100644 tools/perf/arch/arm/include/perf_regs.h
create mode 100644 tools/perf/arch/arm/util/unwind.c
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
index 15130b5..fe9b61e 100644
--- a/tools/perf/arch/arm/Makefile
+++ b/tools/perf/arch/arm/Makefile
@@ -2,3 +2,6 @@ ifndef NO_DWARF
PERF_HAVE_DWARF_REGS := 1
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
endif
+ifndef NO_LIBUNWIND
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
+endif
diff --git a/tools/perf/arch/arm/include/perf_regs.h b/tools/perf/arch/arm/include/perf_regs.h
new file mode 100644
index 0000000..2a1cfde
--- /dev/null
+++ b/tools/perf/arch/arm/include/perf_regs.h
@@ -0,0 +1,54 @@
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include "../../util/types.h"
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MASK ((1ULL << PERF_REG_ARM_MAX) - 1)
+#define PERF_REG_IP PERF_REG_ARM_PC
+#define PERF_REG_SP PERF_REG_ARM_SP
+
+static inline const char *perf_reg_name(int id)
+{
+ switch (id) {
+ case PERF_REG_ARM_R0:
+ return "r0";
+ case PERF_REG_ARM_R1:
+ return "r1";
+ case PERF_REG_ARM_R2:
+ return "r2";
+ case PERF_REG_ARM_R3:
+ return "r3";
+ case PERF_REG_ARM_R4:
+ return "r4";
+ case PERF_REG_ARM_R5:
+ return "r5";
+ case PERF_REG_ARM_R6:
+ return "r6";
+ case PERF_REG_ARM_R7:
+ return "r7";
+ case PERF_REG_ARM_R8:
+ return "r8";
+ case PERF_REG_ARM_R9:
+ return "r9";
+ case PERF_REG_ARM_R10:
+ return "r10";
+ case PERF_REG_ARM_FP:
+ return "fp";
+ case PERF_REG_ARM_IP:
+ return "ip";
+ case PERF_REG_ARM_SP:
+ return "sp";
+ case PERF_REG_ARM_LR:
+ return "lr";
+ case PERF_REG_ARM_PC:
+ return "pc";
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/arm/util/unwind.c b/tools/perf/arch/arm/util/unwind.c
new file mode 100644
index 0000000..da3dc95
--- /dev/null
+++ b/tools/perf/arch/arm/util/unwind.c
@@ -0,0 +1,48 @@
+
+#include <errno.h>
+#include <libunwind.h>
+#include "perf_regs.h"
+#include "../../util/unwind.h"
+
+int unwind__arch_reg_id(int regnum)
+{
+ switch (regnum) {
+ case UNW_ARM_R0:
+ return PERF_REG_ARM_R0;
+ case UNW_ARM_R1:
+ return PERF_REG_ARM_R1;
+ case UNW_ARM_R2:
+ return PERF_REG_ARM_R2;
+ case UNW_ARM_R3:
+ return PERF_REG_ARM_R3;
+ case UNW_ARM_R4:
+ return PERF_REG_ARM_R4;
+ case UNW_ARM_R5:
+ return PERF_REG_ARM_R5;
+ case UNW_ARM_R6:
+ return PERF_REG_ARM_R6;
+ case UNW_ARM_R7:
+ return PERF_REG_ARM_R7;
+ case UNW_ARM_R8:
+ return PERF_REG_ARM_R8;
+ case UNW_ARM_R9:
+ return PERF_REG_ARM_R9;
+ case UNW_ARM_R10:
+ return PERF_REG_ARM_R10;
+ case UNW_ARM_R11:
+ return PERF_REG_ARM_FP;
+ case UNW_ARM_R12:
+ return PERF_REG_ARM_IP;
+ case UNW_ARM_R13:
+ return PERF_REG_ARM_SP;
+ case UNW_ARM_R14:
+ return PERF_REG_ARM_LR;
+ case UNW_ARM_R15:
+ return PERF_REG_ARM_PC;
+ default:
+ pr_err("unwind: invalid reg id %d\n", regnum);
+ return -EINVAL;
+ }
+
+ return -EINVAL;
+}
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 214e17e..4b65710 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -29,6 +29,10 @@ ifeq ($(ARCH),x86_64)
NO_PERF_REGS := 0
LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
endif
+ifeq ($(ARCH),arm)
+ NO_PERF_REGS := 0
+ LIBUNWIND_LIBS = -lunwind -lunwind-arm
+endif
ifeq ($(NO_PERF_REGS),0)
CFLAGS += -DHAVE_PERF_REGS
@@ -205,8 +209,7 @@ ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
endif # try-cc
endif # NO_LIBELF
-# There's only x86 (both 32 and 64) support for CFI unwind so far
-ifneq ($(ARCH),x86)
+ifeq ($(LIBUNWIND_LIBS),)
NO_LIBUNWIND := 1
endif
--
1.7.11.7
On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead, in the dwarf format.
Use libunwind to load and parse the debug info.
Dependencies:
. if present, libunwind >= 1.1 is needed to prevent a segfault when
parsing the dwarf info,
. libunwind needs to be configured with --enable-debug-frame
to prevent a linkage error. Note: --enable-debug-frame is automatically
selected on ARM).
Signed-off-by: Jean Pihet <[email protected]>
---
tools/perf/config/Makefile | 2 +-
tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++++++++++++-----------
2 files changed, 56 insertions(+), 17 deletions(-)
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 2f891f7..429a99c 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,6 +39,15 @@ UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+ unw_word_t ip,
+ unw_word_t segbase,
+ const char *obj_name, unw_word_t start,
+ unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
#define DW_EH_PE_APPL_MASK 0x70 /* how the value is to be applied */
@@ -245,8 +254,9 @@ static int unwind_spec_ehframe(struct dso *dso, struct machine *machine,
return 0;
}
-static int read_unwind_spec(struct dso *dso, struct machine *machine,
- u64 *table_data, u64 *segbase, u64 *fde_count)
+static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
+ u64 *table_data, u64 *segbase,
+ u64 *fde_count)
{
int ret = -EINVAL, fd;
u64 offset;
@@ -255,6 +265,7 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
if (fd < 0)
return -EINVAL;
+ /* Check the .eh_frame section for unwinding info */
offset = elf_section_offset(fd, ".eh_frame_hdr");
close(fd);
@@ -263,10 +274,27 @@ static int read_unwind_spec(struct dso *dso, struct machine *machine,
table_data, segbase,
fde_count);
- /* TODO .debug_frame check if eh_frame_hdr fails */
return ret;
}
+static int read_unwind_spec_debug_frame(struct dso *dso,
+ struct machine *machine, u64 *offset)
+{
+ int fd = dso__data_fd(dso, machine);
+
+ if (fd < 0)
+ return -EINVAL;
+
+ /* Check the .debug_frame section for unwinding info */
+ *offset = elf_section_offset(fd, ".debug_frame");
+ close(fd);
+
+ if (*offset)
+ return 0;
+
+ return -EINVAL;
+}
+
static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
{
struct addr_location al;
@@ -291,20 +319,31 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
pr_debug("unwind: find_proc_info dso %s\n", map->dso->name);
- if (read_unwind_spec(map->dso, ui->machine,
- &table_data, &segbase, &fde_count))
- return -EINVAL;
+ /* Check the .eh_frame section for unwinding info */
+ if (!read_unwind_spec_eh_frame(map->dso, ui->machine,
+ &table_data, &segbase, &fde_count)) {
+ memset(&di, 0, sizeof(di));
+ di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
+ di.start_ip = map->start;
+ di.end_ip = map->end;
+ di.u.rti.segbase = map->start + segbase;
+ di.u.rti.table_data = map->start + table_data;
+ di.u.rti.table_len = fde_count * sizeof(struct table_entry)
+ / sizeof(unw_word_t);
+ return dwarf_search_unwind_table(as, ip, &di, pi,
+ need_unwind_info, arg);
+ }
+
+ /* Check the .debug_frame section for unwinding info */
+ if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
+ memset(&di, 0, sizeof(di));
+ dwarf_find_debug_frame(0, &di, ip, 0, map->dso->name,
+ map->start, map->end);
+ return dwarf_search_unwind_table(as, ip, &di, pi,
+ need_unwind_info, arg);
+ }
- memset(&di, 0, sizeof(di));
- di.format = UNW_INFO_FORMAT_REMOTE_TABLE;
- di.start_ip = map->start;
- di.end_ip = map->end;
- di.u.rti.segbase = map->start + segbase;
- di.u.rti.table_data = map->start + table_data;
- di.u.rti.table_len = fde_count * sizeof(struct table_entry)
- / sizeof(unw_word_t);
- return dwarf_search_unwind_table(as, ip, &di, pi,
- need_unwind_info, arg);
+ return -EINVAL;
}
static int access_fpreg(unw_addr_space_t __maybe_unused as,
--
1.7.11.7
From: Will Deacon <[email protected]>
This patch implements the functions required for the perf registers API,
allowing the perf tool to interface kernel register dumps with libunwind
in order to provide userspace backtracing.
Signed-off-by: Will Deacon <[email protected]>
Cc: Jean Pihet <[email protected]>
---
arch/arm/Kconfig | 2 ++
arch/arm/include/uapi/asm/Kbuild | 1 +
arch/arm/include/uapi/asm/perf_regs.h | 23 +++++++++++++++++++++++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/perf_regs.c | 30 ++++++++++++++++++++++++++++++
5 files changed, 57 insertions(+)
create mode 100644 arch/arm/include/uapi/asm/perf_regs.h
create mode 100644 arch/arm/kernel/perf_regs.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3f7714d..5595888 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -51,6 +51,8 @@ config ARM
select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_PERF_EVENTS
+ select HAVE_PERF_REGS
+ select HAVE_PERF_USER_STACK_DUMP
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UID16
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index 18d76fd..70a1c9d 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -7,6 +7,7 @@ header-y += hwcap.h
header-y += ioctls.h
header-y += kvm_para.h
header-y += mman.h
+header-y += perf_regs.h
header-y += posix_types.h
header-y += ptrace.h
header-y += setup.h
diff --git a/arch/arm/include/uapi/asm/perf_regs.h b/arch/arm/include/uapi/asm/perf_regs.h
new file mode 100644
index 0000000..ce59448
--- /dev/null
+++ b/arch/arm/include/uapi/asm/perf_regs.h
@@ -0,0 +1,23 @@
+#ifndef _ASM_ARM_PERF_REGS_H
+#define _ASM_ARM_PERF_REGS_H
+
+enum perf_event_arm_regs {
+ PERF_REG_ARM_R0,
+ PERF_REG_ARM_R1,
+ PERF_REG_ARM_R2,
+ PERF_REG_ARM_R3,
+ PERF_REG_ARM_R4,
+ PERF_REG_ARM_R5,
+ PERF_REG_ARM_R6,
+ PERF_REG_ARM_R7,
+ PERF_REG_ARM_R8,
+ PERF_REG_ARM_R9,
+ PERF_REG_ARM_R10,
+ PERF_REG_ARM_FP,
+ PERF_REG_ARM_IP,
+ PERF_REG_ARM_SP,
+ PERF_REG_ARM_LR,
+ PERF_REG_ARM_PC,
+ PERF_REG_ARM_MAX,
+};
+#endif /* _ASM_ARM_PERF_REGS_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 5140df5f..9b818ca 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_CPU_XSC3) += xscale-cp0.o
obj-$(CONFIG_CPU_MOHAWK) += xscale-cp0.o
obj-$(CONFIG_CPU_PJ4) += pj4-cp0.o
obj-$(CONFIG_IWMMXT) += iwmmxt.o
+obj-$(CONFIG_PERF_EVENTS) += perf_regs.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o perf_event_cpu.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c
new file mode 100644
index 0000000..6e4379c
--- /dev/null
+++ b/arch/arm/kernel/perf_regs.c
@@ -0,0 +1,30 @@
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+ if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX))
+ return 0;
+
+ return regs->uregs[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_ARM_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+ if (!mask || mask & REG_RESERVED)
+ return -EINVAL;
+
+ return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+ return PERF_SAMPLE_REGS_ABI_32;
+}
--
1.7.11.7
The newly added dwarf unwinding feature [1] requires:
. a recent version (>= 1.1) of libunwind,
. libunwind to be configured with --enable-debug-frame.
[1] http://www.spinics.net/lists/kernel/msg1598951.html
Add the corresponding API test in the feature check list.
Signed-off-by: Jean Pihet <[email protected]>
---
tools/perf/config/Makefile | 2 +-
tools/perf/config/feature-tests.mak | 11 ++++++++++-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 4b65710..395bc41 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -223,7 +223,7 @@ endif
FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
- msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
+ msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
NO_LIBUNWIND := 1
endif # Libunwind support
endif # NO_LIBUNWIND
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 708fb8e..87124d0 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -176,14 +176,23 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
unw_proc_info_t *pi,
int need_unwind_info, void *arg);
-
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+extern int
+UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
+ unw_word_t ip,
+ unw_word_t segbase,
+ const char *obj_name, unw_word_t start,
+ unw_word_t end);
+
+#define dwarf_find_debug_frame UNW_OBJ(dwarf_find_debug_frame)
+
int main(void)
{
unw_addr_space_t addr_space;
addr_space = unw_create_addr_space(NULL, 0);
unw_init_remote(NULL, addr_space, NULL);
+ dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
return 0;
}
--
1.7.11.7
Arnaldo, Ingo,
On Mon, Sep 16, 2013 at 10:17:32AM +0100, Jean Pihet wrote:
> The newly added dwarf unwinding feature [1] requires:
> . a recent version (>= 1.1) of libunwind,
> . libunwind to be configured with --enable-debug-frame.
>
> [1] http://www.spinics.net/lists/kernel/msg1598951.html
>
> Add the corresponding API test in the feature check list.
>
> Signed-off-by: Jean Pihet <[email protected]>
> ---
> tools/perf/config/Makefile | 2 +-
> tools/perf/config/feature-tests.mak | 11 ++++++++++-
> 2 files changed, 11 insertions(+), 2 deletions(-)
Can I have an ack for this and the following patch please?
(http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/198531.html)
Then I can stick these into -next for some more exposure before I queue them
for 3.13.
Cheers,
Will
Hin
On 17 September 2013 12:29, Will Deacon <[email protected]> wrote:
> Arnaldo, Ingo,
>
> On Mon, Sep 16, 2013 at 10:17:32AM +0100, Jean Pihet wrote:
>> The newly added dwarf unwinding feature [1] requires:
>> . a recent version (>= 1.1) of libunwind,
>> . libunwind to be configured with --enable-debug-frame.
>>
>> [1] http://www.spinics.net/lists/kernel/msg1598951.html
>>
>> Add the corresponding API test in the feature check list.
>>
>> Signed-off-by: Jean Pihet <[email protected]>
>> ---
>> tools/perf/config/Makefile | 2 +-
>> tools/perf/config/feature-tests.mak | 11 ++++++++++-
>> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> Can I have an ack for this and the following patch please?
>
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/198531.html)
>
> Then I can stick these into -next for some more exposure before I queue them
> for 3.13.
>
> Cheers,
>
> Will
Ping on the series. The two patches above (3/4 and 4/4) are generic
while the two others are impacting ARM only.
Is it possible to get an Ack for the generic ones?
Kind regards,
Jean
On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
> Hin
>
> On 17 September 2013 12:29, Will Deacon <[email protected]> wrote:
> > Arnaldo, Ingo,
> >
> > On Mon, Sep 16, 2013 at 10:17:32AM +0100, Jean Pihet wrote:
> >> The newly added dwarf unwinding feature [1] requires:
> >> . a recent version (>= 1.1) of libunwind,
> >> . libunwind to be configured with --enable-debug-frame.
> >>
> >> [1] http://www.spinics.net/lists/kernel/msg1598951.html
> >>
> >> Add the corresponding API test in the feature check list.
> >>
> >> Signed-off-by: Jean Pihet <[email protected]>
> >> ---
> >> tools/perf/config/Makefile | 2 +-
> >> tools/perf/config/feature-tests.mak | 11 ++++++++++-
> >> 2 files changed, 11 insertions(+), 2 deletions(-)
> >
> > Can I have an ack for this and the following patch please?
> >
> > (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/198531.html)
> >
> > Then I can stick these into -next for some more exposure before I queue them
> > for 3.13.
> >
> > Cheers,
> >
> > Will
>
> Ping on the series. The two patches above (3/4 and 4/4) are generic
> while the two others are impacting ARM only.
> Is it possible to get an Ack for the generic ones?
I'm fine with those changes.. still I'm sort of worried about
current DWARF unwind users (but not sure if there're any),
who depends on packaged libunwind compiled without
--enable-debug-frame option.
I've seen your libunwind patch to make it default, but
not sure if it was accepted.. if not, maybe we should
detect this and build that code conditionaly.
thoughts anyone?
jirka
On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
> > Ping on the series. The two patches above (3/4 and 4/4) are generic
> > while the two others are impacting ARM only.
> > Is it possible to get an Ack for the generic ones?
>
> I'm fine with those changes.. still I'm sort of worried about
> current DWARF unwind users (but not sure if there're any),
> who depends on packaged libunwind compiled without
> --enable-debug-frame option.
Since x86 is the only architecture using libunwind with perf at the moment,
and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
are any existing users to worry about.
> I've seen your libunwind patch to make it default, but
> not sure if it was accepted.. if not, maybe we should
> detect this and build that code conditionaly.
It certainly defaults to "on" for ARM, but other architectures have to
enable it explicitly afaict.
Will
Hi Jiri, Will,
On 24 September 2013 12:06, Will Deacon <[email protected]> wrote:
> On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
>> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
>> > Ping on the series. The two patches above (3/4 and 4/4) are generic
>> > while the two others are impacting ARM only.
>> > Is it possible to get an Ack for the generic ones?
>>
>> I'm fine with those changes.. still I'm sort of worried about
>> current DWARF unwind users (but not sure if there're any),
>> who depends on packaged libunwind compiled without
>> --enable-debug-frame option.
>
> Since x86 is the only architecture using libunwind with perf at the moment,
> and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
> are any existing users to worry about.
Right
>
>> I've seen your libunwind patch to make it default, but
>> not sure if it was accepted.. if not, maybe we should
>> detect this and build that code conditionaly.
>
> It certainly defaults to "on" for ARM, but other architectures have to
> enable it explicitly afaict.
Yes that is correct.
This patch (3/4) detects if the debug frame code is enabled in
libunwind and uses the lib only if it is the case.
Users that want the feature have to enable it explicitly; the commit
description documents how to do that.
So I think we are safe here.
>
> Will
Thanks,
Jean
Em Tue, Sep 17, 2013 at 11:29:04AM +0100, Will Deacon escreveu:
> Arnaldo, Ingo,
>
> On Mon, Sep 16, 2013 at 10:17:32AM +0100, Jean Pihet wrote:
> > The newly added dwarf unwinding feature [1] requires:
> > . a recent version (>= 1.1) of libunwind,
> > . libunwind to be configured with --enable-debug-frame.
> >
> > [1] http://www.spinics.net/lists/kernel/msg1598951.html
> >
> > Add the corresponding API test in the feature check list.
> >
> > Signed-off-by: Jean Pihet <[email protected]>
> > ---
> > tools/perf/config/Makefile | 2 +-
> > tools/perf/config/feature-tests.mak | 11 ++++++++++-
> > 2 files changed, 11 insertions(+), 2 deletions(-)
>
> Can I have an ack for this and the following patch please?
>
> (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/198531.html)
>
> Then I can stick these into -next for some more exposure before I queue them
> for 3.13.
I can pick it now that Jiri kinda acked it, right Jiri?
- Arnaldo
On Tue, Sep 24, 2013 at 02:03:47PM +0200, Jean Pihet wrote:
> Hi Jiri, Will,
>
> On 24 September 2013 12:06, Will Deacon <[email protected]> wrote:
> > On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
> >> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
> >> > Ping on the series. The two patches above (3/4 and 4/4) are generic
> >> > while the two others are impacting ARM only.
> >> > Is it possible to get an Ack for the generic ones?
> >>
> >> I'm fine with those changes.. still I'm sort of worried about
> >> current DWARF unwind users (but not sure if there're any),
> >> who depends on packaged libunwind compiled without
> >> --enable-debug-frame option.
> >
> > Since x86 is the only architecture using libunwind with perf at the moment,
> > and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
> > are any existing users to worry about.
> Right
>
> >
> >> I've seen your libunwind patch to make it default, but
> >> not sure if it was accepted.. if not, maybe we should
> >> detect this and build that code conditionaly.
> >
> > It certainly defaults to "on" for ARM, but other architectures have to
> > enable it explicitly afaict.
> Yes that is correct.
> This patch (3/4) detects if the debug frame code is enabled in
> libunwind and uses the lib only if it is the case.
My concern is about users (again, not sure if there are any ;-) )
that use this with packaged libunwind compiled without
--enable-debug-frame option.
For them perf will consider libunwind as 'not available' with
your changes:
...
CHK libunwind
config/Makefile:223: No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1
...
and they'll need to compile their own libunwind
(thats the case on Fedora).
This could be solved by detecting this and make your
code conditional as attached below (not much tested).
thanks,
jirka
---
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index 134b36e..d40cf0a 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -223,6 +223,10 @@ ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
NO_LIBUNWIND := 1
endif # Libunwind support
+ifneq ($(call try-cc,$(SOURCE_LIBUNWIND_DEBUG_FRAME),$(FLAGS_UNWIND),libunwind debug_frame),y)
+ msg := $(warning No debug_frame support found in libunwind);
+CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
+endif
endif # NO_LIBUNWIND
ifndef NO_LIBUNWIND
diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
index 87124d0..645141c 100644
--- a/tools/perf/config/feature-tests.mak
+++ b/tools/perf/config/feature-tests.mak
@@ -178,6 +178,28 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+int main(void)
+{
+ unw_addr_space_t addr_space;
+ addr_space = unw_create_addr_space(NULL, 0);
+ unw_init_remote(NULL, addr_space, NULL);
+ dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
+ return 0;
+}
+endef
+
+define SOURCE_LIBUNWIND_DEBUG_FRAME
+#include <libunwind.h>
+#include <stdlib.h>
+
+extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
+ unw_word_t ip,
+ unw_dyn_info_t *di,
+ unw_proc_info_t *pi,
+ int need_unwind_info, void *arg);
+
+#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
+
extern int
UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
unw_word_t ip,
@@ -189,11 +211,7 @@ UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
int main(void)
{
- unw_addr_space_t addr_space;
- addr_space = unw_create_addr_space(NULL, 0);
- unw_init_remote(NULL, addr_space, NULL);
dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
- dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
return 0;
}
endef
diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 429a99c..231c941 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -277,6 +277,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
return ret;
}
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
static int read_unwind_spec_debug_frame(struct dso *dso,
struct machine *machine, u64 *offset)
{
@@ -294,6 +295,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
return -EINVAL;
}
+#endif
static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
{
@@ -334,6 +336,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
need_unwind_info, arg);
}
+#ifndef NO_LIBUNWIND_DEBUG_FRAME
/* Check the .debug_frame section for unwinding info */
if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
memset(&di, 0, sizeof(di));
@@ -342,7 +345,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
return dwarf_search_unwind_table(as, ip, &di, pi,
need_unwind_info, arg);
}
-
+#endif
return -EINVAL;
}
Hi Jiri,
On 24 September 2013 19:43, Jiri Olsa <[email protected]> wrote:
> On Tue, Sep 24, 2013 at 02:03:47PM +0200, Jean Pihet wrote:
>> Hi Jiri, Will,
>>
>> On 24 September 2013 12:06, Will Deacon <[email protected]> wrote:
>> > On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
>> >> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
>> >> > Ping on the series. The two patches above (3/4 and 4/4) are generic
>> >> > while the two others are impacting ARM only.
>> >> > Is it possible to get an Ack for the generic ones?
>> >>
>> >> I'm fine with those changes.. still I'm sort of worried about
>> >> current DWARF unwind users (but not sure if there're any),
>> >> who depends on packaged libunwind compiled without
>> >> --enable-debug-frame option.
>> >
>> > Since x86 is the only architecture using libunwind with perf at the moment,
>> > and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
>> > are any existing users to worry about.
>> Right
>>
>> >
>> >> I've seen your libunwind patch to make it default, but
>> >> not sure if it was accepted.. if not, maybe we should
>> >> detect this and build that code conditionaly.
>> >
>> > It certainly defaults to "on" for ARM, but other architectures have to
>> > enable it explicitly afaict.
>> Yes that is correct.
>> This patch (3/4) detects if the debug frame code is enabled in
>> libunwind and uses the lib only if it is the case.
>
> My concern is about users (again, not sure if there are any ;-) )
> that use this with packaged libunwind compiled without
> --enable-debug-frame option.
>
> For them perf will consider libunwind as 'not available' with
> your changes:
>
> ...
> CHK libunwind
> config/Makefile:223: No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1
> ...
>
> and they'll need to compile their own libunwind
> (thats the case on Fedora).
>
> This could be solved by detecting this and make your
> code conditional as attached below (not much tested).
Ok that makes sense.
Let me integrate this in the patch series, test it (on ARM and x86)
and re-submit. Is that OK?
Regards,
Jean
>
> thanks,
> jirka
>
>
> ---
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 134b36e..d40cf0a 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -223,6 +223,10 @@ ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
> msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1);
> NO_LIBUNWIND := 1
> endif # Libunwind support
> +ifneq ($(call try-cc,$(SOURCE_LIBUNWIND_DEBUG_FRAME),$(FLAGS_UNWIND),libunwind debug_frame),y)
> + msg := $(warning No debug_frame support found in libunwind);
> +CFLAGS += -DNO_LIBUNWIND_DEBUG_FRAME
> +endif
> endif # NO_LIBUNWIND
>
> ifndef NO_LIBUNWIND
> diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak
> index 87124d0..645141c 100644
> --- a/tools/perf/config/feature-tests.mak
> +++ b/tools/perf/config/feature-tests.mak
> @@ -178,6 +178,28 @@ extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
>
> #define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
>
> +int main(void)
> +{
> + unw_addr_space_t addr_space;
> + addr_space = unw_create_addr_space(NULL, 0);
> + unw_init_remote(NULL, addr_space, NULL);
> + dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
> + return 0;
> +}
> +endef
> +
> +define SOURCE_LIBUNWIND_DEBUG_FRAME
> +#include <libunwind.h>
> +#include <stdlib.h>
> +
> +extern int UNW_OBJ(dwarf_search_unwind_table) (unw_addr_space_t as,
> + unw_word_t ip,
> + unw_dyn_info_t *di,
> + unw_proc_info_t *pi,
> + int need_unwind_info, void *arg);
> +
> +#define dwarf_search_unwind_table UNW_OBJ(dwarf_search_unwind_table)
> +
> extern int
> UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
> unw_word_t ip,
> @@ -189,11 +211,7 @@ UNW_OBJ(dwarf_find_debug_frame) (int found, unw_dyn_info_t *di_debug,
>
> int main(void)
> {
> - unw_addr_space_t addr_space;
> - addr_space = unw_create_addr_space(NULL, 0);
> - unw_init_remote(NULL, addr_space, NULL);
> dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0);
> - dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);
> return 0;
> }
> endef
> diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
> index 429a99c..231c941 100644
> --- a/tools/perf/util/unwind.c
> +++ b/tools/perf/util/unwind.c
> @@ -277,6 +277,7 @@ static int read_unwind_spec_eh_frame(struct dso *dso, struct machine *machine,
> return ret;
> }
>
> +#ifndef NO_LIBUNWIND_DEBUG_FRAME
> static int read_unwind_spec_debug_frame(struct dso *dso,
> struct machine *machine, u64 *offset)
> {
> @@ -294,6 +295,7 @@ static int read_unwind_spec_debug_frame(struct dso *dso,
>
> return -EINVAL;
> }
> +#endif
>
> static struct map *find_map(unw_word_t ip, struct unwind_info *ui)
> {
> @@ -334,6 +336,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
> need_unwind_info, arg);
> }
>
> +#ifndef NO_LIBUNWIND_DEBUG_FRAME
> /* Check the .debug_frame section for unwinding info */
> if (!read_unwind_spec_debug_frame(map->dso, ui->machine, &segbase)) {
> memset(&di, 0, sizeof(di));
> @@ -342,7 +345,7 @@ find_proc_info(unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
> return dwarf_search_unwind_table(as, ip, &di, pi,
> need_unwind_info, arg);
> }
> -
> +#endif
> return -EINVAL;
> }
>
On Wed, Sep 25, 2013 at 08:53:44AM +0200, Jean Pihet wrote:
> Hi Jiri,
>
> On 24 September 2013 19:43, Jiri Olsa <[email protected]> wrote:
> > On Tue, Sep 24, 2013 at 02:03:47PM +0200, Jean Pihet wrote:
> >> Hi Jiri, Will,
> >>
> >> On 24 September 2013 12:06, Will Deacon <[email protected]> wrote:
> >> > On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
> >> >> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
> >> >> > Ping on the series. The two patches above (3/4 and 4/4) are generic
> >> >> > while the two others are impacting ARM only.
> >> >> > Is it possible to get an Ack for the generic ones?
> >> >>
> >> >> I'm fine with those changes.. still I'm sort of worried about
> >> >> current DWARF unwind users (but not sure if there're any),
> >> >> who depends on packaged libunwind compiled without
> >> >> --enable-debug-frame option.
> >> >
> >> > Since x86 is the only architecture using libunwind with perf at the moment,
> >> > and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
> >> > are any existing users to worry about.
> >> Right
> >>
> >> >
> >> >> I've seen your libunwind patch to make it default, but
> >> >> not sure if it was accepted.. if not, maybe we should
> >> >> detect this and build that code conditionaly.
> >> >
> >> > It certainly defaults to "on" for ARM, but other architectures have to
> >> > enable it explicitly afaict.
> >> Yes that is correct.
> >> This patch (3/4) detects if the debug frame code is enabled in
> >> libunwind and uses the lib only if it is the case.
> >
> > My concern is about users (again, not sure if there are any ;-) )
> > that use this with packaged libunwind compiled without
> > --enable-debug-frame option.
> >
> > For them perf will consider libunwind as 'not available' with
> > your changes:
> >
> > ...
> > CHK libunwind
> > config/Makefile:223: No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1
> > ...
> >
> > and they'll need to compile their own libunwind
> > (thats the case on Fedora).
> >
> > This could be solved by detecting this and make your
> > code conditional as attached below (not much tested).
> Ok that makes sense.
> Let me integrate this in the patch series, test it (on ARM and x86)
> and re-submit. Is that OK?
that'd be great
thanks,
jirka
Hi Jiri, Will,
I just sent the reworked series as '[PATCH v3 0/4] perf: parse the
dwarf backtrace info from .debug_frame section'.
Tested on x86 and ARMv7.
Regards,
Jean
On 25 September 2013 09:31, Jiri Olsa <[email protected]> wrote:
> On Wed, Sep 25, 2013 at 08:53:44AM +0200, Jean Pihet wrote:
>> Hi Jiri,
>>
>> On 24 September 2013 19:43, Jiri Olsa <[email protected]> wrote:
>> > On Tue, Sep 24, 2013 at 02:03:47PM +0200, Jean Pihet wrote:
>> >> Hi Jiri, Will,
>> >>
>> >> On 24 September 2013 12:06, Will Deacon <[email protected]> wrote:
>> >> > On Tue, Sep 24, 2013 at 10:34:50AM +0100, Jiri Olsa wrote:
>> >> >> On Tue, Sep 24, 2013 at 10:55:32AM +0200, Jean Pihet wrote:
>> >> >> > Ping on the series. The two patches above (3/4 and 4/4) are generic
>> >> >> > while the two others are impacting ARM only.
>> >> >> > Is it possible to get an Ack for the generic ones?
>> >> >>
>> >> >> I'm fine with those changes.. still I'm sort of worried about
>> >> >> current DWARF unwind users (but not sure if there're any),
>> >> >> who depends on packaged libunwind compiled without
>> >> >> --enable-debug-frame option.
>> >> >
>> >> > Since x86 is the only architecture using libunwind with perf at the moment,
>> >> > and I'd expect it to use .eh_frame for unwinding, I'm also not sure there
>> >> > are any existing users to worry about.
>> >> Right
>> >>
>> >> >
>> >> >> I've seen your libunwind patch to make it default, but
>> >> >> not sure if it was accepted.. if not, maybe we should
>> >> >> detect this and build that code conditionaly.
>> >> >
>> >> > It certainly defaults to "on" for ARM, but other architectures have to
>> >> > enable it explicitly afaict.
>> >> Yes that is correct.
>> >> This patch (3/4) detects if the debug frame code is enabled in
>> >> libunwind and uses the lib only if it is the case.
>> >
>> > My concern is about users (again, not sure if there are any ;-) )
>> > that use this with packaged libunwind compiled without
>> > --enable-debug-frame option.
>> >
>> > For them perf will consider libunwind as 'not available' with
>> > your changes:
>> >
>> > ...
>> > CHK libunwind
>> > config/Makefile:223: No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 1.1
>> > ...
>> >
>> > and they'll need to compile their own libunwind
>> > (thats the case on Fedora).
>> >
>> > This could be solved by detecting this and make your
>> > code conditional as attached below (not much tested).
>> Ok that makes sense.
>> Let me integrate this in the patch series, test it (on ARM and x86)
>> and re-submit. Is that OK?
>
> that'd be great
>
> thanks,
> jirka
Hi Arnaldo,
On Tue, Sep 24, 2013 at 06:12:20PM +0100, Arnaldo Carvalho de Melo wrote:
> Em Tue, Sep 17, 2013 at 11:29:04AM +0100, Will Deacon escreveu:
> > Arnaldo, Ingo,
> >
> > On Mon, Sep 16, 2013 at 10:17:32AM +0100, Jean Pihet wrote:
> > > The newly added dwarf unwinding feature [1] requires:
> > > . a recent version (>= 1.1) of libunwind,
> > > . libunwind to be configured with --enable-debug-frame.
> > >
> > > [1] http://www.spinics.net/lists/kernel/msg1598951.html
> > >
> > > Add the corresponding API test in the feature check list.
> > >
> > > Signed-off-by: Jean Pihet <[email protected]>
> > > ---
> > > tools/perf/config/Makefile | 2 +-
> > > tools/perf/config/feature-tests.mak | 11 ++++++++++-
> > > 2 files changed, 11 insertions(+), 2 deletions(-)
> >
> > Can I have an ack for this and the following patch please?
> >
> > (http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/198531.html)
> >
> > Then I can stick these into -next for some more exposure before I queue them
> > for 3.13.
>
> I can pick it now that Jiri kinda acked it, right Jiri?
Jiri ended up acking v3 of the patches:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-September/200579.html
but I don't see them in -next. I'm happy to take them via my tree, just want
to make sure they don't conflict with anything you have planned for 3.13
and/or end up with our trees colliding in -next.
What's the plan?
Cheers,
Will