Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 #include <linux/module.h>
  2 #include <linux/sched.h>
  3 #include <linux/stacktrace.h>
  4 
  5 #include "stacktrace.h"
  6 
  7 int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high,
  8                     int (*fn)(struct stackframe *, void *), void *data)
  9 {
 10         struct stackframe *frame;
 11 
 12         do {
 13                 /*
 14                  * Check current frame pointer is within bounds
 15                  */
 16                 if (fp < (low + 12) || fp + 4 >= high)
 17                         break;
 18 
 19                 frame = (struct stackframe *)(fp - 12);
 20 
 21                 if (fn(frame, data))
 22                         break;
 23 
 24                 /*
 25                  * Update the low bound - the next frame must always
 26                  * be at a higher address than the current frame.
 27                  */
 28                 low = fp + 4;
 29                 fp = frame->fp;
 30         } while (fp);
 31 
 32         return 0;
 33 }
 34 EXPORT_SYMBOL(walk_stackframe);
 35 
 36 #ifdef CONFIG_STACKTRACE
 37 struct stack_trace_data {
 38         struct stack_trace *trace;
 39         unsigned int skip;
 40 };
 41 
 42 static int save_trace(struct stackframe *frame, void *d)
 43 {
 44         struct stack_trace_data *data = d;
 45         struct stack_trace *trace = data->trace;
 46 
 47         if (data->skip) {
 48                 data->skip--;
 49                 return 0;
 50         }
 51 
 52         trace->entries[trace->nr_entries++] = frame->lr;
 53 
 54         return trace->nr_entries >= trace->max_entries;
 55 }
 56 
 57 void save_stack_trace(struct stack_trace *trace)
 58 {
 59         struct stack_trace_data data;
 60         unsigned long fp, base;
 61 
 62         data.trace = trace;
 63         data.skip = trace->skip;
 64         base = (unsigned long)task_stack_page(current);
 65         asm("mov %0, fp" : "=r" (fp));
 66 
 67         walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
 68 }
 69 #endif
 70 
  This page was automatically generated by the LXR engine.