From 0ed42ff033723f6fcb926577b314d335458532bb Mon Sep 17 00:00:00 2001 From: Kris Van Hees Date: Thu, 27 Feb 2014 09:40:13 -0500 Subject: [PATCH] dtrace: avoid unreliable entries in stack() output The original implementation of the stacktrace walker for DTrace often reported unreliable (i.e. non-callframe) entries in the stack() output. This was most often seen as a result of datastructures allocated on the stack in functions. This new implementation isn't plagued by that issue anymore. It uses knowledge of the basepointer (bp) to link callframes. Orabug: 18323450 Signed-off-by: Kris Van Hees Acked-by: Jerry Snitselaar --- kernel/dtrace/dtrace_os.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/kernel/dtrace/dtrace_os.c b/kernel/dtrace/dtrace_os.c index 18f03082c5b7..eac5ec0545b5 100644 --- a/kernel/dtrace/dtrace_os.c +++ b/kernel/dtrace/dtrace_os.c @@ -457,7 +457,7 @@ static unsigned long dtrace_stacktrace_walk_stack( static const struct stacktrace_ops dtrace_stacktrace_ops = { .stack = dtrace_stacktrace_stack, .address = dtrace_stacktrace_address, - .walk_stack = print_context_stack + .walk_stack = print_context_stack_bp }; static const struct stacktrace_ops dtrace_fpstacktrace_ops = { @@ -468,7 +468,28 @@ static const struct stacktrace_ops dtrace_fpstacktrace_ops = { void dtrace_stacktrace(stacktrace_state_t *st) { - dump_trace(NULL, NULL, NULL, 0, + unsigned long bp; + unsigned long stack; + + bp = stack_frame(current, NULL); + + /* + * Generate a stacktrace in the buffer embedded in st, identical to the + * stacktrace that would be printed to the console if dump_stack() were + * called here. + * + * dump_stack() + * -> show_trace(NULL, NULL, &stack, bp) + * where unsigned long bp = stack_frame(current, NULL); + * unsigned long stack; + * -> show_trace_log_lvl(NULL, NULL, &stack, bp, "") + * where unsigned long bp = stack_frame(current, NULL); + * unsigned long stack; + * -> dump_trace(NULL, NULL, &stack, bp, &print_trace_ops, ""); + * where unsigned long bp = stack_frame(current, NULL); + * unsigned long stack; + */ + dump_trace(NULL, NULL, &stack, bp, st->fps != NULL ? &dtrace_fpstacktrace_ops : &dtrace_stacktrace_ops, st); } -- 2.50.1