]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: avoid unreliable entries in stack() output
authorKris Van Hees <kris.van.hees@oracle.com>
Thu, 27 Feb 2014 14:40:13 +0000 (09:40 -0500)
committerNick Alcock <nick.alcock@oracle.com>
Tue, 21 Jul 2015 14:29:32 +0000 (15:29 +0100)
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 <kris.van.hees@oracle.com>
Acked-by: Jerry Snitselaar <jerry.snitselaar@oracle.com>
kernel/dtrace/dtrace_os.c

index 18f03082c5b78f5ecf0b8c256708a267e4c39c19..eac5ec0545b5541d79770168f722a4fc8220d850 100644 (file)
@@ -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);
 }