All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH kvm-unit-tests v7 0/5] Debugging aids
@ 2016-03-22 23:35 Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 1/5] lib: backtrace printing Peter Feiner
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

Paolo, please apply :-)

Some aids for debugging: stack dumping, register dumping, and printing
failing assertion conditions.

Compiled on ppc64, arm64, i386, x86_64.

v7:
	* Rebased.

v6:
	* Don't print dump_stack's call to backtrace() in the stack
	  trace rather than having backtrace() skip over the first
	  return address in the trace.
	* Actually removed lib/asm-generic/stack.c.

v5:
	* Removed unused "b" flag from run_tests.sh
	* Removed misleading comment in mkstandalone.sh.

v4:
	* Moved around arch and asm files per Linux style (hopefully).
	* Added --[enable|disable]-pretty-print-stacks to ./configure.
	  This has obviated the -p command-line option in
	  ./run_tests.sh that I introduced in v1.
	* Fixed arch-neutral backtrace so backtrace itself isn't
	  included.

v3:
	* Renamed functions to match standard backtrace functions
	* Added asm-generic stack walker that uses __builtin_return_address.
	* Moved offset out of libcflat and into pretty printer
	* Made pretty printer more robust w.r.t. errors: now it just
	  continues printing.

v2:
        * Fixed a bunch tests on x86 that broke with
          -fno-omit-frame-pointer.
        * Only use -fno-omit-frame-pointer on x86. I suspect arm & ppc
          will have similar problems that I fixed for x86.

Peter Feiner (5):
  lib: backtrace printing
  x86: lib: debug dump on unhandled exceptions
  lib: dump stack on failed assert()
  scripts: pretty print stack traces
  scripts: automatically pretty print stacks

 Makefile                       |  7 +--
 configure                      | 10 +++++
 lib/arm/asm/stack.h            |  0
 lib/arm64/asm/stack.h          |  0
 lib/libcflat.h                 |  9 +++-
 lib/powerpc/asm/stack.h        |  0
 lib/ppc64/asm/stack.h          |  0
 lib/stack.c                    | 96 ++++++++++++++++++++++++++++++++++++++++++
 lib/stack.h                    | 20 +++++++++
 lib/x86/asm/stack.h            | 14 ++++++
 lib/x86/desc.c                 | 69 +++++++++++++++++++++++++++---
 lib/x86/stack.c                | 31 ++++++++++++++
 run_tests.sh                   |  8 +++-
 scripts/mkstandalone.sh        |  2 +
 scripts/pretty_print_stacks.py | 89 +++++++++++++++++++++++++++++++++++++++
 x86/Makefile.common            |  4 ++
 16 files changed, 347 insertions(+), 12 deletions(-)
 create mode 100644 lib/arm/asm/stack.h
 create mode 100644 lib/arm64/asm/stack.h
 create mode 100644 lib/powerpc/asm/stack.h
 create mode 100644 lib/ppc64/asm/stack.h
 create mode 100644 lib/stack.c
 create mode 100644 lib/stack.h
 create mode 100644 lib/x86/asm/stack.h
 create mode 100644 lib/x86/stack.c
 create mode 100755 scripts/pretty_print_stacks.py

-- 
2.8.0.rc3.226.g39d4020


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

* [PATCH kvm-unit-tests v7 1/5] lib: backtrace printing
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
@ 2016-03-22 23:35 ` Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

Functions to walk stack and print backtrace. The stack's unadorned as

	STACK: [@]addr addr addr ...

where the optional @ indicates that addr isn't a return address.

A follow-up patch post-processes the output to pretty-print the stack.

Frame stack walker is just a stub on arm and ppc.

Signed-off-by: Peter Feiner <pfeiner@google.com>
Reviewed-By: Andrew Jones <drjones@redhat.com>
---
 Makefile                |  7 ++--
 lib/arm/asm/stack.h     |  0
 lib/arm64/asm/stack.h   |  0
 lib/libcflat.h          |  3 ++
 lib/powerpc/asm/stack.h |  0
 lib/ppc64/asm/stack.h   |  0
 lib/stack.c             | 96 +++++++++++++++++++++++++++++++++++++++++++++++++
 lib/stack.h             | 20 +++++++++++
 lib/x86/asm/stack.h     | 14 ++++++++
 lib/x86/stack.c         | 31 ++++++++++++++++
 x86/Makefile.common     |  4 +++
 11 files changed, 172 insertions(+), 3 deletions(-)
 create mode 100644 lib/arm/asm/stack.h
 create mode 100644 lib/arm64/asm/stack.h
 create mode 100644 lib/powerpc/asm/stack.h
 create mode 100644 lib/ppc64/asm/stack.h
 create mode 100644 lib/stack.c
 create mode 100644 lib/stack.h
 create mode 100644 lib/x86/asm/stack.h
 create mode 100644 lib/x86/stack.c

diff --git a/Makefile b/Makefile
index 2a2d942..5d7506e 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,8 @@ cflatobjs := \
 	lib/printf.o \
 	lib/string.o \
 	lib/abort.o \
-	lib/report.o
+	lib/report.o \
+	lib/stack.o
 
 # libfdt paths
 LIBFDT_objdir = lib/libfdt
@@ -42,8 +43,8 @@ cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
 
 CFLAGS += -g
 CFLAGS += $(autodepend-flags) -Wall -Werror
-
-fomit_frame_pointer := $(call cc-option, -fomit-frame-pointer, "")
+frame-pointer-flag=-f$(if $(KEEP_FRAME_POINTER),no-,)omit-frame-pointer
+fomit_frame_pointer := $(call cc-option, $(frame-pointer-flag), "")
 fnostack_protector := $(call cc-option, -fno-stack-protector, "")
 fnostack_protector_all := $(call cc-option, -fno-stack-protector-all, "")
 CFLAGS += $(fomit_frame_pointer)
diff --git a/lib/arm/asm/stack.h b/lib/arm/asm/stack.h
new file mode 100644
index 0000000..e69de29
diff --git a/lib/arm64/asm/stack.h b/lib/arm64/asm/stack.h
new file mode 100644
index 0000000..e69de29
diff --git a/lib/libcflat.h b/lib/libcflat.h
index b58a8a1..55bddca 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -81,6 +81,9 @@ extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
 extern void report_abort(const char *msg_fmt, ...);
 extern int report_summary(void);
 
+extern void dump_stack(void);
+extern void dump_frame_stack(const void *instruction, const void *frame);
+
 #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
 
 #define container_of(ptr, type, member) ({				\
diff --git a/lib/powerpc/asm/stack.h b/lib/powerpc/asm/stack.h
new file mode 100644
index 0000000..e69de29
diff --git a/lib/ppc64/asm/stack.h b/lib/ppc64/asm/stack.h
new file mode 100644
index 0000000..e69de29
diff --git a/lib/stack.c b/lib/stack.c
new file mode 100644
index 0000000..b0a0295
--- /dev/null
+++ b/lib/stack.c
@@ -0,0 +1,96 @@
+#include <libcflat.h>
+#include <stack.h>
+
+#define MAX_DEPTH 20
+
+static void print_stack(const void **return_addrs, int depth,
+			bool top_is_return_address)
+{
+	int i = 0;
+
+	printf("\tSTACK:");
+
+	/* @addr indicates a non-return address, as expected by the stack
+	 * pretty printer script. */
+	if (depth > 0 && !top_is_return_address) {
+		printf(" @%lx", (unsigned long) return_addrs[0]);
+		i++;
+	}
+
+	for (; i < depth; i++) {
+		printf(" %lx", (unsigned long) return_addrs[i]);
+	}
+	printf("\n");
+}
+
+void dump_stack(void)
+{
+	const void *return_addrs[MAX_DEPTH];
+	int depth;
+
+	depth = backtrace(return_addrs, MAX_DEPTH);
+	print_stack(&return_addrs[1], depth ? depth - 1 : 0, true);
+}
+
+void dump_frame_stack(const void *instruction, const void *frame)
+{
+	const void *return_addrs[MAX_DEPTH];
+	int depth;
+
+	return_addrs[0] = instruction;
+	depth = backtrace_frame(frame, &return_addrs[1], MAX_DEPTH - 1);
+	print_stack(return_addrs, depth + 1, false);
+}
+
+#ifndef HAVE_ARCH_BACKTRACE
+int backtrace(const void **return_addrs, int max_depth)
+{
+	static int walking;
+	int depth = 0;
+	void *addr;
+
+	if (walking) {
+		printf("RECURSIVE STACK WALK!!!\n");
+		return 0;
+	}
+	walking = 1;
+
+	/* __builtin_return_address requires a compile-time constant argument */
+#define GET_RETURN_ADDRESS(i)						\
+	if (max_depth == i)						\
+		goto done;						\
+	addr = __builtin_return_address(i);				\
+	if (!addr)							\
+		goto done;						\
+	return_addrs[i] = __builtin_extract_return_addr(addr);		\
+	depth = i + 1;							\
+
+	GET_RETURN_ADDRESS(0)
+	GET_RETURN_ADDRESS(1)
+	GET_RETURN_ADDRESS(2)
+	GET_RETURN_ADDRESS(3)
+	GET_RETURN_ADDRESS(4)
+	GET_RETURN_ADDRESS(5)
+	GET_RETURN_ADDRESS(6)
+	GET_RETURN_ADDRESS(7)
+	GET_RETURN_ADDRESS(8)
+	GET_RETURN_ADDRESS(9)
+	GET_RETURN_ADDRESS(10)
+	GET_RETURN_ADDRESS(11)
+	GET_RETURN_ADDRESS(12)
+	GET_RETURN_ADDRESS(13)
+	GET_RETURN_ADDRESS(14)
+	GET_RETURN_ADDRESS(15)
+	GET_RETURN_ADDRESS(16)
+	GET_RETURN_ADDRESS(17)
+	GET_RETURN_ADDRESS(18)
+	GET_RETURN_ADDRESS(19)
+	GET_RETURN_ADDRESS(20)
+
+#undef GET_RETURN_ADDRESS
+
+done:
+	walking = 0;
+	return depth;
+}
+#endif  /* HAVE_ARCH_BACKTRACE */
diff --git a/lib/stack.h b/lib/stack.h
new file mode 100644
index 0000000..bb6b9aa
--- /dev/null
+++ b/lib/stack.h
@@ -0,0 +1,20 @@
+#ifndef _STACK_H_
+#define _STACK_H_
+
+#include <libcflat.h>
+#include <asm/stack.h>
+
+#ifndef HAVE_ARCH_BACKTRACE_FRAME
+static inline int
+backtrace_frame(const void *frame __unused, const void **return_addrs __unused,
+		int max_depth __unused)
+{
+	return 0;
+}
+#endif
+
+#ifndef HAVE_ARCH_BACKTRACE
+int backtrace(const void **return_addrs, int max_depth);
+#endif
+
+#endif
diff --git a/lib/x86/asm/stack.h b/lib/x86/asm/stack.h
new file mode 100644
index 0000000..fc4766d
--- /dev/null
+++ b/lib/x86/asm/stack.h
@@ -0,0 +1,14 @@
+#ifndef _X86ASM_STACK_H_
+#define _X86ASM_STACK_H_
+
+#ifndef _STACK_H_
+#error Do not directly include <asm/stack.h>. Just use <stack.h>.
+#endif
+
+#define HAVE_ARCH_BACKTRACE_FRAME
+int backtrace_frame(const void *frame, const void **return_addrs, int max_depth);
+
+#define HAVE_ARCH_BACKTRACE
+int backtrace(const void **return_addrs, int max_depth);
+
+#endif
diff --git a/lib/x86/stack.c b/lib/x86/stack.c
new file mode 100644
index 0000000..d75c0be
--- /dev/null
+++ b/lib/x86/stack.c
@@ -0,0 +1,31 @@
+#include <libcflat.h>
+#include <stack.h>
+
+int backtrace_frame(const void *frame, const void **return_addrs, int max_depth)
+{
+	static int walking;
+	int depth = 0;
+	const unsigned long *bp = (unsigned long *) frame;
+
+	if (walking) {
+		printf("RECURSIVE STACK WALK!!!\n");
+		return 0;
+	}
+	walking = 1;
+
+	for (depth = 0; depth < max_depth; depth++) {
+		return_addrs[depth] = (void *) bp[1];
+		if (return_addrs[depth] == 0)
+			break;
+		bp = (unsigned long *) bp[0];
+	}
+
+	walking = 0;
+	return depth;
+}
+
+int backtrace(const void **return_addrs, int max_depth)
+{
+	return backtrace_frame(__builtin_frame_address(0), return_addrs,
+			       max_depth);
+}
diff --git a/x86/Makefile.common b/x86/Makefile.common
index 3a14fea..ca80367 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -12,6 +12,7 @@ cflatobjs += lib/x86/atomic.o
 cflatobjs += lib/x86/desc.o
 cflatobjs += lib/x86/isr.o
 cflatobjs += lib/x86/acpi.o
+cflatobjs += lib/x86/stack.o
 
 $(libcflat): LDFLAGS += -nostdlib
 $(libcflat): CFLAGS += -ffreestanding -I lib
@@ -19,6 +20,9 @@ $(libcflat): CFLAGS += -ffreestanding -I lib
 CFLAGS += -m$(bits)
 CFLAGS += -O1
 
+# dump_stack.o relies on frame pointers.
+KEEP_FRAME_POINTER := y
+
 libgcc := $(shell $(CC) -m$(bits) --print-libgcc-file-name)
 
 FLATLIBS = lib/libcflat.a $(libgcc)
-- 
2.8.0.rc3.226.g39d4020


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

* [PATCH kvm-unit-tests v7 2/5] x86: lib: debug dump on unhandled exceptions
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 1/5] lib: backtrace printing Peter Feiner
@ 2016-03-22 23:35 ` Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 3/5] lib: dump stack on failed assert() Peter Feiner
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

Prints the stack trace and registers.

Signed-off-by: Peter Feiner <pfeiner@google.com>
Reviewed-By: Andrew Jones <drjones@redhat.com>
---
 lib/x86/desc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index 16cbba5..75765ef 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -38,6 +38,67 @@ struct ex_record {
 
 extern struct ex_record exception_table_start, exception_table_end;
 
+static const char* exception_mnemonic(int vector)
+{
+	switch(vector) {
+	case 0: return "#DE";
+	case 1: return "#DB";
+	case 2: return "#NMI";
+	case 3: return "#BP";
+	case 4: return "#OF";
+	case 5: return "#BR";
+	case 6: return "#UD";
+	case 7: return "#NM";
+	case 8: return "#DF";
+	case 10: return "#TS";
+	case 11: return "#NP";
+	case 12: return "#SS";
+	case 13: return "#GP";
+	case 14: return "#PF";
+	case 16: return "#MF";
+	case 17: return "#AC";
+	case 18: return "#MC";
+	case 19: return "#XM";
+	default: return "#??";
+	}
+}
+
+static void unhandled_exception(struct ex_regs *regs, bool cpu)
+{
+	printf("Unhandled %sexception %ld %s at ip %016lx\n",
+	       cpu ? "cpu " : "", regs->vector,
+	       exception_mnemonic(regs->vector), regs->rip);
+	if (regs->vector == 14)
+		printf("PF at 0x%lx addr 0x%lx\n", regs->rip, read_cr2());
+
+	printf("error_code=%04lx      rflags=%08lx      cs=%08lx\n"
+	       "rax=%016lx rcx=%016lx rdx=%016lx rbx=%016lx\n"
+	       "rbp=%016lx rsi=%016lx rdi=%016lx\n"
+#ifdef __x86_64__
+	       " r8=%016lx  r9=%016lx r10=%016lx r11=%016lx\n"
+	       "r12=%016lx r13=%016lx r14=%016lx r15=%016lx\n"
+#endif
+	       "cr0=%016lx cr2=%016lx cr3=%016lx cr4=%016lx\n"
+#ifdef __x86_64__
+	       "cr8=%016lx\n"
+#endif
+	       ,
+	       regs->error_code, regs->rflags, regs->cs,
+	       regs->rax, regs->rcx, regs->rdx, regs->rbx,
+	       regs->rbp, regs->rsi, regs->rdi,
+#ifdef __x86_64__
+	       regs->r8, regs->r9, regs->r10, regs->r11,
+	       regs->r12, regs->r13, regs->r14, regs->r15,
+#endif
+	       read_cr0(), read_cr2(), read_cr3(), read_cr4()
+#ifdef __x86_64__
+	       , read_cr8()
+#endif
+	);
+	dump_frame_stack((void*) regs->rip, (void*) regs->rbp);
+	exit(7);
+}
+
 static void check_exception_table(struct ex_regs *regs)
 {
     struct ex_record *ex;
@@ -53,8 +114,7 @@ static void check_exception_table(struct ex_regs *regs)
             return;
         }
     }
-    printf("unhandled exception %lu\n", regs->vector);
-    abort();
+    unhandled_exception(regs, false);
 }
 
 static void (*exception_handlers[32])(struct ex_regs *regs);
@@ -75,10 +135,7 @@ void do_handle_exception(struct ex_regs *regs)
 		exception_handlers[regs->vector](regs);
 		return;
 	}
-	printf("unhandled cpu exception %lu\n", regs->vector);
-	if (regs->vector == 14)
-		printf("PF at 0x%lx addr 0x%lx\n", regs->rip, read_cr2());
-	abort();
+	unhandled_exception(regs, true);
 }
 
 #define EX(NAME, N) extern char NAME##_fault;	\
-- 
2.8.0.rc3.226.g39d4020


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

* [PATCH kvm-unit-tests v7 3/5] lib: dump stack on failed assert()
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 1/5] lib: backtrace printing Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
@ 2016-03-22 23:35 ` Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 4/5] scripts: pretty print stack traces Peter Feiner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

Signed-off-by: Peter Feiner <pfeiner@google.com>
Reviewed-By: Andrew Jones <drjones@redhat.com>
---
 lib/libcflat.h | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/libcflat.h b/lib/libcflat.h
index 55bddca..df50615 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -92,10 +92,12 @@ extern void dump_frame_stack(const void *instruction, const void *frame);
 
 #define assert(cond)							\
 do {									\
-	if (!(cond))							\
+	if (!(cond)) {							\
 		printf("%s:%d: assert failed: %s\n",			\
-		       __FILE__, __LINE__, #cond),			\
+		       __FILE__, __LINE__, #cond);			\
+		dump_stack();						\
 		abort();						\
+	}								\
 } while (0)
 
 #endif
-- 
2.8.0.rc3.226.g39d4020


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

* [PATCH kvm-unit-tests v7 4/5] scripts: pretty print stack traces
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
                   ` (2 preceding siblings ...)
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 3/5] lib: dump stack on failed assert() Peter Feiner
@ 2016-03-22 23:35 ` Peter Feiner
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks Peter Feiner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

The script runs addresses through addr2line to get file names and line
numbers.  Also prints out source code lines if files are available.
For example

0x004013f5: ac_test_exec at x86/access.c:818
            }
      >     ac_test_setup_pte(at, pool);
            r = ac_test_do_access(at);
0x004014dd: ac_test_run at x86/access.c:852
                ++tests;
      >         successes += ac_test_exec(&at, &pool);
            } while (ac_test_bump(&at));
0x0040157d: main at x86/access.c:873
            printf("starting test\n\n");
      >     r = ac_test_run();
            return r ? 0 : 1;
0x0040028e: start64 at x86/cstart64.S:206
                lea __argv(%rip), %rsi
      >         call main
                mov %eax, %edi

Signed-off-by: Peter Feiner <pfeiner@google.com>
Reviewed-By: Andrew Jones <drjones@redhat.com>
---
 scripts/pretty_print_stacks.py | 89 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100755 scripts/pretty_print_stacks.py

diff --git a/scripts/pretty_print_stacks.py b/scripts/pretty_print_stacks.py
new file mode 100755
index 0000000..ee5a52e
--- /dev/null
+++ b/scripts/pretty_print_stacks.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+import re
+import subprocess
+import sys
+import traceback
+
+# Subvert output buffering.
+def puts(string):
+    sys.stdout.write(string)
+    sys.stdout.flush()
+
+def pretty_print_stack(binary, line):
+    addrs = line.split()[1:]
+    # Addresses are return addresses unless preceded by a '@'. We want the
+    # caller address so line numbers are more intuitive. Thus we subtract 1
+    # from the address to get the call code.
+    for i in range(len(addrs)):
+        addr = addrs[i]
+        if addr.startswith('@'):
+            addrs[i] = addr[1:]
+        else:
+            addrs[i] = '%lx' % (int(addrs[i], 16) - 1)
+
+    # Output like this:
+    #        0x004002be: start64 at path/to/kvm-unit-tests/x86/cstart64.S:208
+    #         (inlined by) test_ept_violation at path/to/kvm-unit-tests/x86/vmx_tests.c:1719 (discriminator 1)
+    cmd = ['addr2line', '-e', binary, '-i', '-f', '--pretty', '--address']
+    cmd.extend(addrs)
+
+    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+    out, err = p.communicate()
+    if p.returncode != 0:
+        puts(line)
+        return
+
+    for line in out.splitlines():
+        m = re.match('(.*) at [^ ]*/kvm-unit-tests/([^ ]*):([0-9]+)(.*)', line)
+        if m is None:
+            puts('%s\n' % line)
+            return
+
+        head, path, line, tail = m.groups()
+        line = int(line)
+        puts('%s at %s:%d%s\n' % (head, path, line, tail))
+        try:
+            lines = open(path).readlines()
+        except IOError:
+            continue
+        if line > 1:
+            puts('        %s\n' % lines[line - 2].rstrip())
+        puts('      > %s\n' % lines[line - 1].rstrip())
+        if line < len(lines):
+            puts('        %s\n' % lines[line].rstrip())
+
+def main():
+    if len(sys.argv) != 2:
+        sys.stderr.write('usage: %s <kernel>\n' % sys.argv[0])
+        sys.exit(1)
+
+    binary = sys.argv[1]
+
+    try:
+        while True:
+            # Subvert input buffering.
+            line = sys.stdin.readline()
+            if line == '':
+                break
+
+            if not line.strip().startswith('STACK:'):
+                puts(line)
+                continue
+
+            try:
+                pretty_print_stack(binary, line)
+            except Exception:
+                puts('Error pretty printing stack:\n')
+                puts(traceback.format_exc())
+                puts('Continuing without pretty printing...\n')
+                while True:
+                    puts(line)
+                    line = sys.stdin.readline()
+                    if line == '':
+                        break
+    except:
+        sys.exit(1)
+
+if __name__ == '__main__':
+    main()
-- 
2.8.0.rc3.226.g39d4020


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

* [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
                   ` (3 preceding siblings ...)
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 4/5] scripts: pretty print stack traces Peter Feiner
@ 2016-03-22 23:35 ` Peter Feiner
  2016-03-29 11:13   ` Paolo Bonzini
  2016-03-29 11:13 ` [PATCH kvm-unit-tests v7 0/5] Debugging aids Paolo Bonzini
  2016-04-06 11:28 ` Paolo Bonzini
  6 siblings, 1 reply; 11+ messages in thread
From: Peter Feiner @ 2016-03-22 23:35 UTC (permalink / raw)
  To: drjones, pbonzini, kvm; +Cc: pfeiner

Now run_tests.sh automatically pipes test output through
scripts/pretty_print_stacks.py. Can be disabled with
./configure --disable-pretty-print-stacks.

Pretty printing disabled on standalone tests because there's no
binary.

Signed-off-by: Peter Feiner <pfeiner@google.com>
Reviewed-By: Andrew Jones <drjones@redhat.com>
---
 configure               | 10 ++++++++++
 run_tests.sh            |  8 +++++++-
 scripts/mkstandalone.sh |  2 ++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/configure b/configure
index 958321d..ba6c55b 100755
--- a/configure
+++ b/configure
@@ -11,6 +11,7 @@ arch=`uname -m | sed -e 's/i.86/i386/;s/arm.*/arm/;s/ppc64.*/ppc64/'`
 host=$arch
 cross_prefix=
 endian=""
+pretty_print_stacks=yes
 
 usage() {
     cat <<-EOF
@@ -25,6 +26,8 @@ usage() {
 	    --prefix=PREFIX        where to install things ($prefix)
 	    --kerneldir=DIR        kernel build directory for kvm.h ($kerneldir)
 	    --endian=ENDIAN        endianness to compile for (little or big, ppc64 only)
+	    --[enable|disable]-pretty-print-stacks
+	                           enable or disable pretty stack printing (enabled by default)
 EOF
     exit 1
 }
@@ -61,6 +64,12 @@ while [[ "$1" = -* ]]; do
 	--ld)
 	    ld="$arg"
 	    ;;
+	--enable-pretty-print-stacks)
+	    pretty_print_stacks=yes
+	    ;;
+	--disable-pretty-print-stacks)
+	    pretty_print_stacks=no
+	    ;;
 	--help)
 	    usage
 	    ;;
@@ -149,4 +158,5 @@ API=$api
 TEST_DIR=$testdir
 FIRMWARE=$firmware
 ENDIAN=$endian
+PRETTY_PRINT_STACKS=$pretty_print_stacks
 EOF
diff --git a/run_tests.sh b/run_tests.sh
index 89e8f84..7e0237f 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -46,7 +46,13 @@ while getopts "g:hv" opt; do
     esac
 done
 
-RUNTIME_arch_run="./$TEST_DIR/run >> test.log"
+if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
+	log_redir="> >(./scripts/pretty_print_stacks.py \$kernel >> test.log)"
+else
+	log_redir=">> test.log"
+fi
+
+RUNTIME_arch_run="./$TEST_DIR/run $log_redir"
 config=$TEST_DIR/unittests.cfg
 rm -f test.log
 printf "BUILD_HEAD=$(cat build-head)\n\n" > test.log
diff --git a/scripts/mkstandalone.sh b/scripts/mkstandalone.sh
index 1d3a20d..ef15bc8 100755
--- a/scripts/mkstandalone.sh
+++ b/scripts/mkstandalone.sh
@@ -41,6 +41,8 @@ generate_test ()
 	echo "#!/bin/bash"
 	echo "export STANDALONE=yes"
 	echo "export HOST=\$(uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/')"
+	echo "export PRETTY_PRINT_STACKS=no"
+
 	config_export ARCH
 	config_export ARCH_NAME
 	config_export PROCESSOR
-- 
2.8.0.rc3.226.g39d4020


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

* Re: [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks Peter Feiner
@ 2016-03-29 11:13   ` Paolo Bonzini
  2016-03-31 23:33     ` Peter Feiner
  0 siblings, 1 reply; 11+ messages in thread
From: Paolo Bonzini @ 2016-03-29 11:13 UTC (permalink / raw)
  To: Peter Feiner, drjones, kvm



On 23/03/2016 00:35, Peter Feiner wrote:
> +if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
> +	log_redir="> >(./scripts/pretty_print_stacks.py \$kernel >> test.log)"

Isn't this the same as "| ./scripts/pretty_print_stack.py \$kernel >>
test.log"?

If so, perhaps

if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
  stack_filter="./scripts/pretty_print_stack.py \$kernel"
else
  stack_filter=cat

RUNTIME_arch_run="./$TEST_DIR/run | $stack_filter >> test.log"

... would be a bit easier to read.

Paolo

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

* Re: [PATCH kvm-unit-tests v7 0/5] Debugging aids
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
                   ` (4 preceding siblings ...)
  2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks Peter Feiner
@ 2016-03-29 11:13 ` Paolo Bonzini
  2016-04-06 11:28 ` Paolo Bonzini
  6 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2016-03-29 11:13 UTC (permalink / raw)
  To: Peter Feiner, drjones, kvm



On 23/03/2016 00:35, Peter Feiner wrote:
> Paolo, please apply :-)
> 
> Some aids for debugging: stack dumping, register dumping, and printing
> failing assertion conditions.
> 
> Compiled on ppc64, arm64, i386, x86_64.

Applied patches 1-4.

Paolo

> v7:
> 	* Rebased.
> 
> v6:
> 	* Don't print dump_stack's call to backtrace() in the stack
> 	  trace rather than having backtrace() skip over the first
> 	  return address in the trace.
> 	* Actually removed lib/asm-generic/stack.c.
> 
> v5:
> 	* Removed unused "b" flag from run_tests.sh
> 	* Removed misleading comment in mkstandalone.sh.
> 
> v4:
> 	* Moved around arch and asm files per Linux style (hopefully).
> 	* Added --[enable|disable]-pretty-print-stacks to ./configure.
> 	  This has obviated the -p command-line option in
> 	  ./run_tests.sh that I introduced in v1.
> 	* Fixed arch-neutral backtrace so backtrace itself isn't
> 	  included.
> 
> v3:
> 	* Renamed functions to match standard backtrace functions
> 	* Added asm-generic stack walker that uses __builtin_return_address.
> 	* Moved offset out of libcflat and into pretty printer
> 	* Made pretty printer more robust w.r.t. errors: now it just
> 	  continues printing.
> 
> v2:
>         * Fixed a bunch tests on x86 that broke with
>           -fno-omit-frame-pointer.
>         * Only use -fno-omit-frame-pointer on x86. I suspect arm & ppc
>           will have similar problems that I fixed for x86.
> 
> Peter Feiner (5):
>   lib: backtrace printing
>   x86: lib: debug dump on unhandled exceptions
>   lib: dump stack on failed assert()
>   scripts: pretty print stack traces
>   scripts: automatically pretty print stacks
> 
>  Makefile                       |  7 +--
>  configure                      | 10 +++++
>  lib/arm/asm/stack.h            |  0
>  lib/arm64/asm/stack.h          |  0
>  lib/libcflat.h                 |  9 +++-
>  lib/powerpc/asm/stack.h        |  0
>  lib/ppc64/asm/stack.h          |  0
>  lib/stack.c                    | 96 ++++++++++++++++++++++++++++++++++++++++++
>  lib/stack.h                    | 20 +++++++++
>  lib/x86/asm/stack.h            | 14 ++++++
>  lib/x86/desc.c                 | 69 +++++++++++++++++++++++++++---
>  lib/x86/stack.c                | 31 ++++++++++++++
>  run_tests.sh                   |  8 +++-
>  scripts/mkstandalone.sh        |  2 +
>  scripts/pretty_print_stacks.py | 89 +++++++++++++++++++++++++++++++++++++++
>  x86/Makefile.common            |  4 ++
>  16 files changed, 347 insertions(+), 12 deletions(-)
>  create mode 100644 lib/arm/asm/stack.h
>  create mode 100644 lib/arm64/asm/stack.h
>  create mode 100644 lib/powerpc/asm/stack.h
>  create mode 100644 lib/ppc64/asm/stack.h
>  create mode 100644 lib/stack.c
>  create mode 100644 lib/stack.h
>  create mode 100644 lib/x86/asm/stack.h
>  create mode 100644 lib/x86/stack.c
>  create mode 100755 scripts/pretty_print_stacks.py
> 

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

* Re: [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks
  2016-03-29 11:13   ` Paolo Bonzini
@ 2016-03-31 23:33     ` Peter Feiner
  2016-04-01  8:38       ` Paolo Bonzini
  0 siblings, 1 reply; 11+ messages in thread
From: Peter Feiner @ 2016-03-31 23:33 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: drjones, kvm

On Tue, Mar 29, 2016 at 01:13:30PM +0200, Paolo Bonzini wrote:
> 
> 
> On 23/03/2016 00:35, Peter Feiner wrote:
> > +if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
> > +	log_redir="> >(./scripts/pretty_print_stacks.py \$kernel >> test.log)"
> 
> Isn't this the same as "| ./scripts/pretty_print_stack.py \$kernel >>
> test.log"?

Not the same. Consider scripts/runtime.bash's usage:

	cmdline="...$RUNTIME_arch_run $kernel -smp $smp $opts"

With your alternative, the command-line arguments after $RUNTIME_arch_run
are be passed to pretty_print_stacks.py instead of Qemu.

> If so, perhaps
> 
> if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
>   stack_filter="./scripts/pretty_print_stack.py \$kernel"
> else
>   stack_filter=cat
> 
> RUNTIME_arch_run="./$TEST_DIR/run | $stack_filter >> test.log"
> 
> ... would be a bit easier to read.

Yes, it's super ugly, but it works!

Peter

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

* Re: [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks
  2016-03-31 23:33     ` Peter Feiner
@ 2016-04-01  8:38       ` Paolo Bonzini
  0 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2016-04-01  8:38 UTC (permalink / raw)
  To: Peter Feiner; +Cc: drjones, kvm



On 01/04/2016 01:33, Peter Feiner wrote:
>> > 
>> > On 23/03/2016 00:35, Peter Feiner wrote:
>>> > > +if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
>>> > > +	log_redir="> >(./scripts/pretty_print_stacks.py \$kernel >> test.log)"
>> > 
>> > Isn't this the same as "| ./scripts/pretty_print_stack.py \$kernel >>
>> > test.log"?
> Not the same. Consider scripts/runtime.bash's usage:
> 
> 	cmdline="...$RUNTIME_arch_run $kernel -smp $smp $opts"
> 
> With your alternative, the command-line arguments after $RUNTIME_arch_run
> are be passed to pretty_print_stacks.py instead of Qemu.

Ok, I'll add a comment then.

Paolo

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

* Re: [PATCH kvm-unit-tests v7 0/5] Debugging aids
  2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
                   ` (5 preceding siblings ...)
  2016-03-29 11:13 ` [PATCH kvm-unit-tests v7 0/5] Debugging aids Paolo Bonzini
@ 2016-04-06 11:28 ` Paolo Bonzini
  6 siblings, 0 replies; 11+ messages in thread
From: Paolo Bonzini @ 2016-04-06 11:28 UTC (permalink / raw)
  To: Peter Feiner, drjones, kvm



On 23/03/2016 00:35, Peter Feiner wrote:
> Paolo, please apply :-)
> 
> Some aids for debugging: stack dumping, register dumping, and printing
> failing assertion conditions.
> 
> Compiled on ppc64, arm64, i386, x86_64.

Applied, thanks.

Paolo

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

end of thread, other threads:[~2016-04-06 11:28 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-22 23:35 [PATCH kvm-unit-tests v7 0/5] Debugging aids Peter Feiner
2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 1/5] lib: backtrace printing Peter Feiner
2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 3/5] lib: dump stack on failed assert() Peter Feiner
2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 4/5] scripts: pretty print stack traces Peter Feiner
2016-03-22 23:35 ` [PATCH kvm-unit-tests v7 5/5] scripts: automatically pretty print stacks Peter Feiner
2016-03-29 11:13   ` Paolo Bonzini
2016-03-31 23:33     ` Peter Feiner
2016-04-01  8:38       ` Paolo Bonzini
2016-03-29 11:13 ` [PATCH kvm-unit-tests v7 0/5] Debugging aids Paolo Bonzini
2016-04-06 11:28 ` Paolo Bonzini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.