The following commit has been merged in the linux branch: commit 9135c3cc5acf344eb28735681d8bebdb98a2c216 Author: Steven Rostedt srostedt@redhat.com Date: Tue Sep 15 08:20:15 2009 -0700
powerpc/ftrace: show real return addresses in modules
When the function graph tracer is enabled, it replaces the return address with a hook back to the tracer. This makes back traces see the hook instead of the actual return address.
The current code also shows the real address by checking if the return address jumps to the return_to_handler. If it is, is also prints out the saved real return address.
On powerpc64, some modules may return to mod_return_to_handler, which is not checked. This patch will also show the real address if a return is to mod_return_to_handler as well.
Signed-off-by: Steven Rostedt rostedt@goodmis.org
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 1168c5f..2ec1eae 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1016,9 +1016,13 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) #ifdef CONFIG_FUNCTION_GRAPH_TRACER int curr_frame = current->curr_ret_stack; extern void return_to_handler(void); - unsigned long addr = (unsigned long)return_to_handler; + unsigned long rth = (unsigned long)return_to_handler; + unsigned long mrth = -1; #ifdef CONFIG_PPC64 - addr = *(unsigned long*)addr; + extern void mod_return_to_handler(void); + rth = *(unsigned long *)rth; + mrth = (unsigned long)mod_return_to_handler; + mrth = *(unsigned long *)mrth; #endif #endif
@@ -1044,7 +1048,7 @@ void show_stack(struct task_struct *tsk, unsigned long *stack) if (!firstframe || ip != lr) { printk("["REG"] ["REG"] %pS", sp, ip, (void *)ip); #ifdef CONFIG_FUNCTION_GRAPH_TRACER - if (ip == addr && curr_frame >= 0) { + if ((ip == rth || ip == mrth) && curr_frame >= 0) { printk(" (%pS)", (void *)current->ret_stack[curr_frame].ret); curr_frame--;