From 7e46daf103bea7dcc92e255629e8412e8f608215 Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Thu, 21 Jul 2011 16:51:48 +0200 Subject: [PATCH] Remove STP_USE_FRAME_POINTER support and merge i386/x86_64 into stack-x86.c The only real difference between stack-i386.c and stack-x86_64 was that the former supported a buggy frame pointer based unwind. Which we never used and for which the kernel has a better fallback (dump_trace). --- runtime/runtime.h | 7 -- runtime/stack-arm.c | 4 +- runtime/stack-i386.c | 124 ------------------------ runtime/{stack-x86_64.c => stack-x86.c} | 12 +-- runtime/stack.c | 15 ++- runtime/unwind.c | 8 -- runtime/unwind/unwind.h | 3 - runtime/unwind/x86_64.h | 9 -- 8 files changed, 16 insertions(+), 166 deletions(-) delete mode 100644 runtime/stack-i386.c rename runtime/{stack-x86_64.c => stack-x86.c} (91%) diff --git a/runtime/runtime.h b/runtime/runtime.h index 8303b3168..a9137c8b5 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -117,13 +117,6 @@ static struct #endif #endif -#ifdef CONFIG_FRAME_POINTER -/* Just because frame pointers are available does not mean we can trust them. */ -#ifndef STP_USE_DWARF_UNWINDER -#define STP_USE_FRAME_POINTER -#endif -#endif - #include "alloc.c" #include "print.c" #include "string.c" diff --git a/runtime/stack-arm.c b/runtime/stack-arm.c index ab721dfe5..a5285f931 100644 --- a/runtime/stack-arm.c +++ b/runtime/stack-arm.c @@ -36,7 +36,7 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, struct unwind_context *uwcontext, struct uretprobe_instance *ri, int uregs_valid) { -#ifdef STP_USE_FRAME_POINTER +#ifdef CONFIG_FRAME_POINTER int pc_offset = find_str_pc_offset(); unsigned long *fp = (unsigned long *)regs->ARM_fp; unsigned long *next_fp, *pc; @@ -65,5 +65,5 @@ static void __stp_stack_print (struct pt_regs *regs, int verbose, int levels, fp = next_fp; } -#endif /* STP_USE_FRAME_POINTER */ +#endif /* CONFIG_FRAME_POINTER */ } diff --git a/runtime/stack-i386.c b/runtime/stack-i386.c deleted file mode 100644 index 569ad107b..000000000 --- a/runtime/stack-i386.c +++ /dev/null @@ -1,124 +0,0 @@ -/* -*- linux-c -*- - * i386 stack tracing functions - * Copyright (C) 2005-2010 Red Hat Inc. - * - * This file is part of systemtap, and is free software. You can - * redistribute it and/or modify it under the terms of the GNU General - * Public License (GPL); either version 2, or (at your option) any - * later version. - */ - -#ifdef STAPCONF_LINUX_UACCESS_H -#include -#else -#include -#endif -#include -#define intptr_t long -#define uintptr_t unsigned long - -static int _stp_valid_pc_addr(unsigned long addr, struct task_struct *tsk) -{ - /* Just a simple check of whether the the address can be accessed - as a user space address. Zero is always bad. */ - int ok; - mm_segment_t oldfs = get_fs(); - set_fs(USER_DS); - ok = access_ok(VERIFY_READ, (long *) (intptr_t) addr, sizeof(long)); - set_fs(oldfs); - return addr != 0L && tsk != NULL ? ok : ! ok; -} - -static int _stp_valid_stack_ptr(unsigned long context, unsigned long p) -{ - return p > context && p < context + THREAD_SIZE - 3; -} - -/* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ -#if !defined(STAPCONF_KERNEL_STACKTRACE) -static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) -{ - unsigned long addr; - while (levels && stack & (THREAD_SIZE-1)) { - if (unlikely(_stp_read_address(addr, (unsigned long *)stack, - KERNEL_DS)) - || ! _stp_valid_pc_addr(addr, NULL)) { - /* cannot access stack. give up. */ - return; - } - _stp_print_addr(addr, verbose | _STP_SYM_INEXACT, NULL); - levels--; - stack++; - } -} -#endif - -static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels, - struct task_struct *tsk, - struct unwind_context *uwcontext, - struct uretprobe_instance *ri, int uregs_valid) -{ - unsigned long context = (unsigned long)®_SP(regs) & ~(THREAD_SIZE - 1); - -#ifdef STP_USE_FRAME_POINTER - unsigned long addr; - unsigned long next_fp, fp = REG_FP(regs); - - while (levels && _stp_valid_stack_ptr(context, (unsigned long)fp)) { - if (unlikely(_stp_read_address(addr, (unsigned long *)(fp + 4), KERNEL_DS))) { - /* cannot access stack. give up. */ - return; - } - _stp_print_addr(addr, verbose | _STP_SYM_INEXACT, NULL); - if (unlikely(_stp_read_address(next_fp, (unsigned long *)fp, KERNEL_DS))) { - /* cannot access stack. give up. */ - return; - } - levels--; - - /* frame pointers move upwards */ - if (next_fp <= fp) - break; - fp = next_fp; - } -#else -#ifdef STP_USE_DWARF_UNWINDER - struct unwind_frame_info *info = &uwcontext->info; - int sanitize = tsk && ! uregs_valid; - arch_unw_init_frame_info(info, regs, sanitize); - - while (levels) { - int ret = unwind(uwcontext, tsk); -#ifdef STAPCONF_UPROBE_GET_PC - unsigned long maybe_pc = 0; - if (ri) { - maybe_pc = uprobe_get_pc(ri, UNW_PC(info), - UNW_SP(info)); - if (!maybe_pc) - printk("SYSTEMTAP ERROR: uprobe_get_return returned 0\n"); - else - UNW_PC(info) = maybe_pc; - } -#endif - dbug_unwind(1, "ret=%d PC=%lx SP=%lx\n", ret, UNW_PC(info), UNW_SP(info)); - if (ret == 0 && _stp_valid_pc_addr(UNW_PC(info), tsk)) { - _stp_print_addr(UNW_PC(info), verbose, tsk); - levels--; - if (UNW_PC(info) != _stp_kretprobe_trampoline) - continue; - } - /* If an error happened or we hit a kretprobe trampoline, - * and the current pc frame address is still valid kernel - * address use fallback backtrace, unless user task backtrace. - * FIXME: is there a way to unwind across kretprobe - * trampolines? PR9999. */ - if ((ret < 0 || UNW_PC(info) == _stp_kretprobe_trampoline) - && ! tsk) - _stp_stack_print_fallback(UNW_SP(info), verbose, levels); - return; - } -#else /* ! STP_USE_DWARF_UNWINDER */ - _stp_stack_print_fallback((unsigned long)®_SP(regs), verbose, levels); -#endif /* STP_USE_FRAME_POINTER */ -#endif -} diff --git a/runtime/stack-x86_64.c b/runtime/stack-x86.c similarity index 91% rename from runtime/stack-x86_64.c rename to runtime/stack-x86.c index 19bbeb47d..6533c1401 100644 --- a/runtime/stack-x86_64.c +++ b/runtime/stack-x86.c @@ -1,6 +1,6 @@ /* -*- linux-c -*- - * x86_64 stack tracing functions - * Copyright (C) 2005-2010 Red Hat Inc. + * x86 stack tracing functions + * Copyright (C) 2005-2011 Red Hat Inc. * * This file is part of systemtap, and is free software. You can * redistribute it and/or modify it under the terms of the GNU General @@ -29,13 +29,12 @@ static int _stp_valid_pc_addr(unsigned long addr, struct task_struct *tsk) return addr != 0L && tsk != NULL ? ok : ! ok; } - /* DWARF unwinder failed. Just dump intereting addresses on kernel stack. */ #if !defined(STAPCONF_KERNEL_STACKTRACE) static void _stp_stack_print_fallback(unsigned long stack, int verbose, int levels) { unsigned long addr; - while (levels && stack & (THREAD_SIZE - 1)) { + while (levels && stack & (THREAD_SIZE-1)) { if (unlikely(_stp_read_address(addr, (unsigned long *)stack, KERNEL_DS)) || ! _stp_valid_pc_addr(addr, NULL)) { @@ -55,7 +54,6 @@ static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels, struct uretprobe_instance *ri, int uregs_valid) { #ifdef STP_USE_DWARF_UNWINDER - int start_levels = levels; struct unwind_frame_info *info = &uwcontext->info; int sanitize = tsk && ! uregs_valid; arch_unw_init_frame_info(info, regs, sanitize); @@ -90,9 +88,5 @@ static void __stp_stack_print(struct pt_regs *regs, int verbose, int levels, _stp_stack_print_fallback(UNW_SP(info), verbose, levels); return; } -#else /* ! STP_USE_DWARF_UNWINDER */ - _stp_stack_print_fallback(REG_SP(regs), verbose, levels); #endif } - - diff --git a/runtime/stack.c b/runtime/stack.c index b2d5d1da8..5f3228698 100644 --- a/runtime/stack.c +++ b/runtime/stack.c @@ -23,7 +23,16 @@ #include "sym.c" #include "regs.h" + +/* DWARF unwinder only tested so far on i386 and x86_64. + It would be nice to also make this depend on STP_NEED_UNWIND_DATA. + But that is defined too late when [u]context-unwind.stp is used. + XXX turn define in tapsets into prama:unwind? */ +#ifdef STP_USE_DWARF_UNWINDER #include "unwind.c" +#else +struct unwind_context { }; +#endif #define MAXBACKTRACE 20 @@ -48,12 +57,10 @@ struct uretprobe_instance; static void _stp_stack_print_fallback(unsigned long, int, int); -#if defined (__x86_64__) -#include "stack-x86_64.c" +#if (defined(__i386__) || defined(__x86_64__)) +#include "stack-x86.c" #elif defined (__ia64__) #include "stack-ia64.c" -#elif defined (__i386__) -#include "stack-i386.c" #elif defined (__powerpc__) #include "stack-ppc.c" #elif defined (__arm__) diff --git a/runtime/unwind.c b/runtime/unwind.c index a60c4b7af..e31c76e6a 100644 --- a/runtime/unwind.c +++ b/runtime/unwind.c @@ -15,8 +15,6 @@ #include "unwind/unwind.h" -#ifdef STP_USE_DWARF_UNWINDER - struct unwind_context { struct unwind_frame_info info; struct unwind_state state; @@ -1374,9 +1372,3 @@ static int unwind(struct unwind_context *context, return res; } - -#else - -struct unwind_context { }; - -#endif /* STP_USE_DWARF_UNWINDER */ diff --git a/runtime/unwind/unwind.h b/runtime/unwind/unwind.h index 55a82a5a0..a8c1998e5 100644 --- a/runtime/unwind/unwind.h +++ b/runtime/unwind/unwind.h @@ -13,8 +13,6 @@ #ifndef _STP_UNWIND_H_ #define _STP_UNWIND_H_ -#ifdef STP_USE_DWARF_UNWINDER - #if defined (__x86_64__) #include "x86_64.h" #elif defined (__i386__) @@ -284,5 +282,4 @@ struct unwind_state { static const struct cfa badCFA = { ARRAY_SIZE(reg_info), 1 }; -#endif /* STP_USE_DWARF_UNWINDER */ #endif /*_STP_UNWIND_H_*/ diff --git a/runtime/unwind/x86_64.h b/runtime/unwind/x86_64.h index c8070d0a1..24c51d216 100644 --- a/runtime/unwind/x86_64.h +++ b/runtime/unwind/x86_64.h @@ -40,15 +40,6 @@ struct unwind_frame_info #define UNW_SP(frame) (frame)->regs.rsp #endif /* STAPCONF_X86_UNIREGS */ -#if 0 /* STP_USE_FRAME_POINTER */ -/* Frame pointers not implemented in x86_64 currently */ -#define UNW_FP(frame) (frame)->regs.rbp -#define FRAME_RETADDR_OFFSET 8 -#define FRAME_LINK_OFFSET 0 -#define STACK_BOTTOM(tsk) (((tsk)->thread.rsp0 - 1) & ~(THREAD_SIZE - 1)) -#define STACK_TOP(tsk) ((tsk)->thread.rsp0) -#endif - /* Might need to account for the special exception and interrupt handling stacks here, since normally EXCEPTION_STACK_ORDER < THREAD_ORDER < IRQSTACK_ORDER, -- 2.43.5