diff options
Diffstat (limited to 'arch/m68knommu/kernel/traps.c')
-rw-r--r-- | arch/m68knommu/kernel/traps.c | 38 |
1 files changed, 35 insertions, 3 deletions
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c index ec9aea652e7..46f8f9d0c40 100644 --- a/arch/m68knommu/kernel/traps.c +++ b/arch/m68knommu/kernel/traps.c | |||
@@ -103,12 +103,28 @@ asmlinkage void buserr_c(struct frame *fp) | |||
103 | force_sig(SIGSEGV, current); | 103 | force_sig(SIGSEGV, current); |
104 | } | 104 | } |
105 | 105 | ||
106 | static void print_this_address(unsigned long addr, int i) | ||
107 | { | ||
108 | #ifdef CONFIG_KALLSYMS | ||
109 | printk(KERN_EMERG " [%08lx] ", addr); | ||
110 | print_symbol(KERN_CONT "%s\n", addr); | ||
111 | #else | ||
112 | if (i % 5) | ||
113 | printk(KERN_CONT " [%08lx] ", addr); | ||
114 | else | ||
115 | printk(KERN_CONT "\n" KERN_EMERG " [%08lx] ", addr); | ||
116 | i++; | ||
117 | #endif | ||
118 | } | ||
119 | |||
106 | int kstack_depth_to_print = 48; | 120 | int kstack_depth_to_print = 48; |
107 | 121 | ||
108 | static void __show_stack(struct task_struct *task, unsigned long *stack) | 122 | static void __show_stack(struct task_struct *task, unsigned long *stack) |
109 | { | 123 | { |
110 | unsigned long *endstack, addr; | 124 | unsigned long *endstack, addr; |
125 | #ifdef CONFIG_FRAME_POINTER | ||
111 | unsigned long *last_stack; | 126 | unsigned long *last_stack; |
127 | #endif | ||
112 | int i; | 128 | int i; |
113 | 129 | ||
114 | if (!stack) | 130 | if (!stack) |
@@ -126,6 +142,7 @@ static void __show_stack(struct task_struct *task, unsigned long *stack) | |||
126 | printk(" %08lx", *(stack + i)); | 142 | printk(" %08lx", *(stack + i)); |
127 | } | 143 | } |
128 | printk("\n"); | 144 | printk("\n"); |
145 | i = 0; | ||
129 | 146 | ||
130 | #ifdef CONFIG_FRAME_POINTER | 147 | #ifdef CONFIG_FRAME_POINTER |
131 | printk(KERN_EMERG "Call Trace:\n"); | 148 | printk(KERN_EMERG "Call Trace:\n"); |
@@ -134,15 +151,30 @@ static void __show_stack(struct task_struct *task, unsigned long *stack) | |||
134 | while (stack <= endstack && stack > last_stack) { | 151 | while (stack <= endstack && stack > last_stack) { |
135 | 152 | ||
136 | addr = *(stack + 1); | 153 | addr = *(stack + 1); |
137 | printk(KERN_EMERG " [%08lx] ", addr); | 154 | print_this_address(addr, i); |
138 | print_symbol(KERN_CONT "%s\n", addr); | 155 | i++; |
139 | 156 | ||
140 | last_stack = stack; | 157 | last_stack = stack; |
141 | stack = (unsigned long *)*stack; | 158 | stack = (unsigned long *)*stack; |
142 | } | 159 | } |
143 | printk("\n"); | 160 | printk("\n"); |
144 | #else | 161 | #else |
145 | printk(KERN_EMERG "CONFIG_FRAME_POINTER disabled, no symbolic call trace\n"); | 162 | printk(KERN_EMERG "Call Trace with CONFIG_FRAME_POINTER disabled:\n"); |
163 | while (stack <= endstack) { | ||
164 | addr = *stack++; | ||
165 | /* | ||
166 | * If the address is either in the text segment of the kernel, | ||
167 | * or in a region which is occupied by a module then it *may* | ||
168 | * be the address of a calling routine; if so, print it so that | ||
169 | * someone tracing down the cause of the crash will be able to | ||
170 | * figure out the call path that was taken. | ||
171 | */ | ||
172 | if (__kernel_text_address(addr)) { | ||
173 | print_this_address(addr, i); | ||
174 | i++; | ||
175 | } | ||
176 | } | ||
177 | printk(KERN_CONT "\n"); | ||
146 | #endif | 178 | #endif |
147 | } | 179 | } |
148 | 180 | ||