Commit af5329cdf51cdd208a323e521faa46800a16d2ec

Authored by Linus Torvalds

Merge branch 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  generic-ipi: powerpc/generic-ipi tree build failure
  stacktrace: fix build failure on sparc64
  stacktrace: export save_stack_trace[_tsk]
  stacktrace: fix modular build, export print_stack_trace and save_stack_trace
  backtrace: replace timer with tasklet + completions
  stacktrace: add saved stack traces to backtrace self-test
  stacktrace: print_stack_trace() cleanup
  debugging: make stacktrace independent from DEBUG_KERNEL
  stacktrace: don't crash on invalid stack trace structs

Showing 11 changed files Side-by-side Diff

arch/arm/kernel/stacktrace.c
... ... @@ -92,5 +92,6 @@
92 92 {
93 93 save_stack_trace_tsk(current, trace);
94 94 }
  95 +EXPORT_SYMBOL_GPL(save_stack_trace);
95 96 #endif
arch/avr32/kernel/stacktrace.c
... ... @@ -51,4 +51,5 @@
51 51 fp = frame->fp;
52 52 }
53 53 }
  54 +EXPORT_SYMBOL_GPL(save_stack_trace);
arch/mips/kernel/stacktrace.c
... ... @@ -73,4 +73,5 @@
73 73 prepare_frametrace(regs);
74 74 save_context_stack(trace, regs);
75 75 }
  76 +EXPORT_SYMBOL_GPL(save_stack_trace);
arch/powerpc/kernel/stacktrace.c
... ... @@ -12,6 +12,7 @@
12 12  
13 13 #include <linux/sched.h>
14 14 #include <linux/stacktrace.h>
  15 +#include <linux/module.h>
15 16 #include <asm/ptrace.h>
16 17  
17 18 /*
... ... @@ -44,4 +45,5 @@
44 45 sp = newsp;
45 46 }
46 47 }
  48 +EXPORT_SYMBOL_GPL(save_stack_trace);
arch/s390/kernel/stacktrace.c
... ... @@ -81,6 +81,7 @@
81 81 S390_lowcore.thread_info,
82 82 S390_lowcore.thread_info + THREAD_SIZE, 1);
83 83 }
  84 +EXPORT_SYMBOL_GPL(save_stack_trace);
84 85  
85 86 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
86 87 {
... ... @@ -93,4 +94,5 @@
93 94 if (trace->nr_entries < trace->max_entries)
94 95 trace->entries[trace->nr_entries++] = ULONG_MAX;
95 96 }
  97 +EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
arch/sh/kernel/stacktrace.c
... ... @@ -34,4 +34,5 @@
34 34 }
35 35 }
36 36 }
  37 +EXPORT_SYMBOL_GPL(save_stack_trace);
arch/sparc64/kernel/stacktrace.c
1 1 #include <linux/sched.h>
2 2 #include <linux/stacktrace.h>
3 3 #include <linux/thread_info.h>
  4 +#include <linux/module.h>
4 5 #include <asm/ptrace.h>
5 6 #include <asm/stacktrace.h>
6 7  
... ... @@ -47,4 +48,5 @@
47 48 trace->entries[trace->nr_entries++] = pc;
48 49 } while (trace->nr_entries < trace->max_entries);
49 50 }
  51 +EXPORT_SYMBOL_GPL(save_stack_trace);
arch/x86/kernel/stacktrace.c
... ... @@ -74,6 +74,7 @@
74 74 if (trace->nr_entries < trace->max_entries)
75 75 trace->entries[trace->nr_entries++] = ULONG_MAX;
76 76 }
  77 +EXPORT_SYMBOL_GPL(save_stack_trace);
77 78  
78 79 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
79 80 {
... ... @@ -81,4 +82,5 @@
81 82 if (trace->nr_entries < trace->max_entries)
82 83 trace->entries[trace->nr_entries++] = ULONG_MAX;
83 84 }
  85 +EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
kernel/backtracetest.c
... ... @@ -10,30 +10,73 @@
10 10 * of the License.
11 11 */
12 12  
  13 +#include <linux/completion.h>
  14 +#include <linux/delay.h>
  15 +#include <linux/interrupt.h>
13 16 #include <linux/module.h>
14 17 #include <linux/sched.h>
15   -#include <linux/delay.h>
  18 +#include <linux/stacktrace.h>
16 19  
17   -static struct timer_list backtrace_timer;
  20 +static void backtrace_test_normal(void)
  21 +{
  22 + printk("Testing a backtrace from process context.\n");
  23 + printk("The following trace is a kernel self test and not a bug!\n");
18 24  
19   -static void backtrace_test_timer(unsigned long data)
  25 + dump_stack();
  26 +}
  27 +
  28 +static DECLARE_COMPLETION(backtrace_work);
  29 +
  30 +static void backtrace_test_irq_callback(unsigned long data)
20 31 {
  32 + dump_stack();
  33 + complete(&backtrace_work);
  34 +}
  35 +
  36 +static DECLARE_TASKLET(backtrace_tasklet, &backtrace_test_irq_callback, 0);
  37 +
  38 +static void backtrace_test_irq(void)
  39 +{
21 40 printk("Testing a backtrace from irq context.\n");
22 41 printk("The following trace is a kernel self test and not a bug!\n");
23   - dump_stack();
  42 +
  43 + init_completion(&backtrace_work);
  44 + tasklet_schedule(&backtrace_tasklet);
  45 + wait_for_completion(&backtrace_work);
24 46 }
  47 +
  48 +#ifdef CONFIG_STACKTRACE
  49 +static void backtrace_test_saved(void)
  50 +{
  51 + struct stack_trace trace;
  52 + unsigned long entries[8];
  53 +
  54 + printk("Testing a saved backtrace.\n");
  55 + printk("The following trace is a kernel self test and not a bug!\n");
  56 +
  57 + trace.nr_entries = 0;
  58 + trace.max_entries = ARRAY_SIZE(entries);
  59 + trace.entries = entries;
  60 + trace.skip = 0;
  61 +
  62 + save_stack_trace(&trace);
  63 + print_stack_trace(&trace, 0);
  64 +}
  65 +#else
  66 +static void backtrace_test_saved(void)
  67 +{
  68 + printk("Saved backtrace test skipped.\n");
  69 +}
  70 +#endif
  71 +
25 72 static int backtrace_regression_test(void)
26 73 {
27 74 printk("====[ backtrace testing ]===========\n");
28   - printk("Testing a backtrace from process context.\n");
29   - printk("The following trace is a kernel self test and not a bug!\n");
30   - dump_stack();
31 75  
32   - init_timer(&backtrace_timer);
33   - backtrace_timer.function = backtrace_test_timer;
34   - mod_timer(&backtrace_timer, jiffies + 10);
  76 + backtrace_test_normal();
  77 + backtrace_test_irq();
  78 + backtrace_test_saved();
35 79  
36   - msleep(10);
37 80 printk("====[ end of backtrace testing ]====\n");
38 81 return 0;
39 82 }
... ... @@ -6,19 +6,21 @@
6 6 * Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
7 7 */
8 8 #include <linux/sched.h>
  9 +#include <linux/module.h>
9 10 #include <linux/kallsyms.h>
10 11 #include <linux/stacktrace.h>
11 12  
12 13 void print_stack_trace(struct stack_trace *trace, int spaces)
13 14 {
14   - int i, j;
  15 + int i;
15 16  
16   - for (i = 0; i < trace->nr_entries; i++) {
17   - unsigned long ip = trace->entries[i];
  17 + if (WARN_ON(!trace->entries))
  18 + return;
18 19  
19   - for (j = 0; j < spaces + 1; j++)
20   - printk(" ");
21   - print_ip_sym(ip);
  20 + for (i = 0; i < trace->nr_entries; i++) {
  21 + printk("%*c", 1 + spaces, ' ');
  22 + print_ip_sym(trace->entries[i]);
22 23 }
23 24 }
  25 +EXPORT_SYMBOL_GPL(print_stack_trace);
... ... @@ -419,7 +419,6 @@
419 419  
420 420 config STACKTRACE
421 421 bool
422   - depends on DEBUG_KERNEL
423 422 depends on STACKTRACE_SUPPORT
424 423  
425 424 config DEBUG_KOBJECT
... ... @@ -562,6 +561,9 @@
562 561 the kernel stack backtrace code. This option is not useful
563 562 for distributions or general kernels, but only for kernel
564 563 developers working on architecture code.
  564 +
  565 + Note that if you want to also test saved backtraces, you will
  566 + have to enable STACKTRACE as well.
565 567  
566 568 Say N if you are unsure.
567 569