linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
@ 2013-09-04 18:04 Jean Pihet
  2013-09-04 18:04 ` [PATCH 1/3] ARM: perf: add support for perf regs API Jean Pihet
                   ` (2 more replies)
  0 siblings, 3 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-04 18:04 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: patches, Jean Pihet

On ARM the debug info is not present in the .eh_frame sections but
in .debug_frame instead.

This patch 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 ARM.

The generated perf has been tested on ARM/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 regs 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/util/unwind.c                | 70 +++++++++++++++++++++++++--------
 10 files changed, 221 insertions(+), 18 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


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 1/3] ARM: perf: add support for perf regs API
  2013-09-04 18:04 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
@ 2013-09-04 18:04 ` Jean Pihet
  2013-09-05 13:21   ` Ard Biesheuvel
  2013-09-04 18:04 ` [PATCH 2/3] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
  2013-09-04 18:04 ` [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
  2 siblings, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-04 18:04 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: patches

From: Will Deacon <will.deacon@arm.com>

This patch implements the functions required for the perf refs API,
allowing the perf tool to interface kernel register dumps with libunwind
in order to provide userspace backtracing.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 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


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 2/3] ARM: perf: wire up perf_regs and unwind support for ARM
  2013-09-04 18:04 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
  2013-09-04 18:04 ` [PATCH 1/3] ARM: perf: add support for perf regs API Jean Pihet
@ 2013-09-04 18:04 ` Jean Pihet
  2013-09-04 18:04 ` [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
  2 siblings, 0 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-04 18:04 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: patches, Jean Pihet

From: Will Deacon <will.deacon@arm.com>

This patch hooks in the perf_regs and libunwind code for ARM.

Signed-off-by: Will Deacon <will.deacon@arm.com>
Cc: Jean Pihet <jean.pihet@linaro.org>
---
 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


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-04 18:04 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
  2013-09-04 18:04 ` [PATCH 1/3] ARM: perf: add support for perf regs API Jean Pihet
  2013-09-04 18:04 ` [PATCH 2/3] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
@ 2013-09-04 18:04 ` Jean Pihet
  2013-09-05 12:45   ` Will Deacon
  2013-09-05 16:30   ` Jiri Olsa
  2 siblings, 2 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-04 18:04 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: patches, Jean Pihet

On ARM the debug info is not present in the .eh_frame sections but
instead in .debug_frame.
Use libunwind to load and parse the debug info.

Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
---
 tools/perf/util/unwind.c | 70 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 54 insertions(+), 16 deletions(-)

diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
index 958723b..5353b32 100644
--- a/tools/perf/util/unwind.c
+++ b/tools/perf/util/unwind.c
@@ -39,6 +39,14 @@ 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 +253,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 +264,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 +273,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 +318,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


^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-04 18:04 ` [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
@ 2013-09-05 12:45   ` Will Deacon
  2013-09-05 13:05     ` Jean Pihet
  2013-09-05 13:10     ` Ard Biesheuvel
  2013-09-05 16:30   ` Jiri Olsa
  1 sibling, 2 replies; 24+ messages in thread
From: Will Deacon @ 2013-09-05 12:45 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel,
	patches, michael.hudson

Hi Jean,

[adding Michael, since I know he was interested in this]

On Wed, Sep 04, 2013 at 07:04:14PM +0100, Jean Pihet wrote:
> On ARM the debug info is not present in the .eh_frame sections but
> instead in .debug_frame.
> Use libunwind to load and parse the debug info.

How have you tested this? Regardless of whether or not I apply this patch, I
get the same (broken/truncated) callchains for userspace in perf report.

E.g. the following stupid program (built with -O0 -g):

--->8

void bar(void)
{
        int i;
        for (i = 0; i < 1000000; ++i)
                asm volatile("nop" ::: "memory");
}

void foo(void)
{
        bar();
}


int main(void)
{
        foo();
        return 0;
}

8<---

Gives me an incomplete callchain:

# Overhead   Command      Shared Object                           Symbol
# ........  ........  .................  ...............................
#
     0.00%  unwindme  unwindme           [.] bar                        
            |
            --- bar

This is the same with or without your patch.

Will

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 12:45   ` Will Deacon
@ 2013-09-05 13:05     ` Jean Pihet
  2013-09-05 13:17       ` Ard Biesheuvel
  2013-09-05 13:10     ` Ard Biesheuvel
  1 sibling, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-05 13:05 UTC (permalink / raw)
  To: Will Deacon
  Cc: Jean Pihet, linaro-kernel, patches, Michael Hudson-Doyle,
	linux-kernel, Jiri Olsa, linux-arm-kernel

Hi Will,


On Thu, Sep 5, 2013 at 2:45 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Jean,
>
> [adding Michael, since I know he was interested in this]
>
> On Wed, Sep 04, 2013 at 07:04:14PM +0100, Jean Pihet wrote:
>> On ARM the debug info is not present in the .eh_frame sections but
>> instead in .debug_frame.
>> Use libunwind to load and parse the debug info.
>
> How have you tested this? Regardless of whether or not I apply this patch, I
> get the same (broken/truncated) callchains for userspace in perf report.
Here are the commands I have been using:
 perf record -g dwarf -- <binary to profile>
 perf report --sort symbol --call-graph --stdio

>
> E.g. the following stupid program (built with -O0 -g):
>
> --->8
>
> void bar(void)
> {
>         int i;
>         for (i = 0; i < 1000000; ++i)
>                 asm volatile("nop" ::: "memory");
> }
>
> void foo(void)
> {
>         bar();
> }
>
>
> int main(void)
> {
>         foo();
>         return 0;
> }
>
> 8<---
>
> Gives me an incomplete callchain:
>
> # Overhead   Command      Shared Object                           Symbol
> # ........  ........  .................  ...............................
> #
>      0.00%  unwindme  unwindme           [.] bar
>             |
>             --- bar
I get the following with a simple stupid program with a long call chain:
     0.57%  stress_bt  stress_bt          [.] foo_115
            |
            --- foo_115
                foo_114
                foo_113
...
                foo_92
                bar
                doit
                main
                __libc_start_main

Things to check:
- compile the binaries and libraries with -g (-dbg flavor of libs are
usually ok),
- use -g dwarf in perf record


> This is the same with or without your patch.
>
> Will

Thanks for testing!
Jean

>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 12:45   ` Will Deacon
  2013-09-05 13:05     ` Jean Pihet
@ 2013-09-05 13:10     ` Ard Biesheuvel
  1 sibling, 0 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2013-09-05 13:10 UTC (permalink / raw)
  To: Will Deacon
  Cc: Jean Pihet, linaro-kernel, patches, Michael Hudson-Doyle,
	linux-kernel, Jiri Olsa, linux-arm-kernel

On 5 September 2013 14:45, Will Deacon <will.deacon@arm.com> wrote:
> Hi Jean,
>
> [adding Michael, since I know he was interested in this]
>
> On Wed, Sep 04, 2013 at 07:04:14PM +0100, Jean Pihet wrote:
>> On ARM the debug info is not present in the .eh_frame sections but
>> instead in .debug_frame.
>> Use libunwind to load and parse the debug info.
>
> How have you tested this? Regardless of whether or not I apply this patch, I
> get the same (broken/truncated) callchains for userspace in perf report.

Same here: I have applied these patches against 3.11 running on a
Calxeda Highbank, and I never get more than a single entry for the
userland part of the call stack.

>
> E.g. the following stupid program (built with -O0 -g):
>
[...]
>
> Gives me an incomplete callchain:
>
> # Overhead   Command      Shared Object                           Symbol
> # ........  ........  .................  ...............................
> #
>      0.00%  unwindme  unwindme           [.] bar
>             |
>             --- bar
>

I get exactly the same results, just bar and nothing below.

-- 
Ard.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 13:05     ` Jean Pihet
@ 2013-09-05 13:17       ` Ard Biesheuvel
  2013-09-05 13:19         ` Will Deacon
  0 siblings, 1 reply; 24+ messages in thread
From: Ard Biesheuvel @ 2013-09-05 13:17 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, linaro-kernel, patches, Michael Hudson-Doyle,
	linux-kernel, Jean Pihet, Jiri Olsa, linux-arm-kernel

On 5 September 2013 15:05, Jean Pihet <jean.pihet@newoldbits.com> wrote:
[..]
> Here are the commands I have been using:
>  perf record -g dwarf -- <binary to profile>
>  perf report --sort symbol --call-graph --stdio
>

Ah, I failed to add the 'dwarf' after -g, however, in that case, my
perf report segfaults:

#0  locate_debug_info (as=0xb6ea9144 <local_addr_space>,
info=info@entry=0x83d6, addr=addr@entry=0, dlname=0x4a0000 <Address
0x4a0000 out of bounds>)
    at dwarf/Gfind_proc_info-lsb.c:295
#1  0xb6e9a9c6 in _Uarm_dwarf_find_debug_frame (found=found@entry=0,
di_debug=di_debug@entry=0xbeff95b8, info=info@entry=0x83d6,
ip=ip@entry=0)
    at dwarf/Gfind_proc_info-lsb.c:423
#2  0x0006f0e4 in find_proc_info (as=0x2c06a0, ip=33750,
pi=0xbeffa8fc, need_unwind_info=1, arg=0xbeffe530) at
util/unwind.c:339
#3  0xb6e98258 in fetch_proc_info (c=c@entry=0xbeffa4d4, ip=<optimised
out>, need_unwind_info=need_unwind_info@entry=1) at
dwarf/Gparser.c:422
#4  0xb6e99640 in uncached_dwarf_find_save_locs (c=0xbeffa4d4) at
dwarf/Gparser.c:824
#5  _Uarm_dwarf_find_save_locs (c=c@entry=0xbeffa4d4) at dwarf/Gparser.c:849
#6  0xb6e9a034 in _Uarm_dwarf_step (c=c@entry=0xbeffa4d4) at dwarf/Gstep.c:34
#7  0xb6e95182 in _Uarm_step (cursor=cursor@entry=0xbeffa4d4) at arm/Gstep.c:177
#8  0x0006ed50 in get_entries (ui=ui@entry=0xbeffe530,
cb=cb@entry=0x47599 <unwind_entry>, arg=arg@entry=0xb6b804c8) at
util/unwind.c:573
#9  0x0006f324 in unwind__get_entries (cb=cb@entry=0x47599
<unwind_entry>, arg=0xb6b804c8, machine=machine@entry=0xf0544,
thread=thread@entry=0x101860,
    sample_uregs=sample_uregs@entry=65535, data=data@entry=0xbeffe740)
at util/unwind.c:608
#10 0x00049a96 in machine__resolve_callchain
(machine=machine@entry=0xf0544, evsel=evsel@entry=0xf0b98,
thread=0x101860, sample=sample@entry=0xbeffe740,
    parent=parent@entry=0xbeffe644) at util/machine.c:1262
#11 0x0001a43e in perf_evsel__add_hist_entry (machine=0xf0544,
sample=0xbeffe740, al=0xbeffe640, evsel=0xf0b98) at
builtin-report.c:256
#12 process_sample_event (tool=0xbeffeb68, event=0xb6b3c600,
sample=0xbeffe740, evsel=0xf0b98, machine=0xf0544) at
builtin-report.c:335
#13 0x0004b3ca in perf_session_deliver_event
(session=session@entry=0xf0498, event=0xb6b3c600,
sample=sample@entry=0xbeffe740, tool=tool@entry=0xbeffeb68,
    file_offset=file_offset@entry=161280) at util/session.c:873
#14 0x0004b8d0 in flush_sample_queue (s=s@entry=0xf0498,
tool=tool@entry=0xbeffeb68) at util/session.c:521
#15 0x0004c974 in __perf_session__process_events
(session=session@entry=0xf0498, data_offset=<optimised out>,
data_size=data_size@entry=437976, file_size=438264,
    tool=tool@entry=0xbeffeb68) at util/session.c:1269
#16 0x0004cc5c in perf_session__process_events
(self=self@entry=0xf0498, tool=tool@entry=0xbeffeb68) at
util/session.c:1286
#17 0x0001b4b2 in __cmd_report (rep=0xbeffeb68) at builtin-report.c:513
#18 cmd_report (argc=0, argv=0xbefff6c8, prefix=<optimised out>) at
builtin-report.c:957
#19 0x0000d80e in run_builtin (p=p@entry=0xaa548 <commands+84>,
argc=argc@entry=2, argv=argv@entry=0xbefff6c8) at perf.c:319
#20 0x0000d28a in handle_internal_command (argv=0xbefff6c8, argc=2) at
perf.c:376
#21 run_argv (argv=0xbefff4a8, argcp=0xbefff4ac) at perf.c:420
#22 main (argc=2, argv=0xbefff6c8) at perf.c:521

-- 
Ard.



>>
>> E.g. the following stupid program (built with -O0 -g):
>>
>> --->8
>>
>> void bar(void)
>> {
>>         int i;
>>         for (i = 0; i < 1000000; ++i)
>>                 asm volatile("nop" ::: "memory");
>> }
>>
>> void foo(void)
>> {
>>         bar();
>> }
>>
>>
>> int main(void)
>> {
>>         foo();
>>         return 0;
>> }
>>
>> 8<---
>>
>> Gives me an incomplete callchain:
>>
>> # Overhead   Command      Shared Object                           Symbol
>> # ........  ........  .................  ...............................
>> #
>>      0.00%  unwindme  unwindme           [.] bar
>>             |
>>             --- bar
> I get the following with a simple stupid program with a long call chain:
>      0.57%  stress_bt  stress_bt          [.] foo_115
>             |
>             --- foo_115
>                 foo_114
>                 foo_113
> ...
>                 foo_92
>                 bar
>                 doit
>                 main
>                 __libc_start_main
>
> Things to check:
> - compile the binaries and libraries with -g (-dbg flavor of libs are
> usually ok),
> - use -g dwarf in perf record
>
>
>> This is the same with or without your patch.
>>
>> Will
>
> Thanks for testing!
> Jean
>
>>
>> _______________________________________________
>> linux-arm-kernel mailing list
>> linux-arm-kernel@lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 13:17       ` Ard Biesheuvel
@ 2013-09-05 13:19         ` Will Deacon
  2013-09-05 13:33           ` Jean Pihet
  0 siblings, 1 reply; 24+ messages in thread
From: Will Deacon @ 2013-09-05 13:19 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: Jean Pihet, linaro-kernel, patches, Michael Hudson-Doyle,
	linux-kernel, Jean Pihet, Jiri Olsa, linux-arm-kernel

On Thu, Sep 05, 2013 at 02:17:30PM +0100, Ard Biesheuvel wrote:
> On 5 September 2013 15:05, Jean Pihet <jean.pihet@newoldbits.com> wrote:
> [..]
> > Here are the commands I have been using:
> >  perf record -g dwarf -- <binary to profile>
> >  perf report --sort symbol --call-graph --stdio
> >
> 
> Ah, I failed to add the 'dwarf' after -g, however, in that case, my
> perf report segfaults:

Same SEGV here.

Will

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 1/3] ARM: perf: add support for perf regs API
  2013-09-04 18:04 ` [PATCH 1/3] ARM: perf: add support for perf regs API Jean Pihet
@ 2013-09-05 13:21   ` Ard Biesheuvel
  0 siblings, 0 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2013-09-05 13:21 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel,
	linux-arm-kernel, Patch Tracking

On 4 September 2013 20:04, Jean Pihet <jean.pihet@linaro.org> wrote:
> From: Will Deacon <will.deacon@arm.com>
>
> This patch implements the functions required for the perf refs API,

'regs API' not 'refs API'


Regards,
Ard.


> allowing the perf tool to interface kernel register dumps with libunwind
> in order to provide userspace backtracing.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
>  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
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 13:19         ` Will Deacon
@ 2013-09-05 13:33           ` Jean Pihet
  2013-09-05 15:29             ` Jean Pihet
  0 siblings, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-05 13:33 UTC (permalink / raw)
  To: Will Deacon
  Cc: Ard Biesheuvel, Jean Pihet, linaro-kernel, patches,
	Michael Hudson-Doyle, linux-kernel, Jiri Olsa, linux-arm-kernel

On 5 September 2013 15:19, Will Deacon <will.deacon@arm.com> wrote:
> On Thu, Sep 05, 2013 at 02:17:30PM +0100, Ard Biesheuvel wrote:
>> On 5 September 2013 15:05, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>> [..]
>> > Here are the commands I have been using:
>> >  perf record -g dwarf -- <binary to profile>
>> >  perf report --sort symbol --call-graph --stdio
>> >
>>
>> Ah, I failed to add the 'dwarf' after -g, however, in that case, my
>> perf report segfaults:
>
> Same SEGV here.
Ouch! I never got the segfault on my side.

Here is the setup I am using:
- OMAP4 Pandaboard,
- 13.07 Ubuntu dist from http://www.linaro.org/downloads/,
- 3.11 mainline kernel + 3 patches for unwinding info,
- patched perf tool,
- dbg flavor of the libs installed. Without them installed I do not
get the address resolved but no segfaults

Can you check if the linked libraries contain the .debug_frame
sections? (ldd; readelf -S /lib/arm-linux-gnueabihf/libc-2.17.so|grep
debug_frame; readelf -S
/usr/lib/debug/lib/arm-linux-gnueabihf/libc-2.17.so|grep debug_frame)?

>
> Will

Jean

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 13:33           ` Jean Pihet
@ 2013-09-05 15:29             ` Jean Pihet
  2013-09-05 15:45               ` Ard Biesheuvel
  0 siblings, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-05 15:29 UTC (permalink / raw)
  To: Will Deacon
  Cc: Ard Biesheuvel, Jean Pihet, linaro-kernel, patches,
	Michael Hudson-Doyle, linux-kernel, Jiri Olsa, linux-arm-kernel

Hi,

On 5 September 2013 15:33, Jean Pihet <jean.pihet@linaro.org> wrote:
> On 5 September 2013 15:19, Will Deacon <will.deacon@arm.com> wrote:
>> On Thu, Sep 05, 2013 at 02:17:30PM +0100, Ard Biesheuvel wrote:
>>> On 5 September 2013 15:05, Jean Pihet <jean.pihet@newoldbits.com> wrote:
>>> [..]
>>> > Here are the commands I have been using:
>>> >  perf record -g dwarf -- <binary to profile>
>>> >  perf report --sort symbol --call-graph --stdio
>>> >
>>>
>>> Ah, I failed to add the 'dwarf' after -g, however, in that case, my
>>> perf report segfaults:
>>
>> Same SEGV here.
> Ouch! I never got the segfault on my side.

The segfault is caused by libunwind. With the latest version [1],
dwarf unwinding works fine.
Investigation on-going, more to come!

[1] git://git.sv.gnu.org/libunwind.git

Regards,
Jean

>
> Here is the setup I am using:
> - OMAP4 Pandaboard,
> - 13.07 Ubuntu dist from http://www.linaro.org/downloads/,
> - 3.11 mainline kernel + 3 patches for unwinding info,
> - patched perf tool,
> - dbg flavor of the libs installed. Without them installed I do not
> get the address resolved but no segfaults
>
> Can you check if the linked libraries contain the .debug_frame
> sections? (ldd; readelf -S /lib/arm-linux-gnueabihf/libc-2.17.so|grep
> debug_frame; readelf -S
> /usr/lib/debug/lib/arm-linux-gnueabihf/libc-2.17.so|grep debug_frame)?
>
>>
>> Will
>
> Jean

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 15:29             ` Jean Pihet
@ 2013-09-05 15:45               ` Ard Biesheuvel
  0 siblings, 0 replies; 24+ messages in thread
From: Ard Biesheuvel @ 2013-09-05 15:45 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, Jean Pihet, linaro-kernel, patches,
	Michael Hudson-Doyle, linux-kernel, Jiri Olsa, linux-arm-kernel

On 5 September 2013 17:29, Jean Pihet <jean.pihet@linaro.org> wrote:

[...]

> The segfault is caused by libunwind. With the latest version [1],
> dwarf unwinding works fine.
> Investigation on-going, more to come!
>
> [1] git://git.sv.gnu.org/libunwind.git
>

I managed to get it to work by upgrading to Ubuntu Saucy's libunwind8
on a Ubuntu Raring system (Calxeda Highbank)

FWIW, for the series

Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> # on
ARM/Highbank/UbuntuSaucy

-- 
Ard.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-04 18:04 ` [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
  2013-09-05 12:45   ` Will Deacon
@ 2013-09-05 16:30   ` Jiri Olsa
  2013-09-05 16:49     ` Jean Pihet
  2013-09-06  9:31     ` Jean Pihet
  1 sibling, 2 replies; 24+ messages in thread
From: Jiri Olsa @ 2013-09-05 16:30 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel, patches

On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
> On ARM the debug info is not present in the .eh_frame sections but
> instead in .debug_frame.
> Use libunwind to load and parse the debug info.

hum, cannot make final link:

$ make LIBUNWIND_DIR=/opt/libunwind/
    CHK -fstack-protector-all
    CHK -Wstack-protector
    CHK -Wvolatile-register-var
    CHK -D_FORTIFY_SOURCE=2
    CHK bionic
    CHK libelf
    CHK libdw
    CHK -DLIBELF_MMAP
    CHK -DLIBELF_MMAP
    CHK libunwind
    CHK libaudit

...

make[1]: `liblk.a' is up to date.
    SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
    LINK perf
libperf.a(unwind.o): In function `find_proc_info':
/home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
collect2: ld returned 1 exit status
make: *** [perf] Error 1


I'm using the latest code from git://git.sv.gnu.org/libunwind.git

Looks like dwarf_find_debug_frame is not exported, although
it looks like it is based on what I see in libunwind sources ;-)

What did I miss?

Also few typo comments below..

thanks,
jirka

> 
> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> ---
>  tools/perf/util/unwind.c | 70 +++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 54 insertions(+), 16 deletions(-)
> 
> diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
> index 958723b..5353b32 100644
> --- a/tools/perf/util/unwind.c
> +++ b/tools/perf/util/unwind.c
> @@ -39,6 +39,14 @@ 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 +253,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 +264,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 +273,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)
> +{

some strange formatting issue ^^^ ;-)


> +	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 +318,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)) {

ditto ^^^

> +		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);

ditto ^^^

> +	}
> +
> +	/* 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);

ditto ^^^

> +	}
>  
> -	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
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 16:30   ` Jiri Olsa
@ 2013-09-05 16:49     ` Jean Pihet
  2013-09-06 10:17       ` Jiri Olsa
  2013-09-06  9:31     ` Jean Pihet
  1 sibling, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-05 16:49 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel,
	Patch Tracking

Hi Jiri,

On 5 September 2013 18:30, Jiri Olsa <jolsa@redhat.com> wrote:
> On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
>> On ARM the debug info is not present in the .eh_frame sections but
>> instead in .debug_frame.
>> Use libunwind to load and parse the debug info.
>
> hum, cannot make final link:
>
> $ make LIBUNWIND_DIR=/opt/libunwind/
>     CHK -fstack-protector-all
>     CHK -Wstack-protector
>     CHK -Wvolatile-register-var
>     CHK -D_FORTIFY_SOURCE=2
>     CHK bionic
>     CHK libelf
>     CHK libdw
>     CHK -DLIBELF_MMAP
>     CHK -DLIBELF_MMAP
>     CHK libunwind
>     CHK libaudit
>
> ...
>
> make[1]: `liblk.a' is up to date.
>     SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
>     LINK perf
> libperf.a(unwind.o): In function `find_proc_info':
> /home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
> collect2: ld returned 1 exit status
> make: *** [perf] Error 1
>
>
> I'm using the latest code from git://git.sv.gnu.org/libunwind.git
>
> Looks like dwarf_find_debug_frame is not exported, although
> it looks like it is based on what I see in libunwind sources ;-)
>
> What did I miss?
Weird, I do not have the error on x86_64. I am investigating this and
will come back to you asap.

>
> Also few typo comments below..
>
> thanks,
> jirka
>
>>
>> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
>> ---
>>  tools/perf/util/unwind.c | 70 +++++++++++++++++++++++++++++++++++++-----------
>>  1 file changed, 54 insertions(+), 16 deletions(-)
>>
>> diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
>> index 958723b..5353b32 100644
>> --- a/tools/perf/util/unwind.c
>> +++ b/tools/perf/util/unwind.c
>> @@ -39,6 +39,14 @@ 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 +253,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 +264,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 +273,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)
>> +{
>
> some strange formatting issue ^^^ ;-)
I am using 4-spaces tabs. scripts/checkpatch.pl reported it to me in
the form of too long lines.
Should I change the code to 8-spaces tabs?

Thx!
Jean

>
>
>> +     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 +318,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)) {
>
> ditto ^^^
>
>> +             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);
>
> ditto ^^^
>
>> +     }
>> +
>> +     /* 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);
>
> ditto ^^^
>
>> +     }
>>
>> -     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
>>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 16:30   ` Jiri Olsa
  2013-09-05 16:49     ` Jean Pihet
@ 2013-09-06  9:31     ` Jean Pihet
  2013-09-06 10:17       ` Jiri Olsa
  1 sibling, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-06  9:31 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel,
	Patch Tracking

Hi Jiri,

On 5 September 2013 18:30, Jiri Olsa <jolsa@redhat.com> wrote:
> On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
>> On ARM the debug info is not present in the .eh_frame sections but
>> instead in .debug_frame.
>> Use libunwind to load and parse the debug info.
>
> hum, cannot make final link:
>
> $ make LIBUNWIND_DIR=/opt/libunwind/
>     CHK -fstack-protector-all
>     CHK -Wstack-protector
>     CHK -Wvolatile-register-var
>     CHK -D_FORTIFY_SOURCE=2
>     CHK bionic
>     CHK libelf
>     CHK libdw
>     CHK -DLIBELF_MMAP
>     CHK -DLIBELF_MMAP
>     CHK libunwind
>     CHK libaudit
>
> ...
>
> make[1]: `liblk.a' is up to date.
>     SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
>     LINK perf
> libperf.a(unwind.o): In function `find_proc_info':
> /home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
> collect2: ld returned 1 exit status
> make: *** [perf] Error 1
>
>
> I'm using the latest code from git://git.sv.gnu.org/libunwind.git
>
> Looks like dwarf_find_debug_frame is not exported, although
> it looks like it is based on what I see in libunwind sources ;-)
>
> What did I miss?
libunwind needs to be configured with --enable-debug-frame for the
debug_frame code to be included in the lib.
On ARM the flag is always set while it isn't on x86. Here is the
culprit below (lines from libunwind configure).

Should that be changed in configure along with the changes in tools/perf?


{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to load
.debug_frame  sections" >&5
$as_echo_n "checking whether to load .debug_frame sections... " >&6; }
# Check whether --enable-debug_frame was given.
if test "${enable_debug_frame+set}" = set; then :
  enableval=$enable_debug_frame;
else

case "${target_arch}" in
  (arm) enable_debug_frame=yes;;
  (*)   enable_debug_frame=no;;
esac
fi

if test x$enable_debug_frame = xyes; then
$as_echo "#define CONFIG_DEBUG_FRAME /**/" >>confdefs.h
fi


Regards,
Jean

>
> Also few typo comments below..
>
> thanks,
> jirka
>
>>
>> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
>> ---
>>  tools/perf/util/unwind.c | 70 +++++++++++++++++++++++++++++++++++++-----------
>>  1 file changed, 54 insertions(+), 16 deletions(-)
>>
>> diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
>> index 958723b..5353b32 100644
>> --- a/tools/perf/util/unwind.c
>> +++ b/tools/perf/util/unwind.c
>> @@ -39,6 +39,14 @@ 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 +253,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 +264,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 +273,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)
>> +{
>
> some strange formatting issue ^^^ ;-)
>
>
>> +     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 +318,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)) {
>
> ditto ^^^
>
>> +             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);
>
> ditto ^^^
>
>> +     }
>> +
>> +     /* 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);
>
> ditto ^^^
>
>> +     }
>>
>> -     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
>>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-05 16:49     ` Jean Pihet
@ 2013-09-06 10:17       ` Jiri Olsa
  0 siblings, 0 replies; 24+ messages in thread
From: Jiri Olsa @ 2013-09-06 10:17 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel,
	Patch Tracking

On Thu, Sep 05, 2013 at 06:49:13PM +0200, Jean Pihet wrote:
> Hi Jiri,
> 
> On 5 September 2013 18:30, Jiri Olsa <jolsa@redhat.com> wrote:
> > On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
> >> On ARM the debug info is not present in the .eh_frame sections but
> >> instead in .debug_frame.
> >> Use libunwind to load and parse the debug info.
> >
> > hum, cannot make final link:
> >
> > $ make LIBUNWIND_DIR=/opt/libunwind/
> >     CHK -fstack-protector-all
> >     CHK -Wstack-protector
> >     CHK -Wvolatile-register-var
> >     CHK -D_FORTIFY_SOURCE=2
> >     CHK bionic
> >     CHK libelf
> >     CHK libdw
> >     CHK -DLIBELF_MMAP
> >     CHK -DLIBELF_MMAP
> >     CHK libunwind
> >     CHK libaudit
> >
> > ...
> >
> > make[1]: `liblk.a' is up to date.
> >     SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
> >     LINK perf
> > libperf.a(unwind.o): In function `find_proc_info':
> > /home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
> > collect2: ld returned 1 exit status
> > make: *** [perf] Error 1
> >
> >
> > I'm using the latest code from git://git.sv.gnu.org/libunwind.git
> >
> > Looks like dwarf_find_debug_frame is not exported, although
> > it looks like it is based on what I see in libunwind sources ;-)
> >
> > What did I miss?
> Weird, I do not have the error on x86_64. I am investigating this and
> will come back to you asap.
> 
> >
> > Also few typo comments below..
> >
> > thanks,
> > jirka
> >
> >>
> >> Signed-off-by: Jean Pihet <jean.pihet@linaro.org>
> >> ---
> >>  tools/perf/util/unwind.c | 70 +++++++++++++++++++++++++++++++++++++-----------
> >>  1 file changed, 54 insertions(+), 16 deletions(-)
> >>
> >> diff --git a/tools/perf/util/unwind.c b/tools/perf/util/unwind.c
> >> index 958723b..5353b32 100644
> >> --- a/tools/perf/util/unwind.c
> >> +++ b/tools/perf/util/unwind.c
> >> @@ -39,6 +39,14 @@ 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 +253,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 +264,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 +273,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)
> >> +{
> >
> > some strange formatting issue ^^^ ;-)
> I am using 4-spaces tabs. scripts/checkpatch.pl reported it to me in
> the form of too long lines.
> Should I change the code to 8-spaces tabs?
> 

right, if I set tabs to 4 space then it's ok
so I guess 8 is globally agreed ;-)

jirka

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-06  9:31     ` Jean Pihet
@ 2013-09-06 10:17       ` Jiri Olsa
  2013-09-06 14:10         ` Jean Pihet
  0 siblings, 1 reply; 24+ messages in thread
From: Jiri Olsa @ 2013-09-06 10:17 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel,
	Patch Tracking

On Fri, Sep 06, 2013 at 11:31:17AM +0200, Jean Pihet wrote:
> Hi Jiri,
> 
> On 5 September 2013 18:30, Jiri Olsa <jolsa@redhat.com> wrote:
> > On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
> >> On ARM the debug info is not present in the .eh_frame sections but
> >> instead in .debug_frame.
> >> Use libunwind to load and parse the debug info.
> >
> > hum, cannot make final link:
> >
> > $ make LIBUNWIND_DIR=/opt/libunwind/
> >     CHK -fstack-protector-all
> >     CHK -Wstack-protector
> >     CHK -Wvolatile-register-var
> >     CHK -D_FORTIFY_SOURCE=2
> >     CHK bionic
> >     CHK libelf
> >     CHK libdw
> >     CHK -DLIBELF_MMAP
> >     CHK -DLIBELF_MMAP
> >     CHK libunwind
> >     CHK libaudit
> >
> > ...
> >
> > make[1]: `liblk.a' is up to date.
> >     SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
> >     LINK perf
> > libperf.a(unwind.o): In function `find_proc_info':
> > /home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
> > collect2: ld returned 1 exit status
> > make: *** [perf] Error 1
> >
> >
> > I'm using the latest code from git://git.sv.gnu.org/libunwind.git
> >
> > Looks like dwarf_find_debug_frame is not exported, although
> > it looks like it is based on what I see in libunwind sources ;-)
> >
> > What did I miss?
> libunwind needs to be configured with --enable-debug-frame for the
> debug_frame code to be included in the lib.
> On ARM the flag is always set while it isn't on x86. Here is the
> culprit below (lines from libunwind configure).

yay, thats it!

> 
> Should that be changed in configure along with the changes in tools/perf?

I guess it's ok

Other than that tabs misformating the 'perf tool' change looks ok.

I tested the '.eh_frame' code and it's still working. Once
I figure out how to create a x86 binary with .debug_frame
data I'll test the code itself ;-)

If you could think of any automated testcase for this that could
be added under 'tests' that'd be nice (not necessarily)

thanks,
jirka

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present
  2013-09-06 10:17       ` Jiri Olsa
@ 2013-09-06 14:10         ` Jean Pihet
  0 siblings, 0 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-06 14:10 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Will Deacon, linux-kernel, linaro-kernel, linux-arm-kernel,
	Patch Tracking

On 6 September 2013 12:17, Jiri Olsa <jolsa@redhat.com> wrote:
> On Fri, Sep 06, 2013 at 11:31:17AM +0200, Jean Pihet wrote:
>> Hi Jiri,
>>
>> On 5 September 2013 18:30, Jiri Olsa <jolsa@redhat.com> wrote:
>> > On Wed, Sep 04, 2013 at 08:04:14PM +0200, Jean Pihet wrote:
>> >> On ARM the debug info is not present in the .eh_frame sections but
>> >> instead in .debug_frame.
>> >> Use libunwind to load and parse the debug info.
>> >
>> > hum, cannot make final link:
>> >
>> > $ make LIBUNWIND_DIR=/opt/libunwind/
>> >     CHK -fstack-protector-all
>> >     CHK -Wstack-protector
>> >     CHK -Wvolatile-register-var
>> >     CHK -D_FORTIFY_SOURCE=2
>> >     CHK bionic
>> >     CHK libelf
>> >     CHK libdw
>> >     CHK -DLIBELF_MMAP
>> >     CHK -DLIBELF_MMAP
>> >     CHK libunwind
>> >     CHK libaudit
>> >
>> > ...
>> >
>> > make[1]: `liblk.a' is up to date.
>> >     SUBDIR /home/jolsa/linux-perf/tools/lib/traceevent/
>> >     LINK perf
>> > libperf.a(unwind.o): In function `find_proc_info':
>> > /home/jolsa/linux-perf/tools/perf/util/unwind.c:339: undefined reference to `_Ux86_64_dwarf_find_debug_frame'
>> > collect2: ld returned 1 exit status
>> > make: *** [perf] Error 1
>> >
>> >
>> > I'm using the latest code from git://git.sv.gnu.org/libunwind.git
>> >
>> > Looks like dwarf_find_debug_frame is not exported, although
>> > it looks like it is based on what I see in libunwind sources ;-)
>> >
>> > What did I miss?
>> libunwind needs to be configured with --enable-debug-frame for the
>> debug_frame code to be included in the lib.
>> On ARM the flag is always set while it isn't on x86. Here is the
>> culprit below (lines from libunwind configure).
>
> yay, thats it!
>
>>
>> Should that be changed in configure along with the changes in tools/perf?
>
> I guess it's ok
I wonder how to express the dependency between the perf changes and
the libunwind version and configure flags. Is a note in the commit
descritpion enough?
I fear that the change can break many build systems...

>
> Other than that tabs misformating the 'perf tool' change looks ok.
Ok I will respin the code with the typo and formatting changes.

>
> I tested the '.eh_frame' code and it's still working. Once
> I figure out how to create a x86 binary with .debug_frame
> data I'll test the code itself ;-)
Great!

>
> If you could think of any automated testcase for this that could
> be added under 'tests' that'd be nice (not necessarily)
Ok will look at it. Linaro has automated tests that I need to write as
well so rather do it in perf/tests directly ;-p

>
> thanks,
> jirka

Thanks!
Jean

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
  2013-09-12 12:19   ` Peter Zijlstra
@ 2013-09-12 12:28     ` Will Deacon
  0 siblings, 0 replies; 24+ messages in thread
From: Will Deacon @ 2013-09-12 12:28 UTC (permalink / raw)
  To: Peter Zijlstra
  Cc: Jean Pihet, Jiri Olsa, linux-kernel, linaro-kernel,
	linux-arm-kernel, Paul Mackerras, Ingo Molnar,
	Arnaldo Carvalho de Melo

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

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
  2013-09-12 12:07 ` Jean Pihet
@ 2013-09-12 12:19   ` Peter Zijlstra
  2013-09-12 12:28     ` Will Deacon
  0 siblings, 1 reply; 24+ messages in thread
From: Peter Zijlstra @ 2013-09-12 12:19 UTC (permalink / raw)
  To: Jean Pihet
  Cc: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel,
	linux-arm-kernel, Paul Mackerras, Ingo Molnar,
	Arnaldo Carvalho de Melo

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 <jean.pihet@linaro.org> 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
> >

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
  2013-09-09 10:00 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
  2013-09-10  7:29 ` Jean Pihet
@ 2013-09-12 12:07 ` Jean Pihet
  2013-09-12 12:19   ` Peter Zijlstra
  1 sibling, 1 reply; 24+ messages in thread
From: Jean Pihet @ 2013-09-12 12:07 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel,
	linux-arm-kernel, .Peter Zijlstra, Paul Mackerras, Ingo Molnar,
	Arnaldo Carvalho de Melo

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 <jean.pihet@linaro.org> 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
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
  2013-09-09 10:00 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
@ 2013-09-10  7:29 ` Jean Pihet
  2013-09-12 12:07 ` Jean Pihet
  1 sibling, 0 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-10  7:29 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: Patch Tracking, Jean Pihet

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 <jean.pihet@linaro.org> 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
>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section
@ 2013-09-09 10:00 Jean Pihet
  2013-09-10  7:29 ` Jean Pihet
  2013-09-12 12:07 ` Jean Pihet
  0 siblings, 2 replies; 24+ messages in thread
From: Jean Pihet @ 2013-09-09 10:00 UTC (permalink / raw)
  To: Will Deacon, Jiri Olsa, linux-kernel, linaro-kernel, linux-arm-kernel
  Cc: patches, Jean Pihet

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


^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2013-09-12 12:28 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-09-04 18:04 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
2013-09-04 18:04 ` [PATCH 1/3] ARM: perf: add support for perf regs API Jean Pihet
2013-09-05 13:21   ` Ard Biesheuvel
2013-09-04 18:04 ` [PATCH 2/3] ARM: perf: wire up perf_regs and unwind support for ARM Jean Pihet
2013-09-04 18:04 ` [PATCH 3/3] perf: parse the .debug_frame section in case .eh_frame is not present Jean Pihet
2013-09-05 12:45   ` Will Deacon
2013-09-05 13:05     ` Jean Pihet
2013-09-05 13:17       ` Ard Biesheuvel
2013-09-05 13:19         ` Will Deacon
2013-09-05 13:33           ` Jean Pihet
2013-09-05 15:29             ` Jean Pihet
2013-09-05 15:45               ` Ard Biesheuvel
2013-09-05 13:10     ` Ard Biesheuvel
2013-09-05 16:30   ` Jiri Olsa
2013-09-05 16:49     ` Jean Pihet
2013-09-06 10:17       ` Jiri Olsa
2013-09-06  9:31     ` Jean Pihet
2013-09-06 10:17       ` Jiri Olsa
2013-09-06 14:10         ` Jean Pihet
2013-09-09 10:00 [PATCH 0/3] perf: parse the dwarf backtrace info from .debug_frame section Jean Pihet
2013-09-10  7:29 ` Jean Pihet
2013-09-12 12:07 ` Jean Pihet
2013-09-12 12:19   ` Peter Zijlstra
2013-09-12 12:28     ` Will Deacon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).