Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1465318
| From | Josh Poimboeuf <jpoimboe@redhat.com> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | [PATCH v4 27/57] ftrace: add ftrace_graph_ret_addr() stack unwinding helpers |
| Date | 2016-08-18 15:30 +0200 |
| Message-ID | <s7vyp-kW-23@gated-at.bofh.it> (permalink) |
| References | <s7vf3-dJ-11@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
When function graph tracing is enabled for a function, ftrace modifies
the stack by replacing the original return address with the address of a
hook function (return_to_handler).
Stack unwinders need a way to get the original return address. Add an
arch-independent helper function for that named ftrace_graph_ret_addr().
This adds two variations of the function: one depends on
HAVE_FUNCTION_GRAPH_RET_ADDR_PTR, and the other relies on an index state
variable.
The former is recommended because, in some cases, the latter can cause
problems when the unwinder skips stack frames. It can get out of sync
with the ret_stack index and wrong addresses can be reported for the
stack trace.
Once all arches have been ported to use
HAVE_FUNCTION_GRAPH_RET_ADDR_PTR, we can get rid of the distinction.
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
include/linux/ftrace.h | 10 +++++++
kernel/trace/trace_functions_graph.c | 58 ++++++++++++++++++++++++++++++++++++
2 files changed, 68 insertions(+)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 483e02a..6f93ac4 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -814,6 +814,9 @@ extern int
ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
unsigned long frame_pointer, unsigned long *retp);
+unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
+ unsigned long ret, unsigned long *retp);
+
/*
* Sometimes we don't want to trace a function with the function
* graph tracer but we want them to keep traced by the usual function
@@ -875,6 +878,13 @@ static inline int task_curr_ret_stack(struct task_struct *tsk)
return -1;
}
+static inline unsigned long
+ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret,
+ unsigned long *retp)
+{
+ return ret;
+}
+
static inline void pause_graph_tracing(void) { }
static inline void unpause_graph_tracing(void) { }
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index f7212ec..0cbe38a 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -284,6 +284,64 @@ unsigned long ftrace_return_to_handler(unsigned long frame_pointer)
return ret;
}
+/**
+ * ftrace_graph_ret_addr - convert a potentially modified stack return address
+ * to its original value
+ *
+ * This function can be called by stack unwinding code to convert a found stack
+ * return address ('ret') to its original value, in case the function graph
+ * tracer has modified it to be 'return_to_handler'. If the address hasn't
+ * been modified, the unchanged value of 'ret' is returned.
+ *
+ * 'idx' is a state variable which should be initialized by the caller to zero
+ * before the first call.
+ *
+ * 'retp' is a pointer to the return address on the stack. It's ignored if
+ * the arch doesn't have HAVE_FUNCTION_GRAPH_RET_ADDR_PTR defined.
+ */
+#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
+unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
+ unsigned long ret, unsigned long *retp)
+{
+ int index = task->curr_ret_stack;
+ int i;
+
+ if (ret != (unsigned long)return_to_handler)
+ return ret;
+
+ if (index < -1)
+ index += FTRACE_NOTRACE_DEPTH;
+
+ if (index < 0)
+ return ret;
+
+ for (i = 0; i <= index; i++)
+ if (task->ret_stack[i].retp == retp)
+ return task->ret_stack[i].ret;
+
+ return ret;
+}
+#else /* !HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */
+unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
+ unsigned long ret, unsigned long *retp)
+{
+ int task_idx;
+
+ if (ret != (unsigned long)return_to_handler)
+ return ret;
+
+ task_idx = task->curr_ret_stack;
+
+ if (!task->ret_stack || task_idx < *idx)
+ return ret;
+
+ task_idx -= *idx;
+ (*idx)++;
+
+ return task->ret_stack[task_idx].ret;
+}
+#endif /* HAVE_FUNCTION_GRAPH_RET_ADDR_PTR */
+
int __trace_graph_entry(struct trace_array *tr,
struct ftrace_graph_ent *trace,
unsigned long flags,
--
2.7.4
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
[PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:20 +0200
[PATCH v4 52/57] x86/dumpstack: warn on stack recursion Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:20 +0200
[PATCH v4 46/57] x86/dumpstack: fix duplicate RIP address display in __show_regs() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:20 +0200
[PATCH v4 28/57] x86/dumpstack/ftrace: convert dump_trace() callbacks to use ftrace_graph_ret_addr() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 29/57] ftrace/x86: implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 26/57] ftrace: add return address pointer to ftrace_ret_stack Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 34/57] x86/dumpstack: add get_stack_info() interface Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 23/57] proc: fix return address printk conversion specifer in /proc/<pid>/stack Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 36/57] x86/unwind: add new unwind interface and implementations Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 21/57] perf/x86: check perf_callchain_store() error Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 33/57] x86/dumpstack: simplify in_exception_stack() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 27/57] ftrace: add ftrace_graph_ret_addr() stack unwinding helpers Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 19/57] x86/entry/head/32: use local labels Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 25/57] ftrace: only allocate the ret_stack 'fp' field when needed Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 16/57] x86/entry/32: fix the end of the stack for newly forked tasks Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 40/57] x86/dumpstack: convert show_trace_log_lvl() to use the new unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 39/57] oprofile/x86: convert x86_backtrace() to use the new unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 35/57] x86/dumpstack: add recursion checking for all stacks Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 22/57] oprofile/x86: add regs->ip to oprofile trace Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 38/57] x86/stacktrace: convert save_stack_trace_*() to use the new unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 24/57] ftrace: remove CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST from config Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 45/57] x86/dumpstack: print any pt_regs found on the stack Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 30/57] x86/dumpstack/ftrace: mark function graph handler function as unreliable Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 47/57] x86/dumpstack: print orig_ax in __show_regs() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 44/57] x86/dumpstack: print stack identifier on its own line Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Frederic Weisbecker <fweisbec@gmail.com> - 2016-08-18 15:30 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Ingo Molnar <mingo@kernel.org> - 2016-08-18 15:40 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Steven Rostedt <rostedt@goodmis.org> - 2016-08-18 16:40 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 16:40 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Steven Rostedt <rostedt@goodmis.org> - 2016-08-18 16:50 +0200
Re: [PATCH v4 00/57] x86/dumpstack: rewrite x86 stack dump code Ingo Molnar <mingo@kernel.org> - 2016-08-19 07:10 +0200
[PATCH v4 41/57] x86/dumpstack: remove dump_trace() and related callbacks Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 31/57] x86/dumpstack/ftrace: don't print unreliable addresses in print_context_stack_bp() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 42/57] x86/entry/unwind: create stack frames for saved interrupt registers Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 20/57] x86/entry/32: rename 'error_code' to 'common_exception' Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 37/57] perf/x86: convert perf_callchain_kernel() to use the new unwinder Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 32/57] x86/dumpstack: allow preemption in show_stack_log_lvl() and dump_trace() Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:30 +0200
[PATCH v4 12/57] x86: move _stext marker to before head code Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:40 +0200
[PATCH v4 09/57] x86/dumpstack: fix x86_32 kernel_stack_pointer() previous stack access Josh Poimboeuf <jpoimboe@redhat.com> - 2016-08-18 15:40 +0200
csiph-web