2013-09-09 10:00:44

by Jean Pihet

[permalink] [raw]
Subject: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section

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 and x86_64, using the
following commands:
perf record -g [dwarf] -- <binary>
perf report --sort symbol --call-graph --stdio


Jean Pihet (1):
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 | 9 +++--
tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++--------
10 files changed, 223 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


2013-09-09 10:00:47

by Jean Pihet

[permalink] [raw]
Subject: [PATCH 1/3] ARM: perf: add support for perf registers API

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 86bf7cb..642bc48 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -49,6 +49,8 @@ config ARM
select HAVE_MEMBLOCK
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 86d10dd..c9e05f2 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

2013-09-09 10:00:52

by Jean Pihet

[permalink] [raw]
Subject: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present

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/config/Makefile b/tools/perf/config/Makefile
index 7014373..54532b8 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -222,7 +222,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/util/unwind.c b/tools/perf/util/unwind.c
index 958723b..028c18a 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

2013-09-09 10:01:21

by Jean Pihet

[permalink] [raw]
Subject: [PATCH 2/3] ARM: perf: wire up perf_regs and unwind support for ARM

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 b5d9238..7014373 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
@@ -204,8 +208,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

2013-09-10 07:29:50

by Jean Pihet

[permalink] [raw]
Subject: Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section

Hi!

FYI a wiki page has been added for perf-libunwind, at
https://wiki.linaro.org/LEG/Engineering/TOOLS/perf-libunwind

Any feedback is welcome!

Cheers,
Jean

On 9 September 2013 12:00, Jean Pihet <[email protected]> wrote:
> 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 and x86_64, using the
> following commands:
> perf record -g [dwarf] -- <binary>
> perf report --sort symbol --call-graph --stdio
>
>
> Jean Pihet (1):
> 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 | 9 +++--
> tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++--------
> 10 files changed, 223 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
>

2013-09-10 19:14:33

by David Ahern

[permalink] [raw]
Subject: Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present

On 9/9/13 3:00 AM, Jean Pihet wrote:
> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
> index 7014373..54532b8 100644
> --- a/tools/perf/config/Makefile
> +++ b/tools/perf/config/Makefile
> @@ -222,7 +222,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

Is the 1.1 version required for x86 too?

David

2013-09-10 19:38:52

by Jean Pihet

[permalink] [raw]
Subject: Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present

On 10 September 2013 21:14, David Ahern <[email protected]> wrote:
> On 9/9/13 3:00 AM, Jean Pihet wrote:
>>
>> diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
>> index 7014373..54532b8 100644
>> --- a/tools/perf/config/Makefile
>> +++ b/tools/perf/config/Makefile
>> @@ -222,7 +222,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
>
>
> Is the 1.1 version required for x86 too?
Yes if the dwarf unwinding feature is used. I know it is not in use on
x86 as of now but could be in the future since the dwarf info brings
more details in the trace, cf. http://lwn.net/Articles/499116/.

>
> David

Jean

2013-09-12 12:07:25

by Jean Pihet

[permalink] [raw]
Subject: Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section

Hi,

-- Adding more maintainers in the To: list --

Ping about the patch set, is this one acceptable for mainline?

Jean

On 9 September 2013 12:00, Jean Pihet <[email protected]> wrote:
> 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 and x86_64, using the
> following commands:
> perf record -g [dwarf] -- <binary>
> perf report --sort symbol --call-graph --stdio
>
>
> Jean Pihet (1):
> 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 | 9 +++--
> tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++--------
> 10 files changed, 223 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
>

2013-09-12 12:20:06

by Peter Zijlstra

[permalink] [raw]
Subject: Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section

On Thu, Sep 12, 2013 at 02:07:23PM +0200, Jean Pihet wrote:
> Hi,
>
> -- Adding more maintainers in the To: list --
>
> Ping about the patch set, is this one acceptable for mainline?

The below looks to be mostly ARM bits and I would suspect Will to take
care of them.

> On 9 September 2013 12:00, Jean Pihet <[email protected]> wrote:

> > 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 | 9 +++--
> > tools/perf/util/unwind.c | 71 +++++++++++++++++++++++++--------

This one looks to be generic code, Acme who do we want to look at that?

> > 10 files changed, 223 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
> >

2013-09-12 12:28:56

by Will Deacon

[permalink] [raw]
Subject: Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section

On Thu, Sep 12, 2013 at 01:19:53PM +0100, Peter Zijlstra wrote:
> On Thu, Sep 12, 2013 at 02:07:23PM +0200, Jean Pihet wrote:
> > Hi,
> >
> > -- Adding more maintainers in the To: list --
> >
> > Ping about the patch set, is this one acceptable for mainline?
>
> The below looks to be mostly ARM bits and I would suspect Will to take
> care of them.

I wrote those bits too, so I'm happy to take them via my tree. I'd rather
wait for the last patch to have an ack from somebody like Acme (or for them
to take it in the tip/perf tree) before I push anything though.

Cheers,

Will

2013-09-12 12:39:23

by Jiri Olsa

[permalink] [raw]
Subject: Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present

On Mon, Sep 09, 2013 at 12:00:15PM +0200, Jean Pihet wrote:
> 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]>

I tested the .eh_frame code is still functional, but
haven't tested the .debug_frame functionality itself

otherwise it looks ok:
Rewieved-by: Jiri Olsa <[email protected]>

thanks,
jirka