00001 #ifndef _STACK_C_
00002 #define _STACK_C_
00003
00004
00005
00006
00007
00008
00009
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_printf ("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 _stp_print ("\n");
00031 } else
00032 _stp_printf ("0x%lx ", addr);
00033 }
00034 }
00035 _stp_print_flush();
00036 }
00037
00038
00039 static void __stp_stack_sprint (String str, unsigned long *stack, int verbose, int levels)
00040 {
00041 unsigned long addr;
00042 while (((long) stack & (THREAD_SIZE-1)) != 0) {
00043 addr = *stack++;
00044 if (_stp_kta(addr)) {
00045 if (verbose)
00046 _stp_symbol_sprint (str, addr);
00047 else
00048 _stp_sprintf (str, "0x%lx ", addr);
00049 }
00050 }
00051 }
00052
00053 #else
00054
00055 static inline int valid_stack_ptr (struct thread_info *tinfo, void *p)
00056 {
00057 return p > (void *)tinfo &&
00058 p < (void *)tinfo + THREAD_SIZE - 3;
00059 }
00060
00061 static inline unsigned long _stp_print_context_stack (
00062 struct thread_info *tinfo,
00063 unsigned long *stack,
00064 unsigned long ebp )
00065 {
00066 unsigned long addr;
00067
00068 #ifdef CONFIG_FRAME_POINTER
00069 while (valid_stack_ptr(tinfo, (void *)ebp)) {
00070 addr = *(unsigned long *)(ebp + 4);
00071 _stp_symbol_print (addr);
00072 _stp_print_cstr("\n");
00073 ebp = *(unsigned long *)ebp;
00074 }
00075 #else
00076 while (valid_stack_ptr(tinfo, stack)) {
00077 addr = *stack++;
00078 if (_stp_kta (addr)) {
00079 _stp_symbol_print (addr);
00080 _stp_print_cstr ("\n");
00081 }
00082 }
00083 #endif
00084 _stp_print_flush();
00085 return ebp;
00086 }
00087
00088 static inline unsigned long _stp_sprint_context_stack (
00089 String str,
00090 struct thread_info *tinfo,
00091 unsigned long *stack,
00092 unsigned long ebp )
00093 {
00094 unsigned long addr;
00095
00096 #ifdef CONFIG_FRAME_POINTER
00097 while (valid_stack_ptr(tinfo, (void *)ebp)) {
00098 addr = *(unsigned long *)(ebp + 4);
00099 _stp_symbol_sprint (str, addr);
00100 _stp_string_cat ("\n");
00101 ebp = *(unsigned long *)ebp;
00102 }
00103 #else
00104 while (valid_stack_ptr(tinfo, stack)) {
00105 addr = *stack++;
00106 if (_stp_kta (addr)) {
00107 _stp_symbol_sprint (addr);
00108 _stp_string_cat ("\n");
00109 }
00110 }
00111 #endif
00112 return ebp;
00113 }
00114
00115 static void __stp_stack_print (unsigned long *stack, int verbose, int levels)
00116 {
00117 unsigned long ebp;
00118
00119
00120 asm ("movl %%ebp, %0" : "=r" (ebp) : );
00121
00122 while (stack) {
00123 struct thread_info *context = (struct thread_info *)
00124 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00125 ebp = _stp_print_context_stack (context, stack, ebp);
00126 stack = (unsigned long*)context->previous_esp;
00127 }
00128 }
00129
00130 static void __stp_stack_sprint (String str, unsigned long *stack, int verbose, int levels)
00131 {
00132 unsigned long ebp;
00133
00134
00135 asm ("movl %%ebp, %0" : "=r" (ebp) : );
00136
00137 while (stack) {
00138 struct thread_info *context = (struct thread_info *)
00139 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00140 ebp = _stp_sprint_context_stack (str, context, stack, ebp);
00141 stack = (unsigned long*)context->previous_esp;
00142 }
00143 }
00144
00145 #endif
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 void _stp_stack_print (int verbose, int levels)
00156 {
00157 unsigned long stack;
00158 __stp_stack_print (&stack, verbose, levels);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 String _stp_stack_sprint (String str, int verbose, int levels)
00172 {
00173 unsigned long stack;
00174 __stp_stack_sprint (str, &stack, verbose, levels);
00175 _stp_log ("sss: str=%s\n", str->buf);
00176 return str;
00177 }
00178
00179
00180 #endif