-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sh: Use the generalized stacktrace ops
Copy the stacktrace ops code from x86 and provide a central function for use by functions that need to dump a callstack. Signed-off-by: Matt Fleming <matt@console-pimps.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
- Loading branch information
Matt Fleming
authored and
Paul Mundt
committed
Aug 13, 2009
1 parent
922b0dc
commit 4e14dfc
Showing
6 changed files
with
251 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* Copyright (C) 2009 Matt Fleming | ||
* | ||
* Based on: | ||
* The x86 implementation - arch/x86/include/asm/stacktrace.h | ||
*/ | ||
#ifndef _ASM_SH_STACKTRACE_H | ||
#define _ASM_SH_STACKTRACE_H | ||
|
||
/* Generic stack tracer with callbacks */ | ||
|
||
struct stacktrace_ops { | ||
void (*warning)(void *data, char *msg); | ||
/* msg must contain %s for the symbol */ | ||
void (*warning_symbol)(void *data, char *msg, unsigned long symbol); | ||
void (*address)(void *data, unsigned long address, int reliable); | ||
/* On negative return stop dumping */ | ||
int (*stack)(void *data, char *name); | ||
}; | ||
|
||
void dump_trace(struct task_struct *tsk, struct pt_regs *regs, | ||
unsigned long *stack, | ||
const struct stacktrace_ops *ops, void *data); | ||
|
||
#endif /* _ASM_SH_STACKTRACE_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* | ||
* Copyright (C) 1991, 1992 Linus Torvalds | ||
* Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs | ||
* Copyright (C) 2009 Matt Fleming | ||
*/ | ||
#include <linux/kallsyms.h> | ||
#include <linux/ftrace.h> | ||
#include <linux/debug_locks.h> | ||
|
||
#include <asm/stacktrace.h> | ||
|
||
void printk_address(unsigned long address, int reliable) | ||
{ | ||
printk(" [<%p>] %s%pS\n", (void *) address, | ||
reliable ? "" : "? ", (void *) address); | ||
} | ||
|
||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
static void | ||
print_ftrace_graph_addr(unsigned long addr, void *data, | ||
const struct stacktrace_ops *ops, | ||
struct thread_info *tinfo, int *graph) | ||
{ | ||
struct task_struct *task = tinfo->task; | ||
unsigned long ret_addr; | ||
int index = task->curr_ret_stack; | ||
|
||
if (addr != (unsigned long)return_to_handler) | ||
return; | ||
|
||
if (!task->ret_stack || index < *graph) | ||
return; | ||
|
||
index -= *graph; | ||
ret_addr = task->ret_stack[index].ret; | ||
|
||
ops->address(data, ret_addr, 1); | ||
|
||
(*graph)++; | ||
} | ||
#else | ||
static inline void | ||
print_ftrace_graph_addr(unsigned long addr, void *data, | ||
const struct stacktrace_ops *ops, | ||
struct thread_info *tinfo, int *graph) | ||
{ } | ||
#endif | ||
|
||
/* | ||
* Unwind the call stack and pass information to the stacktrace_ops | ||
* functions. | ||
*/ | ||
void dump_trace(struct task_struct *task, struct pt_regs *regs, | ||
unsigned long *sp, const struct stacktrace_ops *ops, | ||
void *data) | ||
{ | ||
struct thread_info *context; | ||
int graph = 0; | ||
|
||
context = (struct thread_info *) | ||
((unsigned long)sp & (~(THREAD_SIZE - 1))); | ||
|
||
while (!kstack_end(sp)) { | ||
unsigned long addr = *sp++; | ||
|
||
if (__kernel_text_address(addr)) { | ||
ops->address(data, addr, 0); | ||
|
||
print_ftrace_graph_addr(addr, data, ops, | ||
context, &graph); | ||
} | ||
} | ||
} | ||
EXPORT_SYMBOL(dump_trace); | ||
|
||
|
||
static void | ||
print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) | ||
{ | ||
printk(data); | ||
print_symbol(msg, symbol); | ||
printk("\n"); | ||
} | ||
|
||
static void print_trace_warning(void *data, char *msg) | ||
{ | ||
printk("%s%s\n", (char *)data, msg); | ||
} | ||
|
||
static int print_trace_stack(void *data, char *name) | ||
{ | ||
printk("%s <%s> ", (char *)data, name); | ||
return 0; | ||
} | ||
|
||
/* | ||
* Print one address/symbol entries per line. | ||
*/ | ||
static void print_trace_address(void *data, unsigned long addr, int reliable) | ||
{ | ||
printk(data); | ||
printk_address(addr, reliable); | ||
} | ||
|
||
static const struct stacktrace_ops print_trace_ops = { | ||
.warning = print_trace_warning, | ||
.warning_symbol = print_trace_warning_symbol, | ||
.stack = print_trace_stack, | ||
.address = print_trace_address, | ||
}; | ||
|
||
void show_trace(struct task_struct *tsk, unsigned long *sp, | ||
struct pt_regs *regs) | ||
{ | ||
if (regs && user_mode(regs)) | ||
return; | ||
|
||
printk("\nCall trace:\n"); | ||
|
||
dump_trace(tsk, regs, sp, &print_trace_ops, ""); | ||
|
||
printk("\n"); | ||
|
||
if (!tsk) | ||
tsk = current; | ||
|
||
debug_show_held_locks(tsk); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters