+++ /dev/null
-Index: linux-2.4.20/kernel/ksyms.c
-===================================================================
---- linux-2.4.20.orig/kernel/ksyms.c 2004-10-21 21:30:14.000000000 -0400
-+++ linux-2.4.20/kernel/ksyms.c 2004-10-21 21:32:00.000000000 -0400
-@@ -75,6 +75,7 @@
- extern spinlock_t dma_spin_lock;
- extern int panic_timeout;
-
-+extern void show_task(task_t *);
-
- #ifdef CONFIG_MODVERSIONS
- const struct module_symbol __export_Using_Versions
-@@ -636,3 +637,4 @@
- extern void check_tasklist_locked(void);
- EXPORT_SYMBOL_GPL(check_tasklist_locked);
- EXPORT_SYMBOL(dump_stack);
-+EXPORT_SYMBOL(show_task);
-Index: linux-2.4.20/arch/i386/kernel/traps.c
-===================================================================
---- linux-2.4.20.orig/arch/i386/kernel/traps.c 2004-10-21 21:30:15.000000000 -0400
-+++ linux-2.4.20/arch/i386/kernel/traps.c 2004-10-25 14:34:41.000000000 -0400
-@@ -137,29 +137,141 @@
-
- #endif
-
--void show_trace(unsigned long * stack)
-+void scan_stack (unsigned long *stack)
- {
- int i;
- unsigned long addr;
-- /* static to not take up stackspace; if we race here too bad */
-- static char buffer[512];
-+ /* static to not take up stackspace */
-+ static char buffer[NR_CPUS][512], *bufp;
-
-- if (!stack)
-- stack = (unsigned long*)&stack;
-+ bufp = buffer[smp_processor_id()];
-
-- printk("Call Trace: ");
-+ /*
-+ * If we have frame pointers then use them to get
-+ * a 100% exact backtrace, up until the entry frame:
-+ */
- i = 1;
- while (((long) stack & (THREAD_SIZE-1)) != 0) {
- addr = *stack++;
- if (kernel_text_address(addr)) {
-- lookup_symbol(addr, buffer, 512);
-- printk("[<%08lx>] %s (0x%x))\n", addr,buffer,stack-1);
-+ lookup_symbol(addr, bufp, 512);
-+ printk("[<%08lx>] %s (0x%p)\n", addr,bufp,stack-1);
- i++;
- }
- }
-+}
-+
-+#if CONFIG_FRAME_POINTER
-+void show_stack_frame_params (int param_count, unsigned long params[])
-+{
-+ int i;
-+ unsigned long *p, task_addr, stack_base;
-+
-+ if (param_count <= 0)
-+ return;
-+
-+ task_addr = (unsigned long) current;
-+ stack_base = task_addr + THREAD_SIZE - 1;
-+
-+ printk(" (");
-+
-+ for (i = 0, p = params;
-+ ((param_count - i) > 1) && (p >= task_addr) && (p <= stack_base);
-+ i++, p++) {
-+ printk("0x%x, ", *p);
-+
-+ if ((i % 4) == 3)
-+ printk("\n ");
-+ }
-+
-+ if ((p >= task_addr) && (p <= stack_base))
-+ printk("0x%x)\n", *p);
-+}
-+
-+/* Display a stack trace for the currently executing task. The 'dummy'
-+ * parameter serves a purpose although its value is unused. We use the
-+ * address of 'dummy' as a reference point for finding the saved %ebp register
-+ * value on the stack.
-+ */
-+void frame_pointer_walk (void *dummy)
-+{
-+ int i;
-+ unsigned long addr, task_addr, *frame_ptr, *next_frame_ptr, *eip_ptr,
-+ eip, stack_base;
-+ /* static to not take up stackspace */
-+ static char buffer[NR_CPUS][512], *bufp;
-+
-+ bufp = buffer[smp_processor_id()];
-+ task_addr = (unsigned long) current;
-+ stack_base = task_addr + THREAD_SIZE - 1;
-+ frame_ptr = (unsigned long *) (&dummy - 2);
-+
-+ for (; ; ) {
-+ next_frame_ptr = (unsigned long *) (*frame_ptr);
-+ addr = (unsigned long) next_frame_ptr;
-+
-+ /* Stop when we reach a frame pointer that points to a
-+ * location clearly outside our own kernel stack.
-+ */
-+ if ((addr < task_addr) || (addr > stack_base))
-+ break;
-+
-+ eip_ptr = frame_ptr + 1;
-+ eip = *eip_ptr;
-+
-+ if (kernel_text_address(eip)) {
-+ lookup_symbol(eip, bufp, 512);
-+ show_stack_frame_params(4, frame_ptr + 2);
-+ printk("[<%08lx>] %s (0x%x)\n", eip, bufp,
-+ eip_ptr);
-+ }
-+
-+ frame_ptr = next_frame_ptr;
-+ }
-+}
-+
-+typedef void (*stack_trace_fn_t) (unsigned long *stack);
-+
-+void show_trace(unsigned long * stack)
-+{
-+ static const stack_trace_fn_t trace_fn_vector[] =
-+ { scan_stack, frame_pointer_walk };
-+ unsigned long addr, task_addr, stack_base;
-+ int task_is_current;
-+
-+ if (!stack)
-+ stack = (unsigned long*)&stack;
-+
-+ printk("Call Trace:\n");
-+ addr = (unsigned long) stack;
-+ task_addr = (unsigned long) current;
-+ stack_base = task_addr + THREAD_SIZE - 1;
-+ task_is_current = (addr >= task_addr) && (addr <= stack_base);
-+
-+ /* We may use frame pointers to do a stack trace only if the current
-+ * task is being traced. Tracing some other task in this manner
-+ * would require a saved %ebp register value. Perhaps in the future
-+ * I'll consider providing a means of obtaining this.
-+ */
-+ trace_fn_vector[task_is_current](stack);
-+
- printk("\n");
- }
-
-+#else /* CONFIG_FRAME_POINTER */
-+
-+void show_trace(unsigned long * stack)
-+{
-+ if (!stack)
-+ stack = (unsigned long*)&stack;
-+
-+ printk("Call Trace:\n");
-+ scan_stack(stack);
-+ printk("\n");
-+}
-+
-+#endif /* CONFIG_FRAME_POINTER */
-+
- void show_trace_task(struct task_struct *tsk)
- {
- unsigned long esp = tsk->thread.esp;