All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <drjones@redhat.com>
To: Peter Feiner <pfeiner@google.com>
Cc: kvm@vger.kernel.org, pbonzini@redhat.com
Subject: Re: [kvm-unit-tests v2 5/8] lib: backtrace printing
Date: Thu, 3 Mar 2016 10:17:46 +0100	[thread overview]
Message-ID: <20160303091746.GA1515@localhost.redhat.com> (raw)
In-Reply-To: <1456967378-6367-6-git-send-email-pfeiner@google.com>

On Wed, Mar 02, 2016 at 05:09:35PM -0800, Peter Feiner wrote:
> Functions to walk stack and print backtrace. The stack's unadorned as
> 
> 	STACK: addr addr addr ...
> 
> A follow-up patch post-processes the output to pretty-print the stack.
> 
> Stack walker is just a stub on arm and ppc.
> 
> Signed-off-by: Peter Feiner <pfeiner@google.com>
> ---
>  Makefile                 |  3 ++-
>  arm/Makefile.common      |  1 +
>  lib/arm/dump_stack.c     |  6 ++++++
>  lib/libcflat.h           |  4 ++++
>  lib/powerpc/dump_stack.c |  6 ++++++
>  lib/printf.c             | 37 +++++++++++++++++++++++++++++++++++++
>  lib/x86/dump_stack.c     | 24 ++++++++++++++++++++++++
>  powerpc/Makefile.common  |  1 +
>  x86/Makefile.common      |  4 ++++
>  9 files changed, 85 insertions(+), 1 deletion(-)
>  create mode 100644 lib/arm/dump_stack.c
>  create mode 100644 lib/powerpc/dump_stack.c
>  create mode 100644 lib/x86/dump_stack.c
> 
> diff --git a/Makefile b/Makefile
> index ddba941..40ea4ec 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -42,7 +42,8 @@ cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
>  
>  CFLAGS += -g
>  CFLAGS += $(autodepend-flags) -Wall
> -CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
> +frame-pointer-flag=-f$(if $(KEEP_FRAME_POINTER),no-,)omit-frame-pointer
> +CFLAGS += $(call cc-option, $(frame-pointer-flag), "")
>  CFLAGS += $(call cc-option, -fno-stack-protector, "")
>  CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
>  
> diff --git a/arm/Makefile.common b/arm/Makefile.common
> index dd3a0ca..054bdee 100644
> --- a/arm/Makefile.common
> +++ b/arm/Makefile.common
> @@ -39,6 +39,7 @@ cflatobjs += lib/arm/mmu.o
>  cflatobjs += lib/arm/bitops.o
>  cflatobjs += lib/arm/psci.o
>  cflatobjs += lib/arm/smp.o
> +cflatobjs += lib/arm/dump_stack.o
>  
>  libeabi = lib/arm/libeabi.a
>  eabiobjs = lib/arm/eabi_compat.o
> diff --git a/lib/arm/dump_stack.c b/lib/arm/dump_stack.c
> new file mode 100644
> index 0000000..528ba63
> --- /dev/null
> +++ b/lib/arm/dump_stack.c
> @@ -0,0 +1,6 @@
> +#include "libcflat.h"
> +
> +int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
> +{
> +	return 0;
> +}
> diff --git a/lib/libcflat.h b/lib/libcflat.h
> index 1f0049c..42c94df 100644
> --- a/lib/libcflat.h
> +++ b/lib/libcflat.h
> @@ -65,6 +65,10 @@ 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);
>  
> +int walk_stack(unsigned long bp, unsigned long *stack, int max_depth);
> +void dump_stack(unsigned long ip, unsigned long bp);
> +void dump_current_stack(void);

The inputs are a bit x86ish. On ARM, for example, we call them pc and
fp. Acutally, how about we implement backtrace(3) instead? And then wrap
print_current_stack(void) around that.

Also, instead of building on a single arch function, walk_stack, how about
two

  void *arch_frame_address(unsigned int level);
  void *arch_return_address(void *frame, unsigned int level);

The architecture may be able to easily implement these with gcc builtins,
or not. I've added *frame to arch_return_address' parameters in case
__builtin_return_address(level) doesn't work. 

And, let's just require the architectures to have the functions, not that
they have a dump_stack.c file. If we include lib/asm/<ARCH>/stack.h, or
whatever you want to call it, then the arch could just supply some inlines
there.

> +
>  #define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
>  
>  #define container_of(ptr, type, member) ({				\
> diff --git a/lib/powerpc/dump_stack.c b/lib/powerpc/dump_stack.c
> new file mode 100644
> index 0000000..528ba63
> --- /dev/null
> +++ b/lib/powerpc/dump_stack.c
> @@ -0,0 +1,6 @@
> +#include "libcflat.h"
> +
> +int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
> +{
> +	return 0;
> +}
> diff --git a/lib/printf.c b/lib/printf.c
> index 2aec59a..e97fca9 100644
> --- a/lib/printf.c
> +++ b/lib/printf.c
> @@ -259,3 +259,40 @@ int printf(const char *fmt, ...)
>      puts(buf);
>      return r;
>  }
> +
> +static void print_stack(unsigned long *stack, int depth,
> +			bool top_is_return_address)
> +{
> +	int i;
> +
> +	printf("\tSTACK: " );
> +	for (i = 0; i < depth; i++) {
> +		int offset = -1;
> +		if (i == 0 && !top_is_return_address)
> +			offset = 0;
> +		printf(" %lx", stack[i] + offset);

I'm afraid I don't understand the use of offset here. I fear it may
be x86-ness leaked into the arch-neutral print_stack().

> +	}
> +	printf("\n");
> +}
> +
> +#define MAX_DEPTH 10
> +
> +void dump_stack(unsigned long ip, unsigned long bp)
> +{
> +	unsigned long stack[MAX_DEPTH];
> +	int depth;
> +
> +	stack[0] = ip;
> +	depth = walk_stack(bp, &stack[1], MAX_DEPTH - 1);
> +	print_stack(stack, depth + 1, false);
> +}

When would dump_stack() be useful, as opposed to dump_current_stack?

> +
> +void dump_current_stack(void)
> +{
> +	unsigned long stack[MAX_DEPTH];
> +	int depth;
> +
> +	depth = walk_stack((unsigned long)__builtin_frame_address(1), stack,
> +			   MAX_DEPTH);
> +	print_stack(stack, depth, true);
> +}
> diff --git a/lib/x86/dump_stack.c b/lib/x86/dump_stack.c
> new file mode 100644
> index 0000000..6e9d126
> --- /dev/null
> +++ b/lib/x86/dump_stack.c
> @@ -0,0 +1,24 @@
> +#include "libcflat.h"
> +
> +int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
> +{
> +	static int walking;
> +	int depth = 0;
> +	unsigned long *frame = (unsigned long *) bp;
> +
> +	if (walking) {
> +		printf("RECURSIVE STACK WALK!!!\n");
> +		return 0;
> +	}
> +	walking = 1;
> +
> +	for (depth = 0; depth < max_depth; depth++) {
> +		stack[depth] = frame[1];
> +		if (stack[depth] == 0)
> +			break;
> +		frame = (unsigned long *) frame[0];
> +	}
> +
> +	walking = 0;
> +	return depth;
> +}
> diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> index 2ce6494..694dea0 100644
> --- a/powerpc/Makefile.common
> +++ b/powerpc/Makefile.common
> @@ -30,6 +30,7 @@ cflatobjs += lib/powerpc/io.o
>  cflatobjs += lib/powerpc/hcall.o
>  cflatobjs += lib/powerpc/setup.o
>  cflatobjs += lib/powerpc/rtas.o
> +cflatobjs += lib/powerpc/dump_stack.o
>  
>  FLATLIBS = $(libcflat) $(LIBFDT_archive)
>  %.elf: CFLAGS += $(arch_CFLAGS)
> diff --git a/x86/Makefile.common b/x86/Makefile.common
> index 3a14fea..d7c7eab 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/dump_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.7.0.rc3.207.g0ac5344

Thanks,
drew

  reply	other threads:[~2016-03-03  9:17 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-01 21:27 [kvm-unit-tests 0/5] Debugging aids Peter Feiner
2016-03-01 21:27 ` [kvm-unit-tests 1/5] lib: print failing assert cond Peter Feiner
2016-03-02 15:04   ` Andrew Jones
2016-03-01 21:27 ` [kvm-unit-tests 2/5] lib: backtrace printing Peter Feiner
2016-03-01 22:58   ` Peter Feiner
2016-03-01 23:07     ` Peter Feiner
2016-03-01 21:27 ` [kvm-unit-tests 3/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-01 21:27 ` [kvm-unit-tests 4/5] lib: dump stack on abort() Peter Feiner
2016-03-01 21:29   ` Peter Feiner
2016-03-01 21:27 ` [kvm-unit-tests 5/5] scripts: pretty print stack traces Peter Feiner
2016-03-01 21:34   ` Paolo Bonzini
2016-03-03  9:35     ` Andrew Jones
2016-03-03 12:57       ` Paolo Bonzini
2016-03-03 13:38         ` Andrew Jones
2016-03-03  1:09 ` [kvm-unit-tests v2 0/8] Debugging aids Peter Feiner
2016-03-03  1:09   ` [kvm-unit-tests v2 1/8] x86: emulator: asm fixes Peter Feiner
2016-03-03  1:09   ` [kvm-unit-tests v2 2/8] x86: emulator: disable test_lldt Peter Feiner
2016-03-03  1:09   ` [kvm-unit-tests v2 3/8] x86: realmode: fix test_sgdt_sidt overflow Peter Feiner
2016-03-03  1:09   ` [kvm-unit-tests v2 4/8] x86: eventinj: make test work with -O0 Peter Feiner
2016-03-03 12:53     ` Paolo Bonzini
2016-03-03  1:09   ` [kvm-unit-tests v2 5/8] lib: backtrace printing Peter Feiner
2016-03-03  9:17     ` Andrew Jones [this message]
2016-03-03 17:01       ` Peter Feiner
2016-03-03 17:56         ` Andrew Jones
2016-03-03  1:09   ` [kvm-unit-tests v2 6/8] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-03  1:09   ` [kvm-unit-tests v2 7/8] lib: dump stack on abort() Peter Feiner
2016-03-03  9:19     ` Andrew Jones
2016-03-03  1:09   ` [kvm-unit-tests v2 8/8] scripts: pretty print stack traces Peter Feiner
2016-03-03  9:54     ` Andrew Jones
2016-03-03 12:58   ` [kvm-unit-tests v2 0/8] Debugging aids Paolo Bonzini
2016-03-03 20:48 ` [kvm-unit-tests v3 0/4] " Peter Feiner
2016-03-03 20:48   ` [kvm-unit-tests v3 1/4] lib: backtrace printing Peter Feiner
2016-03-04 10:15     ` Andrew Jones
2016-03-03 20:48   ` [kvm-unit-tests v3 2/4] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-03 20:48   ` [kvm-unit-tests v3 3/4] lib: dump stack on failed assert() Peter Feiner
2016-03-04 10:25     ` Andrew Jones
2016-03-03 20:48   ` [kvm-unit-tests v3 4/4] scripts: pretty print stack traces Peter Feiner
2016-03-04 10:24     ` Andrew Jones
2016-03-04 16:55       ` Peter Feiner
2016-03-04 18:43         ` Andrew Jones
2016-03-04 19:33 ` [PATCH kvm-unit-tests v4 0/6] Debugging aids Peter Feiner
2016-03-04 19:33   ` [PATCH kvm-unit-tests v4 1/5] lib: backtrace printing Peter Feiner
2016-03-04 19:33   ` [PATCH kvm-unit-tests v4 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-04 19:33   ` [PATCH kvm-unit-tests v4 3/5] lib: dump stack on failed assert() Peter Feiner
2016-03-04 19:34   ` [PATCH kvm-unit-tests v4 4/5] scripts: pretty print stack traces Peter Feiner
2016-03-04 19:34   ` [PATCH kvm-unit-tests v4 5/5] scripts: automatically pretty print stacks Peter Feiner
2016-03-05 11:29     ` Andrew Jones
2016-03-07 17:48       ` Peter Feiner
2016-03-04 19:37   ` [PATCH kvm-unit-tests v4 0/6] Debugging aids Peter Feiner
2016-03-07 17:46 ` [PATCH kvm-unit-tests v5 0/5] " Peter Feiner
2016-03-07 17:46   ` [PATCH kvm-unit-tests v5 1/5] lib: backtrace printing Peter Feiner
2016-03-08  4:24     ` Andrew Jones
2016-03-11  0:31       ` Peter Feiner
2016-03-07 17:46   ` [PATCH kvm-unit-tests v5 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-07 17:46   ` [PATCH kvm-unit-tests v5 3/5] lib: dump stack on failed assert() Peter Feiner
2016-03-07 17:46   ` [PATCH kvm-unit-tests v5 4/5] scripts: pretty print stack traces Peter Feiner
2016-03-07 17:46   ` [PATCH kvm-unit-tests v5 5/5] scripts: automatically pretty print stacks Peter Feiner
2016-03-08  4:31   ` [PATCH kvm-unit-tests v5 0/5] Debugging aids Andrew Jones
2016-03-11  0:47 ` [PATCH kvm-unit-tests v6 " Peter Feiner
2016-03-11  0:47   ` [PATCH kvm-unit-tests v6 1/5] lib: backtrace printing Peter Feiner
2016-03-11  0:47   ` [PATCH kvm-unit-tests v6 2/5] x86: lib: debug dump on unhandled exceptions Peter Feiner
2016-03-11  0:47   ` [PATCH kvm-unit-tests v6 3/5] lib: dump stack on failed assert() Peter Feiner
2016-03-11  0:47   ` [PATCH kvm-unit-tests v6 4/5] scripts: pretty print stack traces Peter Feiner
2016-03-11  0:47   ` [PATCH kvm-unit-tests v6 5/5] scripts: automatically pretty print stacks Peter Feiner
2016-03-11  2:41   ` [PATCH kvm-unit-tests v6 0/5] Debugging aids Andrew Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160303091746.GA1515@localhost.redhat.com \
    --to=drjones@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=pfeiner@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.