From patchwork Thu Mar 3 01:09:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Feiner X-Patchwork-Id: 8487061 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 75BDEC0553 for ; Thu, 3 Mar 2016 01:10:05 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6F24D2021F for ; Thu, 3 Mar 2016 01:10:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 91AA62034A for ; Thu, 3 Mar 2016 01:10:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755170AbcCCBJ6 (ORCPT ); Wed, 2 Mar 2016 20:09:58 -0500 Received: from mail-pf0-f171.google.com ([209.85.192.171]:36599 "EHLO mail-pf0-f171.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755023AbcCCBJ4 (ORCPT ); Wed, 2 Mar 2016 20:09:56 -0500 Received: by mail-pf0-f171.google.com with SMTP id 63so4167603pfe.3 for ; Wed, 02 Mar 2016 17:09:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CF1gm1reE6xnl0VkVDWe6jnQh6LaFQ5VmRmJ3HLwd/0=; b=QRC37vBEEb2WXj26A2y0EQy74wP0SGQhWgJcPVNG6aqWN6qlS2jxqEPcBLIk57O9AI m910Te1j5uXFQ4ovFakPejhoEKTeF13HS6C/u5D+C/XKXnp/3i7gPJC1y8qUtDGRPNJ6 NlBMuJEXtOyArx8SGxYFli/upgkOgRC9n6MCkBAroCrSanzQzufjxR+IldV36b2Fyon7 OmgCyxRUaCQw9FB05roXje/TVtZ91zpWxV5w7DWgxVolWZ3r3ebQr2Mo5JtmgnykkTnV a7+rTEiP4iSd/ihYjsC70DCJ5+iX0Sl/98hF05C/fW8IifgAduogVpCU5spaVA3I5Eod vOlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CF1gm1reE6xnl0VkVDWe6jnQh6LaFQ5VmRmJ3HLwd/0=; b=ThWrQNF0z9hKfrKOZKMPyOlkS8XVALsXh+cxW90wbunmJuhp7UYDzfHMDwQhqQIlS+ T4r21L9R4qSKhWz7E3mJZqJclf9queS6IKUOpr3+MYZuPovZhlwzbR+bAFEsucP8f0l+ vjw3C77VU5y6Mzj9Slpjyo6V8/pDj4XGPE1DYc4DMJTwu5YqlE2/J7+qgx/uEkRg50R7 mqk5ibsvNOs04sJXRO/x7ALygf89MoczdRhkv7plfEeDdmBGt+yZujtcDU4ul2HUwLVQ UFSoAjaN+M48Y1rNH8+mYdXmbXMw/iqMFHJuCHeX3xJVPatGE901OMFhpCx414KZUWii 1Kqg== X-Gm-Message-State: AD7BkJJyD9qxu0d4RQuh/eQpeP+at2PdwwUXABT49pNjYx3GSBb45S8B41w0UvP4aiuCIog3 X-Received: by 10.98.66.157 with SMTP id h29mr43250646pfd.91.1456967395468; Wed, 02 Mar 2016 17:09:55 -0800 (PST) Received: from localhost ([2620:0:1009:3:10b2:1b3a:febc:1b15]) by smtp.gmail.com with ESMTPSA id z67sm55669173pfa.71.2016.03.02.17.09.53 (version=TLS1_2 cipher=AES128-SHA bits=128/128); Wed, 02 Mar 2016 17:09:54 -0800 (PST) From: Peter Feiner To: kvm@vger.kernel.org, drjones@redhat.com, pbonzini@redhat.com Cc: pfeiner@google.com Subject: [kvm-unit-tests v2 5/8] lib: backtrace printing Date: Wed, 2 Mar 2016 17:09:35 -0800 Message-Id: <1456967378-6367-6-git-send-email-pfeiner@google.com> X-Mailer: git-send-email 2.7.0.rc3.207.g0ac5344 In-Reply-To: <1456967378-6367-1-git-send-email-pfeiner@google.com> References: <1456867658-10937-1-git-send-email-pfeiner@google.com> <1456967378-6367-1-git-send-email-pfeiner@google.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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); + #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); + } + 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); +} + +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)