unwind_frame.c (8023e0e2a48d45e8d5363081fad9f7ed4402f953) | unwind_frame.c (8b5e99f02264130782a10ba5c0c759797fb064ee) |
---|---|
1#include <linux/sched.h> 2#include <asm/ptrace.h> 3#include <asm/bitops.h> 4#include <asm/stacktrace.h> 5#include <asm/unwind.h> 6 7#define FRAME_HEADER_SIZE (sizeof(long) * 2) 8 | 1#include <linux/sched.h> 2#include <asm/ptrace.h> 3#include <asm/bitops.h> 4#include <asm/stacktrace.h> 5#include <asm/unwind.h> 6 7#define FRAME_HEADER_SIZE (sizeof(long) * 2) 8 |
9static void unwind_dump(struct unwind_state *state, unsigned long *sp) 10{ 11 static bool dumped_before = false; 12 bool prev_zero, zero = false; 13 unsigned long word; 14 15 if (dumped_before) 16 return; 17 18 dumped_before = true; 19 20 printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n", 21 state->stack_info.type, state->stack_info.next_sp, 22 state->stack_mask, state->graph_idx); 23 24 for (sp = state->orig_sp; sp < state->stack_info.end; sp++) { 25 word = READ_ONCE_NOCHECK(*sp); 26 27 prev_zero = zero; 28 zero = word == 0; 29 30 if (zero) { 31 if (!prev_zero) 32 printk_deferred("%p: %016x ...\n", sp, 0); 33 continue; 34 } 35 36 printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word); 37 } 38} 39 |
|
9unsigned long unwind_get_return_address(struct unwind_state *state) 10{ 11 unsigned long addr; 12 unsigned long *addr_p = unwind_get_return_address_ptr(state); 13 14 if (unwind_done(state)) 15 return 0; 16 17 if (state->regs && user_mode(state->regs)) 18 return 0; 19 20 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p, 21 addr_p); 22 23 if (!__kernel_text_address(addr)) { 24 printk_deferred_once(KERN_WARNING 25 "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n", 26 (void *)addr, addr_p, state->task->comm, 27 state->task->pid); | 40unsigned long unwind_get_return_address(struct unwind_state *state) 41{ 42 unsigned long addr; 43 unsigned long *addr_p = unwind_get_return_address_ptr(state); 44 45 if (unwind_done(state)) 46 return 0; 47 48 if (state->regs && user_mode(state->regs)) 49 return 0; 50 51 addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p, 52 addr_p); 53 54 if (!__kernel_text_address(addr)) { 55 printk_deferred_once(KERN_WARNING 56 "WARNING: unrecognized kernel stack return address %p at %p in %s:%d\n", 57 (void *)addr, addr_p, state->task->comm, 58 state->task->pid); |
59 unwind_dump(state, addr_p); |
|
28 return 0; 29 } 30 31 return addr; 32} 33EXPORT_SYMBOL_GPL(unwind_get_return_address); 34 35static size_t regs_size(struct pt_regs *regs) --- 33 unchanged lines hidden (view full) --- 69 70 return (struct pt_regs *)(regs & ~0x1); 71} 72 73static bool update_stack_state(struct unwind_state *state, void *addr, 74 size_t len) 75{ 76 struct stack_info *info = &state->stack_info; | 60 return 0; 61 } 62 63 return addr; 64} 65EXPORT_SYMBOL_GPL(unwind_get_return_address); 66 67static size_t regs_size(struct pt_regs *regs) --- 33 unchanged lines hidden (view full) --- 101 102 return (struct pt_regs *)(regs & ~0x1); 103} 104 105static bool update_stack_state(struct unwind_state *state, void *addr, 106 size_t len) 107{ 108 struct stack_info *info = &state->stack_info; |
109 enum stack_type orig_type = info->type; |
|
77 78 /* 79 * If addr isn't on the current stack, switch to the next one. 80 * 81 * We may have to traverse multiple stacks to deal with the possibility 82 * that 'info->next_sp' could point to an empty stack and 'addr' could 83 * be on a subsequent stack. 84 */ 85 while (!on_stack(info, addr, len)) 86 if (get_stack_info(info->next_sp, state->task, info, 87 &state->stack_mask)) 88 return false; 89 | 110 111 /* 112 * If addr isn't on the current stack, switch to the next one. 113 * 114 * We may have to traverse multiple stacks to deal with the possibility 115 * that 'info->next_sp' could point to an empty stack and 'addr' could 116 * be on a subsequent stack. 117 */ 118 while (!on_stack(info, addr, len)) 119 if (get_stack_info(info->next_sp, state->task, info, 120 &state->stack_mask)) 121 return false; 122 |
123 if (!state->orig_sp || info->type != orig_type) 124 state->orig_sp = addr; 125 |
|
90 return true; 91} 92 93bool unwind_next_frame(struct unwind_state *state) 94{ 95 struct pt_regs *regs; 96 unsigned long *next_bp, *next_frame; 97 size_t next_len; --- 82 unchanged lines hidden (view full) --- 180 return true; 181 182bad_address: 183 if (state->regs) { 184 printk_deferred_once(KERN_WARNING 185 "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", 186 state->regs, state->task->comm, 187 state->task->pid, next_frame); | 126 return true; 127} 128 129bool unwind_next_frame(struct unwind_state *state) 130{ 131 struct pt_regs *regs; 132 unsigned long *next_bp, *next_frame; 133 size_t next_len; --- 82 unchanged lines hidden (view full) --- 216 return true; 217 218bad_address: 219 if (state->regs) { 220 printk_deferred_once(KERN_WARNING 221 "WARNING: kernel stack regs at %p in %s:%d has bad 'bp' value %p\n", 222 state->regs, state->task->comm, 223 state->task->pid, next_frame); |
224 unwind_dump(state, (unsigned long *)state->regs); |
|
188 } else { 189 printk_deferred_once(KERN_WARNING 190 "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n", 191 state->bp, state->task->comm, 192 state->task->pid, next_frame); | 225 } else { 226 printk_deferred_once(KERN_WARNING 227 "WARNING: kernel stack frame pointer at %p in %s:%d has bad value %p\n", 228 state->bp, state->task->comm, 229 state->task->pid, next_frame); |
230 unwind_dump(state, state->bp); |
|
193 } 194the_end: 195 state->stack_info.type = STACK_TYPE_UNKNOWN; 196 return false; 197} 198EXPORT_SYMBOL_GPL(unwind_next_frame); 199 200void __unwind_start(struct unwind_state *state, struct task_struct *task, --- 43 unchanged lines hidden --- | 231 } 232the_end: 233 state->stack_info.type = STACK_TYPE_UNKNOWN; 234 return false; 235} 236EXPORT_SYMBOL_GPL(unwind_next_frame); 237 238void __unwind_start(struct unwind_state *state, struct task_struct *task, --- 43 unchanged lines hidden --- |