Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

stack.c

Go to the documentation of this file.
00001 #ifndef _STACK_C_
00002 #define _STACK_C_
00003 /* -*- linux-c -*- */
00004 
00005 /** @file stack.c
00006  * @brief Stack Tracing Functions
00007  */
00008 
00009 /** @addtogroup stack Stack Tracing Functions
00010  * @{
00011  */
00012 
00013 #include "sym.c"
00014 
00015 static int (*_stp_kta)(unsigned long addr)=(void *)KTA;
00016 
00017 #ifdef __x86_64__
00018 static void __stp_stack_print (unsigned long *stack, int verbose, int levels)
00019 {
00020         unsigned long addr;
00021 
00022         if (verbose)
00023                 _stp_print ("trace for %d (%s)\n", current->pid, current->comm);
00024 
00025         while (((long) stack & (THREAD_SIZE-1)) != 0) {
00026                 addr = *stack++;
00027                 if (_stp_kta(addr)) {
00028                         if (verbose)
00029                                 _stp_symbol_print (addr);
00030                         else
00031                                 _stp_print ("0x%lx ", addr);
00032                 }
00033         }
00034         _stp_print_str ("\n");
00035 }
00036 
00037 
00038 static char *__stp_stack_sprint (unsigned long *stack, int verbose, int levels)
00039 {
00040         unsigned long addr;
00041         char *ptr = _stp_scbuf_cur();
00042         while (((long) stack & (THREAD_SIZE-1)) != 0) {
00043                 addr = *stack++;
00044                 if (_stp_kta(addr)) {
00045                         if (verbose)
00046                                 _stp_symbol_sprint (addr);
00047                         else
00048                                 _stp_sprint ("0x%lx ", addr);
00049                 }
00050         }
00051         return ptr;
00052 }
00053 
00054 #else  /* i386 */
00055 
00056 static inline int valid_stack_ptr (struct thread_info *tinfo, void *p)
00057 {
00058         return  p > (void *)tinfo &&
00059                 p < (void *)tinfo + THREAD_SIZE - 3;
00060 }
00061 
00062 static inline unsigned long _stp_print_context_stack (
00063         struct thread_info *tinfo,
00064         unsigned long *stack, 
00065         unsigned long ebp )
00066 {
00067         unsigned long addr;
00068 
00069 #ifdef  CONFIG_FRAME_POINTER
00070         while (valid_stack_ptr(tinfo, (void *)ebp)) {
00071                 addr = *(unsigned long *)(ebp + 4);
00072                 _stp_symbol_print (addr);
00073                 _stp_print_str("\n");
00074                 ebp = *(unsigned long *)ebp;
00075         }
00076 #else
00077         while (valid_stack_ptr(tinfo, stack)) {
00078                 addr = *stack++;
00079                 if (_stp_kta (addr)) {
00080                         _stp_symbol_print (addr);
00081                         _stp_print_str ("\n");
00082                 }
00083         }
00084 #endif
00085         return ebp;
00086 }
00087 
00088 static inline unsigned long _stp_sprint_context_stack (
00089         struct thread_info *tinfo,
00090         unsigned long *stack, 
00091         unsigned long ebp )
00092 {
00093         unsigned long addr;
00094 
00095 #ifdef  CONFIG_FRAME_POINTER
00096         while (valid_stack_ptr(tinfo, (void *)ebp)) {
00097                 addr = *(unsigned long *)(ebp + 4);
00098                 _stp_symbol_sprint (addr);
00099                 _stp_sprint_str("\n");
00100                 ebp = *(unsigned long *)ebp;
00101         }
00102 #else
00103         while (valid_stack_ptr(tinfo, stack)) {
00104                 addr = *stack++;
00105                 if (_stp_kta (addr)) {
00106                         _stp_symbol_sprint (addr);
00107                         _stp_sprint_str ("\n");
00108                 }
00109         }
00110 #endif
00111         return ebp;
00112 }
00113 
00114 static void __stp_stack_print (unsigned long *stack, int verbose, int levels)
00115 {
00116         unsigned long ebp;
00117 
00118         /* Grab ebp right from our regs */
00119         asm ("movl %%ebp, %0" : "=r" (ebp) : );
00120 
00121         while (stack) {
00122                 struct thread_info *context = (struct thread_info *)
00123                         ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00124                 ebp = _stp_print_context_stack (context, stack, ebp);
00125                 stack = (unsigned long*)context->previous_esp;
00126         }
00127 }
00128 
00129 static void __stp_stack_sprint (unsigned long *stack, int verbose, int levels)
00130 {
00131         unsigned long ebp;
00132 
00133         /* Grab ebp right from our regs */
00134         asm ("movl %%ebp, %0" : "=r" (ebp) : );
00135 
00136         while (stack) {
00137                 struct thread_info *context = (struct thread_info *)
00138                         ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00139                 ebp = _stp_sprint_context_stack (context, stack, ebp);
00140                 stack = (unsigned long*)context->previous_esp;
00141         }
00142 }
00143 
00144 #endif /* i386 */
00145 
00146 void _stp_stack_print (int verbose, int levels)
00147 {
00148   unsigned long stack;
00149   return __stp_stack_print (&stack, verbose, levels);
00150 }
00151 
00152 char *_stp_stack_sprint (int verbose, int levels)
00153 {
00154   unsigned long stack;
00155   char *ptr = _stp_scbuf_cur();
00156   __stp_stack_sprint (&stack, verbose, levels);
00157   return ptr;
00158 }
00159 
00160 /** @} */
00161 #endif /* _STACK_C_ */