stacktrace.c 2.2 KB
Newer Older
1 2 3 4 5
/*
 * arch/sh/kernel/stacktrace.c
 *
 * Stack trace management functions
 *
P
Paul Mundt 已提交
6
 *  Copyright (C) 2006 - 2008  Paul Mundt
7 8 9 10 11 12 13 14
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/sched.h>
#include <linux/stacktrace.h>
#include <linux/thread_info.h>
15
#include <linux/module.h>
16
#include <asm/unwinder.h>
17
#include <asm/ptrace.h>
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#include <asm/stacktrace.h>

static void save_stack_warning(void *data, char *msg)
{
}

static void
save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
{
}

static int save_stack_stack(void *data, char *name)
{
	return 0;
}
33 34 35 36

/*
 * Save stack-backtrace addresses into a stack_trace buffer.
 */
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
static void save_stack_address(void *data, unsigned long addr, int reliable)
{
	struct stack_trace *trace = data;

	if (trace->skip > 0) {
		trace->skip--;
		return;
	}

	if (trace->nr_entries < trace->max_entries)
		trace->entries[trace->nr_entries++] = addr;
}

static const struct stacktrace_ops save_stack_ops = {
	.warning = save_stack_warning,
	.warning_symbol = save_stack_warning_symbol,
	.stack = save_stack_stack,
	.address = save_stack_address,
};

57
void save_stack_trace(struct stack_trace *trace)
58
{
C
Christoph Hellwig 已提交
59
	unsigned long *sp = (unsigned long *)current_stack_pointer;
60

61
	unwind_stack(current, NULL, sp,  &save_stack_ops, trace);
62
}
63
EXPORT_SYMBOL_GPL(save_stack_trace);
P
Paul Mundt 已提交
64

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
static void
save_stack_address_nosched(void *data, unsigned long addr, int reliable)
{
	struct stack_trace *trace = (struct stack_trace *)data;

	if (in_sched_functions(addr))
		return;

	if (trace->skip > 0) {
		trace->skip--;
		return;
	}

	if (trace->nr_entries < trace->max_entries)
		trace->entries[trace->nr_entries++] = addr;
}

static const struct stacktrace_ops save_stack_ops_nosched = {
	.warning = save_stack_warning,
	.warning_symbol = save_stack_warning_symbol,
	.stack = save_stack_stack,
	.address = save_stack_address_nosched,
};

P
Paul Mundt 已提交
89 90 91 92
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
	unsigned long *sp = (unsigned long *)tsk->thread.sp;

93
	unwind_stack(current, NULL, sp,  &save_stack_ops_nosched, trace);
P
Paul Mundt 已提交
94 95
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);