* [PATCH] sh: Check for return_to_handler when unwinding the stack
@ 2009-10-24 18:56 Matt Fleming
2009-10-26 2:02 ` Paul Mundt
0 siblings, 1 reply; 2+ messages in thread
From: Matt Fleming @ 2009-10-24 18:56 UTC (permalink / raw)
To: linux-sh
When CONFIG_FUNCTION_GRAPH_TRACER is enabled the function graph tracer
may patch return addresses on the stack with the address of
return_to_handler(). This really confuses the DWARF unwinder because it
will try find the caller of return_to_handler(), not the caller of the
real return address.
So teach the DWARF unwinder how to find the real return address whenever
it encounters return_to_handler().
This patch does not cope very well when multiple return addresses on the
stack have been patched. To make it work properly it would require state
to track how many return_to_handler()'s have been seen so that we'd know
where to look in current->curr_ret_stack[]. So for now, instead of
trying to handle this, just moan if more than one return address on the
stack has been patched.
Signed-off-by: Matt Fleming <matt@console-pimps.org>
---
arch/sh/kernel/dwarf.c | 22 ++++++++++++++++++++++
1 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/sh/kernel/dwarf.c b/arch/sh/kernel/dwarf.c
index 4d8c7bd..6c9d0c1 100644
--- a/arch/sh/kernel/dwarf.c
+++ b/arch/sh/kernel/dwarf.c
@@ -21,6 +21,7 @@
#include <linux/mempool.h>
#include <linux/mm.h>
#include <linux/elf.h>
+#include <linux/ftrace.h>
#include <asm/dwarf.h>
#include <asm/unwinder.h>
#include <asm/sections.h>
@@ -569,6 +570,27 @@ struct dwarf_frame * dwarf_unwind_stack(unsigned long pc,
if (!pc && !prev)
pc = (unsigned long)current_text_addr();
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+ /*
+ * If our stack has been patched by the function graph tracer
+ * then we might see the address of return_to_handler() where we
+ * expected to find the real return address.
+ */
+ if (pc = (unsigned long)&return_to_handler) {
+ int index = current->curr_ret_stack;
+
+ /*
+ * We currently have no way of tracking how many
+ * return_to_handler()'s we've seen. If there is more
+ * than one patched return address on our stack,
+ * complain loudly.
+ */
+ WARN_ON(index > 0);
+
+ pc = current->ret_stack[index].ret;
+ }
+#endif
+
frame = mempool_alloc(dwarf_frame_pool, GFP_ATOMIC);
if (!frame) {
printk(KERN_ERR "Unable to allocate a dwarf frame\n");
--
1.6.4.rc0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] sh: Check for return_to_handler when unwinding the stack
2009-10-24 18:56 [PATCH] sh: Check for return_to_handler when unwinding the stack Matt Fleming
@ 2009-10-26 2:02 ` Paul Mundt
0 siblings, 0 replies; 2+ messages in thread
From: Paul Mundt @ 2009-10-26 2:02 UTC (permalink / raw)
To: linux-sh
On Sat, Oct 24, 2009 at 07:56:57PM +0100, Matt Fleming wrote:
> When CONFIG_FUNCTION_GRAPH_TRACER is enabled the function graph tracer
> may patch return addresses on the stack with the address of
> return_to_handler(). This really confuses the DWARF unwinder because it
> will try find the caller of return_to_handler(), not the caller of the
> real return address.
>
> So teach the DWARF unwinder how to find the real return address whenever
> it encounters return_to_handler().
>
> This patch does not cope very well when multiple return addresses on the
> stack have been patched. To make it work properly it would require state
> to track how many return_to_handler()'s have been seen so that we'd know
> where to look in current->curr_ret_stack[]. So for now, instead of
> trying to handle this, just moan if more than one return address on the
> stack has been patched.
>
> Signed-off-by: Matt Fleming <matt@console-pimps.org>
Applied, thanks.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-10-26 2:02 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-24 18:56 [PATCH] sh: Check for return_to_handler when unwinding the stack Matt Fleming
2009-10-26 2:02 ` Paul Mundt
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.