|
@@ -99,13 +99,14 @@ static inline void preempt_conditional_cli(struct pt_regs *regs)
|
|
int kstack_depth_to_print = 12;
|
|
int kstack_depth_to_print = 12;
|
|
|
|
|
|
#ifdef CONFIG_KALLSYMS
|
|
#ifdef CONFIG_KALLSYMS
|
|
-void printk_address(unsigned long address)
|
|
|
|
|
|
+void printk_address(unsigned long address, int reliable)
|
|
{
|
|
{
|
|
unsigned long offset = 0, symsize;
|
|
unsigned long offset = 0, symsize;
|
|
const char *symname;
|
|
const char *symname;
|
|
char *modname;
|
|
char *modname;
|
|
char *delim = ":";
|
|
char *delim = ":";
|
|
char namebuf[128];
|
|
char namebuf[128];
|
|
|
|
+ char reliab[4] = "";;
|
|
|
|
|
|
symname = kallsyms_lookup(address, &symsize, &offset,
|
|
symname = kallsyms_lookup(address, &symsize, &offset,
|
|
&modname, namebuf);
|
|
&modname, namebuf);
|
|
@@ -113,13 +114,16 @@ void printk_address(unsigned long address)
|
|
printk(" [<%016lx>]\n", address);
|
|
printk(" [<%016lx>]\n", address);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ if (!reliable)
|
|
|
|
+ strcpy(reliab, "? ");
|
|
|
|
+
|
|
if (!modname)
|
|
if (!modname)
|
|
modname = delim = "";
|
|
modname = delim = "";
|
|
- printk(" [<%016lx>] %s%s%s%s+0x%lx/0x%lx\n",
|
|
|
|
- address, delim, modname, delim, symname, offset, symsize);
|
|
|
|
|
|
+ printk(" [<%016lx>] %s%s%s%s%s+0x%lx/0x%lx\n",
|
|
|
|
+ address, reliab, delim, modname, delim, symname, offset, symsize);
|
|
}
|
|
}
|
|
#else
|
|
#else
|
|
-void printk_address(unsigned long address)
|
|
|
|
|
|
+void printk_address(unsigned long address, int reliable)
|
|
{
|
|
{
|
|
printk(" [<%016lx>]\n", address);
|
|
printk(" [<%016lx>]\n", address);
|
|
}
|
|
}
|
|
@@ -215,7 +219,7 @@ static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
|
|
}
|
|
}
|
|
|
|
|
|
void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
|
|
void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
|
|
- unsigned long *stack,
|
|
|
|
|
|
+ unsigned long *stack, unsigned long bp,
|
|
const struct stacktrace_ops *ops, void *data)
|
|
const struct stacktrace_ops *ops, void *data)
|
|
{
|
|
{
|
|
const unsigned cpu = get_cpu();
|
|
const unsigned cpu = get_cpu();
|
|
@@ -252,7 +256,7 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
|
|
* down the cause of the crash will be able to figure \
|
|
* down the cause of the crash will be able to figure \
|
|
* out the call path that was taken. \
|
|
* out the call path that was taken. \
|
|
*/ \
|
|
*/ \
|
|
- ops->address(data, addr); \
|
|
|
|
|
|
+ ops->address(data, addr, 1); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
} while (0)
|
|
|
|
|
|
@@ -331,10 +335,10 @@ static int print_trace_stack(void *data, char *name)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static void print_trace_address(void *data, unsigned long addr)
|
|
|
|
|
|
+static void print_trace_address(void *data, unsigned long addr, int reliable)
|
|
{
|
|
{
|
|
touch_nmi_watchdog();
|
|
touch_nmi_watchdog();
|
|
- printk_address(addr);
|
|
|
|
|
|
+ printk_address(addr, reliable);
|
|
}
|
|
}
|
|
|
|
|
|
static const struct stacktrace_ops print_trace_ops = {
|
|
static const struct stacktrace_ops print_trace_ops = {
|
|
@@ -345,15 +349,17 @@ static const struct stacktrace_ops print_trace_ops = {
|
|
};
|
|
};
|
|
|
|
|
|
void
|
|
void
|
|
-show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack)
|
|
|
|
|
|
+show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack,
|
|
|
|
+ unsigned long bp)
|
|
{
|
|
{
|
|
printk("\nCall Trace:\n");
|
|
printk("\nCall Trace:\n");
|
|
- dump_trace(tsk, regs, stack, &print_trace_ops, NULL);
|
|
|
|
|
|
+ dump_trace(tsk, regs, stack, bp, &print_trace_ops, NULL);
|
|
printk("\n");
|
|
printk("\n");
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
static void
|
|
-_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp)
|
|
|
|
|
|
+_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp,
|
|
|
|
+ unsigned long bp)
|
|
{
|
|
{
|
|
unsigned long *stack;
|
|
unsigned long *stack;
|
|
int i;
|
|
int i;
|
|
@@ -387,12 +393,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp)
|
|
printk(" %016lx", *stack++);
|
|
printk(" %016lx", *stack++);
|
|
touch_nmi_watchdog();
|
|
touch_nmi_watchdog();
|
|
}
|
|
}
|
|
- show_trace(tsk, regs, sp);
|
|
|
|
|
|
+ show_trace(tsk, regs, sp, bp);
|
|
}
|
|
}
|
|
|
|
|
|
void show_stack(struct task_struct *tsk, unsigned long * sp)
|
|
void show_stack(struct task_struct *tsk, unsigned long * sp)
|
|
{
|
|
{
|
|
- _show_stack(tsk, NULL, sp);
|
|
|
|
|
|
+ _show_stack(tsk, NULL, sp, 0);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -401,13 +407,14 @@ void show_stack(struct task_struct *tsk, unsigned long * sp)
|
|
void dump_stack(void)
|
|
void dump_stack(void)
|
|
{
|
|
{
|
|
unsigned long dummy;
|
|
unsigned long dummy;
|
|
|
|
+ unsigned long bp = 0;
|
|
|
|
|
|
printk("Pid: %d, comm: %.20s %s %s %.*s\n",
|
|
printk("Pid: %d, comm: %.20s %s %s %.*s\n",
|
|
current->pid, current->comm, print_tainted(),
|
|
current->pid, current->comm, print_tainted(),
|
|
init_utsname()->release,
|
|
init_utsname()->release,
|
|
(int)strcspn(init_utsname()->version, " "),
|
|
(int)strcspn(init_utsname()->version, " "),
|
|
init_utsname()->version);
|
|
init_utsname()->version);
|
|
- show_trace(NULL, NULL, &dummy);
|
|
|
|
|
|
+ show_trace(NULL, NULL, &dummy, bp);
|
|
}
|
|
}
|
|
|
|
|
|
EXPORT_SYMBOL(dump_stack);
|
|
EXPORT_SYMBOL(dump_stack);
|
|
@@ -432,7 +439,7 @@ void show_registers(struct pt_regs *regs)
|
|
*/
|
|
*/
|
|
if (in_kernel) {
|
|
if (in_kernel) {
|
|
printk("Stack: ");
|
|
printk("Stack: ");
|
|
- _show_stack(NULL, regs, (unsigned long*)sp);
|
|
|
|
|
|
+ _show_stack(NULL, regs, (unsigned long *)sp, regs->bp);
|
|
|
|
|
|
printk("\nCode: ");
|
|
printk("\nCode: ");
|
|
if (regs->ip < PAGE_OFFSET)
|
|
if (regs->ip < PAGE_OFFSET)
|
|
@@ -527,7 +534,7 @@ int __kprobes __die(const char * str, struct pt_regs * regs, long err)
|
|
add_taint(TAINT_DIE);
|
|
add_taint(TAINT_DIE);
|
|
/* Executive summary in case the oops scrolled away */
|
|
/* Executive summary in case the oops scrolled away */
|
|
printk(KERN_ALERT "RIP ");
|
|
printk(KERN_ALERT "RIP ");
|
|
- printk_address(regs->ip);
|
|
|
|
|
|
+ printk_address(regs->ip, regs->bp);
|
|
printk(" RSP <%016lx>\n", regs->sp);
|
|
printk(" RSP <%016lx>\n", regs->sp);
|
|
if (kexec_should_crash(current))
|
|
if (kexec_should_crash(current))
|
|
crash_kexec(regs);
|
|
crash_kexec(regs);
|