1 Index: linux-2.4.20/kernel/ksyms.c
2 ===================================================================
3 --- linux-2.4.20.orig/kernel/ksyms.c 2004-10-21 21:30:14.000000000 -0400
4 +++ linux-2.4.20/kernel/ksyms.c 2004-10-21 21:32:00.000000000 -0400
6 extern spinlock_t dma_spin_lock;
7 extern int panic_timeout;
9 +extern void show_task(task_t *);
11 #ifdef CONFIG_MODVERSIONS
12 const struct module_symbol __export_Using_Versions
14 extern void check_tasklist_locked(void);
15 EXPORT_SYMBOL_GPL(check_tasklist_locked);
16 EXPORT_SYMBOL(dump_stack);
17 +EXPORT_SYMBOL(show_task);
18 Index: linux-2.4.20/arch/i386/kernel/traps.c
19 ===================================================================
20 --- linux-2.4.20.orig/arch/i386/kernel/traps.c 2004-10-21 21:30:15.000000000 -0400
21 +++ linux-2.4.20/arch/i386/kernel/traps.c 2004-10-25 14:34:41.000000000 -0400
22 @@ -137,29 +137,141 @@
26 -void show_trace(unsigned long * stack)
27 +void scan_stack (unsigned long *stack)
31 - /* static to not take up stackspace; if we race here too bad */
32 - static char buffer[512];
33 + /* static to not take up stackspace */
34 + static char buffer[NR_CPUS][512], *bufp;
37 - stack = (unsigned long*)&stack;
38 + bufp = buffer[smp_processor_id()];
40 - printk("Call Trace: ");
42 + * If we have frame pointers then use them to get
43 + * a 100% exact backtrace, up until the entry frame:
46 while (((long) stack & (THREAD_SIZE-1)) != 0) {
48 if (kernel_text_address(addr)) {
49 - lookup_symbol(addr, buffer, 512);
50 - printk("[<%08lx>] %s (0x%x))\n", addr,buffer,stack-1);
51 + lookup_symbol(addr, bufp, 512);
52 + printk("[<%08lx>] %s (0x%p)\n", addr,bufp,stack-1);
58 +#if CONFIG_FRAME_POINTER
59 +void show_stack_frame_params (int param_count, unsigned long params[])
62 + unsigned long *p, task_addr, stack_base;
64 + if (param_count <= 0)
67 + task_addr = (unsigned long) current;
68 + stack_base = task_addr + THREAD_SIZE - 1;
72 + for (i = 0, p = params;
73 + ((param_count - i) > 1) && (p >= task_addr) && (p <= stack_base);
75 + printk("0x%x, ", *p);
81 + if ((p >= task_addr) && (p <= stack_base))
82 + printk("0x%x)\n", *p);
85 +/* Display a stack trace for the currently executing task. The 'dummy'
86 + * parameter serves a purpose although its value is unused. We use the
87 + * address of 'dummy' as a reference point for finding the saved %ebp register
88 + * value on the stack.
90 +void frame_pointer_walk (void *dummy)
93 + unsigned long addr, task_addr, *frame_ptr, *next_frame_ptr, *eip_ptr,
95 + /* static to not take up stackspace */
96 + static char buffer[NR_CPUS][512], *bufp;
98 + bufp = buffer[smp_processor_id()];
99 + task_addr = (unsigned long) current;
100 + stack_base = task_addr + THREAD_SIZE - 1;
101 + frame_ptr = (unsigned long *) (&dummy - 2);
104 + next_frame_ptr = (unsigned long *) (*frame_ptr);
105 + addr = (unsigned long) next_frame_ptr;
107 + /* Stop when we reach a frame pointer that points to a
108 + * location clearly outside our own kernel stack.
110 + if ((addr < task_addr) || (addr > stack_base))
113 + eip_ptr = frame_ptr + 1;
116 + if (kernel_text_address(eip)) {
117 + lookup_symbol(eip, bufp, 512);
118 + show_stack_frame_params(4, frame_ptr + 2);
119 + printk("[<%08lx>] %s (0x%x)\n", eip, bufp,
123 + frame_ptr = next_frame_ptr;
127 +typedef void (*stack_trace_fn_t) (unsigned long *stack);
129 +void show_trace(unsigned long * stack)
131 + static const stack_trace_fn_t trace_fn_vector[] =
132 + { scan_stack, frame_pointer_walk };
133 + unsigned long addr, task_addr, stack_base;
134 + int task_is_current;
137 + stack = (unsigned long*)&stack;
139 + printk("Call Trace:\n");
140 + addr = (unsigned long) stack;
141 + task_addr = (unsigned long) current;
142 + stack_base = task_addr + THREAD_SIZE - 1;
143 + task_is_current = (addr >= task_addr) && (addr <= stack_base);
145 + /* We may use frame pointers to do a stack trace only if the current
146 + * task is being traced. Tracing some other task in this manner
147 + * would require a saved %ebp register value. Perhaps in the future
148 + * I'll consider providing a means of obtaining this.
150 + trace_fn_vector[task_is_current](stack);
155 +#else /* CONFIG_FRAME_POINTER */
157 +void show_trace(unsigned long * stack)
160 + stack = (unsigned long*)&stack;
162 + printk("Call Trace:\n");
167 +#endif /* CONFIG_FRAME_POINTER */
169 void show_trace_task(struct task_struct *tsk)
171 unsigned long esp = tsk->thread.esp;