Commit aa16b81f authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo
Browse files

perf tests x86: Add dwarf unwind test



Adding dwarf unwind test, that setups live machine data over the perf
test thread and does the remote unwind.

At this moment this test fails due to bug in the max_stack processing in
unwind__get_entries function.  This is fixed in following patch.

Need to use -fno-optimize-sibling-calls for test compilation, otherwise
'krava_*' function calls are optimized into jumps and ommited from the
stack unwind.

So far it's enabled only for x86.

Signed-off-by: default avatarJiri Olsa <jolsa@redhat.com>
Acked-by: default avatarJean Pihet <jean.pihet@linaro.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1389098853-14466-6-git-send-email-jolsa@redhat.com


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 3c8b06f9
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -408,6 +408,11 @@ endif
LIB_OBJS += $(OUTPUT)tests/code-reading.o
LIB_OBJS += $(OUTPUT)tests/sample-parsing.o
LIB_OBJS += $(OUTPUT)tests/parse-no-sample-id-all.o
ifndef NO_LIBUNWIND
ifeq ($(ARCH),x86)
LIB_OBJS += $(OUTPUT)tests/dwarf-unwind.o
endif
endif

BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
@@ -655,6 +660,9 @@ $(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
		-DPYTHON='"$(PYTHON_WORD)"' \
		$<

$(OUTPUT)tests/dwarf-unwind.o: tests/dwarf-unwind.c
	$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -fno-optimize-sibling-calls $<

$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
	$(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<

+1 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ endif
ifndef NO_LIBUNWIND
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/unwind.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/regs_load.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/tests/dwarf-unwind.o
endif
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o
+4 −0
Original line number Diff line number Diff line
@@ -9,12 +9,16 @@ void perf_regs_load(u64 *regs);

#ifndef HAVE_ARCH_X86_64_SUPPORT
#define PERF_REGS_MASK ((1ULL << PERF_REG_X86_32_MAX) - 1)
#define PERF_REGS_MAX PERF_REG_X86_32_MAX
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_32
#else
#define REG_NOSUPPORT ((1ULL << PERF_REG_X86_DS) | \
		       (1ULL << PERF_REG_X86_ES) | \
		       (1ULL << PERF_REG_X86_FS) | \
		       (1ULL << PERF_REG_X86_GS))
#define PERF_REGS_MASK (((1ULL << PERF_REG_X86_64_MAX) - 1) & ~REG_NOSUPPORT)
#define PERF_REGS_MAX PERF_REG_X86_64_MAX
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
#endif
#define PERF_REG_IP PERF_REG_X86_IP
#define PERF_REG_SP PERF_REG_X86_SP
+58 −0
Original line number Diff line number Diff line
#include <string.h>
#include "perf_regs.h"
#include "thread.h"
#include "map.h"
#include "event.h"
#include "tests/tests.h"

#define STACK_SIZE 8192

static int sample_ustack(struct perf_sample *sample,
			 struct thread *thread, u64 *regs)
{
	struct stack_dump *stack = &sample->user_stack;
	struct map *map;
	unsigned long sp;
	u64 stack_size, *buf;

	buf = malloc(STACK_SIZE);
	if (!buf) {
		pr_debug("failed to allocate sample uregs data\n");
		return -1;
	}

	sp = (unsigned long) regs[PERF_REG_X86_SP];

	map = map_groups__find(&thread->mg, MAP__FUNCTION, (u64) sp);
	if (!map) {
		pr_debug("failed to get stack map\n");
		return -1;
	}

	stack_size = map->end - sp;
	stack_size = stack_size > STACK_SIZE ? STACK_SIZE : stack_size;

	memcpy(buf, (void *) sp, stack_size);
	stack->data = (char *) buf;
	stack->size = stack_size;
	return 0;
}

int test__arch_unwind_sample(struct perf_sample *sample,
			     struct thread *thread)
{
	struct regs_dump *regs = &sample->user_regs;
	u64 *buf;

	buf = malloc(sizeof(u64) * PERF_REGS_MAX);
	if (!buf) {
		pr_debug("failed to allocate sample uregs data\n");
		return -1;
	}

	perf_regs_load(buf);
	regs->abi  = PERF_SAMPLE_REGS_ABI;
	regs->regs = buf;

	return sample_ustack(sample, thread, buf);
}
+8 −0
Original line number Diff line number Diff line
@@ -115,6 +115,14 @@ static struct test {
		.desc = "Test parsing with no sample_id_all bit set",
		.func = test__parse_no_sample_id_all,
	},
#if defined(__x86_64__) || defined(__i386__)
#ifdef HAVE_LIBUNWIND_SUPPORT
	{
		.desc = "Test dwarf unwind",
		.func = test__dwarf_unwind,
	},
#endif
#endif
	{
		.func = NULL,
	},
Loading