Whamcloud - gitweb
b=10651
[fs/lustre-release.git] / lustre / kernel_patches / patches / llnl-frame-pointer-walk-2.4.21-rhel.patch
1 diff -X dontdiff -urp kern_oldest/arch/i386/kernel/traps.c kern_fix/arch/i386/kernel/traps.c
2 --- kern_oldest/arch/i386/kernel/traps.c        2006-05-01 11:56:31.000000000 -0700
3 +++ kern_fix/arch/i386/kernel/traps.c   2006-05-01 14:56:40.000000000 -0700
4 @@ -133,6 +133,80 @@ static inline int kernel_text_address(un
5  
6  #endif
7  
8 +#if CONFIG_FRAME_POINTER
9 +void show_stack_frame_params (int param_count, unsigned long params[])
10 +{
11 +       int i;
12 +       unsigned long *p, task_addr, stack_base;
13 +
14 +       if (param_count <= 0)
15 +               return;
16 +
17 +       task_addr = (unsigned long) current;
18 +       stack_base = task_addr + THREAD_SIZE - 1;
19 +
20 +       printk("             (");
21 +
22 +       for (i = 0, p = params;
23 +            ((param_count - i) > 1) && (p >= task_addr) && (p <= stack_base);
24 +            i++, p++) {
25 +               printk("0x%x, ", *p);
26 +
27 +               if ((i % 4) == 3)
28 +                       printk("\n              ");
29 +       }
30 +
31 +       if ((p >= task_addr) && (p <= stack_base))
32 +               printk("0x%x)\n", *p);
33 +}
34 +
35 +void frame_pointer_walk(unsigned long *stack)
36 +{
37 +       int i;
38 +       unsigned long addr, task_addr, *frame_ptr, *next_frame_ptr, *eip_ptr,
39 +                     eip, stack_base;
40 +       /* static to not take up stackspace; if we race here too bad */
41 +       static char buffer[512];
42 +
43 +       addr = (unsigned long) stack;
44 +       task_addr = (unsigned long) current;
45 +       stack_base = task_addr + THREAD_SIZE - 1;
46 +
47 +       /* Simply return if we are doing a stack trace for any task other
48 +        * than the currently executing task.  To trace another task, we
49 +        * would need an %ebp register value for that task.
50 +        */
51 +       if (((addr < task_addr) || (addr > stack_base))) {
52 +               return;
53 +       }
54 +
55 +       frame_ptr = (unsigned long *) (&stack - 2);
56 +
57 +       for (; ; ) {
58 +               next_frame_ptr = (unsigned long *) (*frame_ptr);
59 +               addr = (unsigned long) next_frame_ptr;
60 +
61 +               /* Stop when we reach a frame pointer that points to a
62 +                * location clearly outside our own kernel stack.
63 +                */
64 +               if ((addr < task_addr) || (addr > stack_base))
65 +                       break;
66 +
67 +               eip_ptr = frame_ptr + 1;
68 +               eip = *eip_ptr;
69 +
70 +               if (kernel_text_address(eip)) {
71 +                       lookup_symbol(eip, buffer, 512);
72 +                       show_stack_frame_params(4, frame_ptr + 2);
73 +                       printk("[<%08lx>] %s (0x%x)\n", eip, buffer,
74 +                              eip_ptr);
75 +               }
76 +
77 +               frame_ptr = next_frame_ptr;
78 +       }
79 +}
80 +#endif
81 +
82  void show_trace(unsigned long * stack)
83  {
84  #if !CONFIG_FRAME_POINTER
85 @@ -151,16 +225,7 @@ void show_trace(unsigned long * stack)
86          * a 100% exact backtrace, up until the entry frame:
87          */
88  #if CONFIG_FRAME_POINTER
89 -#define DO(n) \
90 -       addr = (int)__builtin_return_address(n);        \
91 -       if (!kernel_text_address(addr))                 \
92 -               goto out;                               \
93 -       lookup_symbol(addr, buffer, 512);               \
94 -       printk("[<%08lx>] %s\n", addr, buffer);
95 -
96 -       DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(7); DO(8); DO(9);
97 -       DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); DO(17); DO(18); DO(19);
98 -out:
99 +       frame_pointer_walk(stack);
100  #else
101         i = 1;
102         limit = ((unsigned long)stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE - 3;
103 @@ -168,7 +233,7 @@ out:
104                 addr = *stack++;
105                 if (kernel_text_address(addr)) {
106                         lookup_symbol(addr, buffer, 512);
107 -                       printk("[<%08lx>] %s (0x%p)\n", addr,buffer,stack-1);
108 +                       printk("[<%08lx>] %s (0x%x)\n", addr,buffer,stack-1);
109                         i++;
110                 }
111         }
112 @@ -244,7 +309,7 @@ void show_registers(struct pt_regs *regs
113         lookup_symbol(regs->eip, buffer, 512);
114         printk("CPU:    %d\nEIP:    %04x:[<%08lx>]    %s\nEFLAGS: %08lx\n",
115                 smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags);
116 -       printk("\nEIP is at %s (" UTS_RELEASE ARCHIT ")\n",buffer);
117 +       printk("\nEIP is at %s (" UTS_RELEASE ")\n",buffer);
118         printk("eax: %08lx   ebx: %08lx   ecx: %08lx   edx: %08lx\n",
119                 regs->eax, regs->ebx, regs->ecx, regs->edx);
120         printk("esi: %08lx   edi: %08lx   ebp: %08lx   esp: %08lx\n",