diff options
Diffstat (limited to 'arch/i386/kernel/traps.c')
-rw-r--r-- | arch/i386/kernel/traps.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index b9f0030a2ebb..0aaebf3e1cfa 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -112,33 +112,38 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p) | |||
112 | p < (void *)tinfo + THREAD_SIZE - 3; | 112 | p < (void *)tinfo + THREAD_SIZE - 3; |
113 | } | 113 | } |
114 | 114 | ||
115 | static void print_addr_and_symbol(unsigned long addr, char *log_lvl) | ||
116 | { | ||
117 | printk(log_lvl); | ||
118 | printk(" [<%08lx>] ", addr); | ||
119 | print_symbol("%s", addr); | ||
120 | printk("\n"); | ||
121 | } | ||
122 | |||
115 | static inline unsigned long print_context_stack(struct thread_info *tinfo, | 123 | static inline unsigned long print_context_stack(struct thread_info *tinfo, |
116 | unsigned long *stack, unsigned long ebp) | 124 | unsigned long *stack, unsigned long ebp, |
125 | char *log_lvl) | ||
117 | { | 126 | { |
118 | unsigned long addr; | 127 | unsigned long addr; |
119 | 128 | ||
120 | #ifdef CONFIG_FRAME_POINTER | 129 | #ifdef CONFIG_FRAME_POINTER |
121 | while (valid_stack_ptr(tinfo, (void *)ebp)) { | 130 | while (valid_stack_ptr(tinfo, (void *)ebp)) { |
122 | addr = *(unsigned long *)(ebp + 4); | 131 | addr = *(unsigned long *)(ebp + 4); |
123 | printk(KERN_EMERG " [<%08lx>] ", addr); | 132 | print_addr_and_symbol(addr, log_lvl); |
124 | print_symbol("%s", addr); | ||
125 | printk("\n"); | ||
126 | ebp = *(unsigned long *)ebp; | 133 | ebp = *(unsigned long *)ebp; |
127 | } | 134 | } |
128 | #else | 135 | #else |
129 | while (valid_stack_ptr(tinfo, stack)) { | 136 | while (valid_stack_ptr(tinfo, stack)) { |
130 | addr = *stack++; | 137 | addr = *stack++; |
131 | if (__kernel_text_address(addr)) { | 138 | if (__kernel_text_address(addr)) |
132 | printk(KERN_EMERG " [<%08lx>]", addr); | 139 | print_addr_and_symbol(addr, log_lvl); |
133 | print_symbol(" %s", addr); | ||
134 | printk("\n"); | ||
135 | } | ||
136 | } | 140 | } |
137 | #endif | 141 | #endif |
138 | return ebp; | 142 | return ebp; |
139 | } | 143 | } |
140 | 144 | ||
141 | void show_trace(struct task_struct *task, unsigned long * stack) | 145 | static void show_trace_log_lvl(struct task_struct *task, |
146 | unsigned long *stack, char *log_lvl) | ||
142 | { | 147 | { |
143 | unsigned long ebp; | 148 | unsigned long ebp; |
144 | 149 | ||
@@ -157,7 +162,7 @@ void show_trace(struct task_struct *task, unsigned long * stack) | |||
157 | struct thread_info *context; | 162 | struct thread_info *context; |
158 | context = (struct thread_info *) | 163 | context = (struct thread_info *) |
159 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); | 164 | ((unsigned long)stack & (~(THREAD_SIZE - 1))); |
160 | ebp = print_context_stack(context, stack, ebp); | 165 | ebp = print_context_stack(context, stack, ebp, log_lvl); |
161 | stack = (unsigned long*)context->previous_esp; | 166 | stack = (unsigned long*)context->previous_esp; |
162 | if (!stack) | 167 | if (!stack) |
163 | break; | 168 | break; |
@@ -165,7 +170,13 @@ void show_trace(struct task_struct *task, unsigned long * stack) | |||
165 | } | 170 | } |
166 | } | 171 | } |
167 | 172 | ||
168 | void show_stack(struct task_struct *task, unsigned long *esp) | 173 | void show_trace(struct task_struct *task, unsigned long * stack) |
174 | { | ||
175 | show_trace_log_lvl(task, stack, ""); | ||
176 | } | ||
177 | |||
178 | static void show_stack_log_lvl(struct task_struct *task, unsigned long *esp, | ||
179 | char *log_lvl) | ||
169 | { | 180 | { |
170 | unsigned long *stack; | 181 | unsigned long *stack; |
171 | int i; | 182 | int i; |
@@ -178,16 +189,26 @@ void show_stack(struct task_struct *task, unsigned long *esp) | |||
178 | } | 189 | } |
179 | 190 | ||
180 | stack = esp; | 191 | stack = esp; |
181 | printk(KERN_EMERG); | 192 | printk(log_lvl); |
182 | for(i = 0; i < kstack_depth_to_print; i++) { | 193 | for(i = 0; i < kstack_depth_to_print; i++) { |
183 | if (kstack_end(stack)) | 194 | if (kstack_end(stack)) |
184 | break; | 195 | break; |
185 | if (i && ((i % 8) == 0)) | 196 | if (i && ((i % 8) == 0)) { |
186 | printk("\n" KERN_EMERG " "); | 197 | printk("\n"); |
198 | printk(log_lvl); | ||
199 | printk(" "); | ||
200 | } | ||
187 | printk("%08lx ", *stack++); | 201 | printk("%08lx ", *stack++); |
188 | } | 202 | } |
189 | printk("\n" KERN_EMERG "Call Trace:\n"); | 203 | printk("\n"); |
190 | show_trace(task, esp); | 204 | printk(log_lvl); |
205 | printk("Call Trace:\n"); | ||
206 | show_trace_log_lvl(task, esp, log_lvl); | ||
207 | } | ||
208 | |||
209 | void show_stack(struct task_struct *task, unsigned long *esp) | ||
210 | { | ||
211 | show_stack_log_lvl(task, esp, ""); | ||
191 | } | 212 | } |
192 | 213 | ||
193 | /* | 214 | /* |
@@ -238,7 +259,7 @@ void show_registers(struct pt_regs *regs) | |||
238 | u8 __user *eip; | 259 | u8 __user *eip; |
239 | 260 | ||
240 | printk("\n" KERN_EMERG "Stack: "); | 261 | printk("\n" KERN_EMERG "Stack: "); |
241 | show_stack(NULL, (unsigned long*)esp); | 262 | show_stack_log_lvl(NULL, (unsigned long *)esp, KERN_EMERG); |
242 | 263 | ||
243 | printk(KERN_EMERG "Code: "); | 264 | printk(KERN_EMERG "Code: "); |
244 | 265 | ||