diff options
Diffstat (limited to 'kernel/trace/trace_stack.c')
| -rw-r--r-- | kernel/trace/trace_stack.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c index 21b320e5d163..8a4e5cb66a4c 100644 --- a/kernel/trace/trace_stack.c +++ b/kernel/trace/trace_stack.c | |||
| @@ -51,11 +51,33 @@ static DEFINE_MUTEX(stack_sysctl_mutex); | |||
| 51 | int stack_tracer_enabled; | 51 | int stack_tracer_enabled; |
| 52 | static int last_stack_tracer_enabled; | 52 | static int last_stack_tracer_enabled; |
| 53 | 53 | ||
| 54 | static inline void print_max_stack(void) | ||
| 55 | { | ||
| 56 | long i; | ||
| 57 | int size; | ||
| 58 | |||
| 59 | pr_emerg(" Depth Size Location (%d entries)\n" | ||
| 60 | " ----- ---- --------\n", | ||
| 61 | max_stack_trace.nr_entries - 1); | ||
| 62 | |||
| 63 | for (i = 0; i < max_stack_trace.nr_entries; i++) { | ||
| 64 | if (stack_dump_trace[i] == ULONG_MAX) | ||
| 65 | break; | ||
| 66 | if (i+1 == max_stack_trace.nr_entries || | ||
| 67 | stack_dump_trace[i+1] == ULONG_MAX) | ||
| 68 | size = stack_dump_index[i]; | ||
| 69 | else | ||
| 70 | size = stack_dump_index[i] - stack_dump_index[i+1]; | ||
| 71 | |||
| 72 | pr_emerg("%3ld) %8d %5d %pS\n", i, stack_dump_index[i], | ||
| 73 | size, (void *)stack_dump_trace[i]); | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 54 | static inline void | 77 | static inline void |
| 55 | check_stack(unsigned long ip, unsigned long *stack) | 78 | check_stack(unsigned long ip, unsigned long *stack) |
| 56 | { | 79 | { |
| 57 | unsigned long this_size, flags; | 80 | unsigned long this_size, flags; unsigned long *p, *top, *start; |
| 58 | unsigned long *p, *top, *start; | ||
| 59 | static int tracer_frame; | 81 | static int tracer_frame; |
| 60 | int frame_size = ACCESS_ONCE(tracer_frame); | 82 | int frame_size = ACCESS_ONCE(tracer_frame); |
| 61 | int i; | 83 | int i; |
| @@ -85,8 +107,12 @@ check_stack(unsigned long ip, unsigned long *stack) | |||
| 85 | 107 | ||
| 86 | max_stack_size = this_size; | 108 | max_stack_size = this_size; |
| 87 | 109 | ||
| 88 | max_stack_trace.nr_entries = 0; | 110 | max_stack_trace.nr_entries = 0; |
| 89 | max_stack_trace.skip = 3; | 111 | |
| 112 | if (using_ftrace_ops_list_func()) | ||
| 113 | max_stack_trace.skip = 4; | ||
| 114 | else | ||
| 115 | max_stack_trace.skip = 3; | ||
| 90 | 116 | ||
| 91 | save_stack_trace(&max_stack_trace); | 117 | save_stack_trace(&max_stack_trace); |
| 92 | 118 | ||
| @@ -145,8 +171,12 @@ check_stack(unsigned long ip, unsigned long *stack) | |||
| 145 | i++; | 171 | i++; |
| 146 | } | 172 | } |
| 147 | 173 | ||
| 148 | BUG_ON(current != &init_task && | 174 | if ((current != &init_task && |
| 149 | *(end_of_stack(current)) != STACK_END_MAGIC); | 175 | *(end_of_stack(current)) != STACK_END_MAGIC)) { |
| 176 | print_max_stack(); | ||
| 177 | BUG(); | ||
| 178 | } | ||
| 179 | |||
| 150 | out: | 180 | out: |
| 151 | arch_spin_unlock(&max_stack_lock); | 181 | arch_spin_unlock(&max_stack_lock); |
| 152 | local_irq_restore(flags); | 182 | local_irq_restore(flags); |
