stacktrace.c (7a9787e1eba95a166265e6a260cf30af04ef0a99) | stacktrace.c (2ec220e27f5040aec1e88901c1b6ea3d135787ad) |
---|---|
1/* 2 * arch/mips/kernel/stacktrace.c 3 * 4 * Stack trace management functions 5 * 6 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> 7 */ 8#include <linux/sched.h> --- 18 unchanged lines hidden (view full) --- 27 else 28 trace->entries[trace->nr_entries++] = addr; 29 if (trace->nr_entries >= trace->max_entries) 30 break; 31 } 32 } 33} 34 | 1/* 2 * arch/mips/kernel/stacktrace.c 3 * 4 * Stack trace management functions 5 * 6 * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> 7 */ 8#include <linux/sched.h> --- 18 unchanged lines hidden (view full) --- 27 else 28 trace->entries[trace->nr_entries++] = addr; 29 if (trace->nr_entries >= trace->max_entries) 30 break; 31 } 32 } 33} 34 |
35static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs) | 35static void save_context_stack(struct stack_trace *trace, 36 struct task_struct *tsk, struct pt_regs *regs) |
36{ 37 unsigned long sp = regs->regs[29]; 38#ifdef CONFIG_KALLSYMS 39 unsigned long ra = regs->regs[31]; 40 unsigned long pc = regs->cp0_epc; 41 42 if (raw_show_trace || !__kernel_text_address(pc)) { 43 unsigned long stack_page = | 37{ 38 unsigned long sp = regs->regs[29]; 39#ifdef CONFIG_KALLSYMS 40 unsigned long ra = regs->regs[31]; 41 unsigned long pc = regs->cp0_epc; 42 43 if (raw_show_trace || !__kernel_text_address(pc)) { 44 unsigned long stack_page = |
44 (unsigned long)task_stack_page(current); | 45 (unsigned long)task_stack_page(tsk); |
45 if (stack_page && sp >= stack_page && 46 sp <= stack_page + THREAD_SIZE - 32) 47 save_raw_context_stack(trace, sp); 48 return; 49 } 50 do { 51 if (trace->skip > 0) 52 trace->skip--; 53 else 54 trace->entries[trace->nr_entries++] = pc; 55 if (trace->nr_entries >= trace->max_entries) 56 break; | 46 if (stack_page && sp >= stack_page && 47 sp <= stack_page + THREAD_SIZE - 32) 48 save_raw_context_stack(trace, sp); 49 return; 50 } 51 do { 52 if (trace->skip > 0) 53 trace->skip--; 54 else 55 trace->entries[trace->nr_entries++] = pc; 56 if (trace->nr_entries >= trace->max_entries) 57 break; |
57 pc = unwind_stack(current, &sp, pc, &ra); | 58 pc = unwind_stack(tsk, &sp, pc, &ra); |
58 } while (pc); 59#else 60 save_raw_context_stack(trace, sp); 61#endif 62} 63 64/* 65 * Save stack-backtrace addresses into a stack_trace buffer. 66 */ 67void save_stack_trace(struct stack_trace *trace) 68{ | 59 } while (pc); 60#else 61 save_raw_context_stack(trace, sp); 62#endif 63} 64 65/* 66 * Save stack-backtrace addresses into a stack_trace buffer. 67 */ 68void save_stack_trace(struct stack_trace *trace) 69{ |
70 save_stack_trace_tsk(current, trace); 71} 72EXPORT_SYMBOL_GPL(save_stack_trace); 73 74void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) 75{ |
|
69 struct pt_regs dummyregs; 70 struct pt_regs *regs = &dummyregs; 71 72 WARN_ON(trace->nr_entries || !trace->max_entries); 73 | 76 struct pt_regs dummyregs; 77 struct pt_regs *regs = &dummyregs; 78 79 WARN_ON(trace->nr_entries || !trace->max_entries); 80 |
74 prepare_frametrace(regs); 75 save_context_stack(trace, regs); | 81 if (tsk != current) { 82 regs->regs[29] = tsk->thread.reg29; 83 regs->regs[31] = 0; 84 regs->cp0_epc = tsk->thread.reg31; 85 } else 86 prepare_frametrace(regs); 87 save_context_stack(trace, tsk, regs); |
76} | 88} |
77EXPORT_SYMBOL_GPL(save_stack_trace); | 89EXPORT_SYMBOL_GPL(save_stack_trace_tsk); |