Changeset 5203efb1 in mainline for kernel/arch/mips32/src/debug/stacktrace.c
- Timestamp:
- 2010-09-12T07:56:18Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 553f430, dc94cb2
- Parents:
- 2fa10f6 (diff), 76e1121f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/mips32/src/debug/stacktrace.c
r2fa10f6 r5203efb1 31 31 */ 32 32 /** @file 33 */ 34 35 /* 36 * This stack tracing code is based on the suggested algorithm described on page 37 * 3-27 and 3-28 of: 38 * 39 * SYSTEM V 40 * APPLICATION BINARY INTERFACE 41 * 42 * MIPS RISC Processor 43 * Supplement 44 * 3rd Edition 45 * 46 * Unfortunately, GCC generates code which is not entirely compliant with this 47 * method. For example, it places the "jr ra" instruction quite arbitrarily in 48 * the middle of the function which makes the original algorithm unapplicable. 49 * 50 * We deal with this problem by simply not using those parts of the algorithm 51 * that rely on the "jr ra" instruction occurring in the last basic block of a 52 * function, which gives us still usable, but less reliable stack tracer. The 53 * unreliability stems from the fact that under some circumstances it can become 54 * confused and produce incorrect or incomplete stack trace. We apply extra 55 * sanity checks so that the algorithm is still safe and should not crash the 56 * system. 57 * 58 * Even though not perfect, our solution is pretty lightweight, especially when 59 * compared with a prospective alternative solution based on additional 60 * debugging information stored directly in the kernel image. 33 61 */ 34 62 … … 96 124 extern char ktext_end; 97 125 126 static bool bounds_check(uintptr_t pc) 127 { 128 return (pc >= (uintptr_t) &ktext_start) && 129 (pc < (uintptr_t) &ktext_end); 130 } 131 98 132 static bool 99 133 scan(stack_trace_context_t *ctx, uintptr_t *prev_fp, uintptr_t *prev_ra) … … 106 140 do { 107 141 inst--; 142 if (!bounds_check((uintptr_t) inst)) 143 return false; 108 144 #if 0 109 145 /* … … 180 216 return false; 181 217 /* too big offsets are suspicious */ 182 if ( offset > 32 * 4)218 if ((size_t) offset > sizeof(istate_t)) 183 219 return false; 184 220 … … 207 243 { 208 244 return !((ctx->fp == 0) || ((ctx->fp % 8) != 0) || 209 (ctx->pc % 4 != 0) || (ctx->pc < (uintptr_t) &ktext_start) || 210 (ctx->pc >= (uintptr_t) &ktext_end)); 245 (ctx->pc % 4 != 0) || !bounds_check(ctx->pc)); 211 246 } 212 247
Note:
See TracChangeset
for help on using the changeset viewer.