-
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.
[ARM] Add stacktrace support and make oprofile use it
Add support for stacktrace. Use the new stacktrace code with oprofile instead of it's version; there's no point having multiple versions of stacktracing in the kernel. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
- Loading branch information
Russell King
authored and
Russell King
committed
Apr 28, 2007
1 parent
ed519de
commit f16fb1e
Showing
5 changed files
with
109 additions
and
54 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
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,73 @@ | ||
#include <linux/sched.h> | ||
#include <linux/stacktrace.h> | ||
|
||
#include "stacktrace.h" | ||
|
||
int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, | ||
int (*fn)(struct stackframe *, void *), void *data) | ||
{ | ||
struct stackframe *frame; | ||
|
||
do { | ||
/* | ||
* Check current frame pointer is within bounds | ||
*/ | ||
if ((fp - 12) < low || fp + 4 >= high) | ||
break; | ||
|
||
frame = (struct stackframe *)(fp - 12); | ||
|
||
if (fn(frame, data)) | ||
break; | ||
|
||
/* | ||
* Update the low bound - the next frame must always | ||
* be at a higher address than the current frame. | ||
*/ | ||
low = fp + 4; | ||
fp = frame->fp; | ||
} while (fp); | ||
|
||
return 0; | ||
} | ||
|
||
#ifdef CONFIG_STACKTRACE | ||
struct stack_trace_data { | ||
struct stack_trace *trace; | ||
unsigned int skip; | ||
}; | ||
|
||
static int save_trace(struct stackframe *frame, void *d) | ||
{ | ||
struct stack_trace_data *data = d; | ||
struct stack_trace *trace = data->trace; | ||
|
||
if (data->skip) { | ||
data->skip--; | ||
return 0; | ||
} | ||
|
||
trace->entries[trace->nr_entries++] = frame->lr; | ||
|
||
return trace->nr_entries >= trace->max_entries; | ||
} | ||
|
||
void save_stack_trace(struct stack_trace *trace, struct task_struct *task) | ||
{ | ||
struct stack_trace_data data; | ||
unsigned long fp, base; | ||
|
||
data.trace = trace; | ||
data.skip = trace->skip; | ||
|
||
if (task) { | ||
base = (unsigned long)task_stack_page(task); | ||
fp = 0; /* FIXME */ | ||
} else { | ||
base = (unsigned long)task_stack_page(current); | ||
asm("mov %0, fp" : "=r" (fp)); | ||
} | ||
|
||
walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data); | ||
} | ||
#endif |
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,9 @@ | ||
struct stackframe { | ||
unsigned long fp; | ||
unsigned long sp; | ||
unsigned long lr; | ||
unsigned long pc; | ||
}; | ||
|
||
int walk_stackframe(unsigned long fp, unsigned long low, unsigned long high, | ||
int (*fn)(struct stackframe *, void *), void *data); |
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