static unsigned long walk_stack(struct thread_info *tinfo, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; while (valid_stack_ptr(tinfo, stack, sizeof(*stack), end)) { unsigned long addr; addr = *stack; if (is_kernel_text(addr)) { if ((unsigned long) stack == bp + sizeof(long)) { ops->address(data, addr, 1); frame = frame->next_frame; bp = (unsigned long) frame; } else { ops->address(data, addr, 0); } } stack++; } return bp; }
unsigned long print_context_stack(struct task_struct *task, void *stack_start, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; while (valid_stack_ptr(stack_start, stack, sizeof(*stack), end)) { unsigned long addr; addr = *stack; if (__kernel_text_address(addr)) { if ((unsigned long) stack == bp + sizeof(long)) { ops->address(data, addr, 1); frame = frame->next_frame; bp = (unsigned long) frame; } else { ops->address(data, addr, 0); } print_ftrace_graph_addr(addr, data, ops, task, graph); } stack++; } return bp; }
unsigned long print_context_stack_bp(struct task_struct *task, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; unsigned long *retp = &frame->return_address; while (valid_stack_ptr(task, retp, sizeof(*retp), end)) { unsigned long addr = *retp; unsigned long real_addr; if (!__kernel_text_address(addr)) break; real_addr = ftrace_graph_ret_addr(task, graph, addr, retp); if (ops->address(data, real_addr, 1)) break; frame = frame->next_frame; retp = &frame->return_address; } return (unsigned long)frame; }
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth) { /* Get first frame pointer */ struct frame_head *head = (struct frame_head *)(regs->r7); if (!user_mode(regs)) { #ifdef CONFIG_FRAME_POINTER /* * Traverse the kernel stack from frame to frame up to * "depth" steps. */ while (depth-- && valid_stack_ptr(task_thread_info(current), (unsigned long)head)) { oprofile_add_trace(head->lr); if (head->fp <= head) break; head = head->fp; } #endif } else { /* Assume we have frame pointers in user mode process */ while (depth-- && head) head = dump_user_backtrace(head); } }
unsigned long print_context_stack(struct task_struct *task, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; /* * If we overflowed the stack into a guard page, jump back to the * bottom of the usable stack. */ if ((unsigned long)task_stack_page(task) - (unsigned long)stack < PAGE_SIZE) stack = (unsigned long *)task_stack_page(task); while (valid_stack_ptr(task, stack, sizeof(*stack), end)) { unsigned long addr = *stack; if (__kernel_text_address(addr)) { unsigned long real_addr; int reliable = 0; if ((unsigned long) stack == bp + sizeof(long)) { reliable = 1; frame = frame->next_frame; bp = (unsigned long) frame; } /* * When function graph tracing is enabled for a * function, its return address on the stack is * replaced with the address of an ftrace handler * (return_to_handler). In that case, before printing * the "real" address, we want to print the handler * address as an "unreliable" hint that function graph * tracing was involved. */ real_addr = ftrace_graph_ret_addr(task, graph, addr, stack); if (real_addr != addr) ops->address(data, addr, 0); ops->address(data, real_addr, reliable); } stack++; } return bp; }
void show_trace(struct task_struct *task, unsigned long *stack) { struct thread_info *context; unsigned long addr; context = (struct thread_info *) ((unsigned long)stack & (~(THREAD_SIZE - 1))); while (valid_stack_ptr(context, stack)) { addr = *stack++; if (__kernel_text_address(addr)) { printk(" [<%08lx>]", addr); print_symbol(" %s", addr); printk("\n"); } } printk(" =======================\n"); }
unsigned long print_context_stack_bp(struct thread_info *tinfo, unsigned long *stack, unsigned long bp, const struct stacktrace_ops *ops, void *data, unsigned long *end, int *graph) { struct stack_frame *frame = (struct stack_frame *)bp; unsigned long *ret_addr = &frame->return_address; while (valid_stack_ptr(tinfo, ret_addr, sizeof(*ret_addr), end)) { unsigned long addr = *ret_addr; if (__kernel_text_address(addr)) { ops->address(data, addr, 1); frame = frame->next_frame; ret_addr = &frame->return_address; print_ftrace_graph_addr(addr, data, ops, tinfo, graph); } } return (unsigned long)frame; }
void avr32_backtrace(struct pt_regs * const regs, unsigned int depth) { struct frame_head *head = (struct frame_head *)(regs->r7); if (!user_mode(regs)) { #ifdef CONFIG_FRAME_POINTER while (depth-- && valid_stack_ptr(task_thread_info(current), (unsigned long)head)) { oprofile_add_trace(head->lr); if (head->fp <= head) break; head = head->fp; } #endif } else { while (depth-- && head) head = dump_user_backtrace(head); } }