mirror of https://gitee.com/openkylin/linux.git
Merge branch 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core/stacktrace' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: generic-ipi: powerpc/generic-ipi tree build failure stacktrace: fix build failure on sparc64 stacktrace: export save_stack_trace[_tsk] stacktrace: fix modular build, export print_stack_trace and save_stack_trace backtrace: replace timer with tasklet + completions stacktrace: add saved stack traces to backtrace self-test stacktrace: print_stack_trace() cleanup debugging: make stacktrace independent from DEBUG_KERNEL stacktrace: don't crash on invalid stack trace structs
This commit is contained in:
commit
af5329cdf5
|
@ -92,4 +92,5 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
{
|
||||
save_stack_trace_tsk(current, trace);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
#endif
|
||||
|
|
|
@ -51,3 +51,4 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
fp = frame->fp;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
|
|
@ -73,3 +73,4 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
prepare_frametrace(regs);
|
||||
save_context_stack(trace, regs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
||||
/*
|
||||
|
@ -44,3 +45,4 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
sp = newsp;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
|
|
@ -81,6 +81,7 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
S390_lowcore.thread_info,
|
||||
S390_lowcore.thread_info + THREAD_SIZE, 1);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
||||
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
||||
{
|
||||
|
@ -93,3 +94,4 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|||
if (trace->nr_entries < trace->max_entries)
|
||||
trace->entries[trace->nr_entries++] = ULONG_MAX;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
|
||||
|
|
|
@ -34,3 +34,4 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
|
@ -47,3 +48,4 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
trace->entries[trace->nr_entries++] = pc;
|
||||
} while (trace->nr_entries < trace->max_entries);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
|
|
@ -74,6 +74,7 @@ void save_stack_trace(struct stack_trace *trace)
|
|||
if (trace->nr_entries < trace->max_entries)
|
||||
trace->entries[trace->nr_entries++] = ULONG_MAX;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace);
|
||||
|
||||
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
||||
{
|
||||
|
@ -81,3 +82,4 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
|
|||
if (trace->nr_entries < trace->max_entries)
|
||||
trace->entries[trace->nr_entries++] = ULONG_MAX;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
|
||||
|
|
|
@ -10,30 +10,73 @@
|
|||
* of the License.
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/stacktrace.h>
|
||||
|
||||
static struct timer_list backtrace_timer;
|
||||
static void backtrace_test_normal(void)
|
||||
{
|
||||
printk("Testing a backtrace from process context.\n");
|
||||
printk("The following trace is a kernel self test and not a bug!\n");
|
||||
|
||||
static void backtrace_test_timer(unsigned long data)
|
||||
dump_stack();
|
||||
}
|
||||
|
||||
static DECLARE_COMPLETION(backtrace_work);
|
||||
|
||||
static void backtrace_test_irq_callback(unsigned long data)
|
||||
{
|
||||
dump_stack();
|
||||
complete(&backtrace_work);
|
||||
}
|
||||
|
||||
static DECLARE_TASKLET(backtrace_tasklet, &backtrace_test_irq_callback, 0);
|
||||
|
||||
static void backtrace_test_irq(void)
|
||||
{
|
||||
printk("Testing a backtrace from irq context.\n");
|
||||
printk("The following trace is a kernel self test and not a bug!\n");
|
||||
dump_stack();
|
||||
|
||||
init_completion(&backtrace_work);
|
||||
tasklet_schedule(&backtrace_tasklet);
|
||||
wait_for_completion(&backtrace_work);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_STACKTRACE
|
||||
static void backtrace_test_saved(void)
|
||||
{
|
||||
struct stack_trace trace;
|
||||
unsigned long entries[8];
|
||||
|
||||
printk("Testing a saved backtrace.\n");
|
||||
printk("The following trace is a kernel self test and not a bug!\n");
|
||||
|
||||
trace.nr_entries = 0;
|
||||
trace.max_entries = ARRAY_SIZE(entries);
|
||||
trace.entries = entries;
|
||||
trace.skip = 0;
|
||||
|
||||
save_stack_trace(&trace);
|
||||
print_stack_trace(&trace, 0);
|
||||
}
|
||||
#else
|
||||
static void backtrace_test_saved(void)
|
||||
{
|
||||
printk("Saved backtrace test skipped.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static int backtrace_regression_test(void)
|
||||
{
|
||||
printk("====[ backtrace testing ]===========\n");
|
||||
printk("Testing a backtrace from process context.\n");
|
||||
printk("The following trace is a kernel self test and not a bug!\n");
|
||||
dump_stack();
|
||||
|
||||
init_timer(&backtrace_timer);
|
||||
backtrace_timer.function = backtrace_test_timer;
|
||||
mod_timer(&backtrace_timer, jiffies + 10);
|
||||
backtrace_test_normal();
|
||||
backtrace_test_irq();
|
||||
backtrace_test_saved();
|
||||
|
||||
msleep(10);
|
||||
printk("====[ end of backtrace testing ]====\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -6,19 +6,21 @@
|
|||
* Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
||||
*/
|
||||
#include <linux/sched.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/stacktrace.h>
|
||||
|
||||
void print_stack_trace(struct stack_trace *trace, int spaces)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (WARN_ON(!trace->entries))
|
||||
return;
|
||||
|
||||
for (i = 0; i < trace->nr_entries; i++) {
|
||||
unsigned long ip = trace->entries[i];
|
||||
|
||||
for (j = 0; j < spaces + 1; j++)
|
||||
printk(" ");
|
||||
print_ip_sym(ip);
|
||||
printk("%*c", 1 + spaces, ' ');
|
||||
print_ip_sym(trace->entries[i]);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(print_stack_trace);
|
||||
|
||||
|
|
|
@ -419,7 +419,6 @@ config DEBUG_LOCKING_API_SELFTESTS
|
|||
|
||||
config STACKTRACE
|
||||
bool
|
||||
depends on DEBUG_KERNEL
|
||||
depends on STACKTRACE_SUPPORT
|
||||
|
||||
config DEBUG_KOBJECT
|
||||
|
@ -563,6 +562,9 @@ config BACKTRACE_SELF_TEST
|
|||
for distributions or general kernels, but only for kernel
|
||||
developers working on architecture code.
|
||||
|
||||
Note that if you want to also test saved backtraces, you will
|
||||
have to enable STACKTRACE as well.
|
||||
|
||||
Say N if you are unsure.
|
||||
|
||||
config LKDTM
|
||||
|
|
Loading…
Reference in New Issue