static int kstack_depth_to_print = 24;
-void show_stack(unsigned long *sp)
+void show_stack(struct task_struct *task, unsigned long *sp)
{
unsigned long *stack;
int i;
void dump_stack(void)
{
- show_stack(NULL);
+ show_stack(NULL, NULL);
}
void
".previous \n"
: "=r" (cr4): "0" (0));
printk("CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n", cr0, cr2, cr3, cr4);
- show_trace(®s->esp);
+ show_trace(NULL, ®s->esp);
}
/*
#ifdef CONFIG_MCA
#include <linux/mca.h>
-#include <asm/processor.h>
#endif
+#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
static int kstack_depth_to_print = 24;
-void show_trace(unsigned long * stack)
+void show_trace(struct task_struct *task, unsigned long * stack)
{
int i;
unsigned long addr;
/* User space on another CPU? */
if ((esp ^ (unsigned long)tsk->thread_info) & (PAGE_MASK<<1))
return;
- show_trace((unsigned long *)esp);
+ show_trace(tsk, (unsigned long *)esp);
}
-void show_stack(unsigned long * esp)
+void show_stack(struct task_struct *task, unsigned long * esp)
{
unsigned long *stack;
int i;
printk("%08lx ", *stack++);
}
printk("\n");
- show_trace(esp);
+ show_trace(task, esp);
}
/*
{
unsigned long stack;
- show_trace(&stack);
+ show_trace(current, &stack);
}
void show_registers(struct pt_regs *regs)
if (in_kernel) {
printk("\nStack: ");
- show_stack((unsigned long*)esp);
+ show_stack(NULL, (unsigned long*)esp);
printk("Code: ");
if(regs->eip < PAGE_OFFSET)
return last;
}
-static void show_tsk_stack(struct task_struct *p, unsigned long sp);
char *ppc_find_proc_name(unsigned *p, char *buf, unsigned buflen);
void show_regs(struct pt_regs * regs)
printk("NIP [%016lx] ", regs->nip);
printk("%s\n", ppc_find_proc_name((unsigned *)regs->nip,
name_buf, 256));
- show_tsk_stack(current, regs->gpr[1]);
+ show_stack(current, (unsigned long *)regs->gpr[1]);
}
void exit_thread(void)
return 0;
}
-static void show_tsk_stack(struct task_struct *p, unsigned long sp)
+void show_stack(struct task_struct *p, unsigned long *_sp)
{
unsigned long ip;
unsigned long stack_page = (unsigned long)p->thread_info;
int count = 0;
char name_buf[256];
+ unsigned long sp = (unsigned long)_sp;
if (!p)
return;
+ if (sp == 0)
+ sp = p->thread.ksp;
printk("Call Trace:\n");
do {
if (__get_user(sp, (unsigned long *)sp))
break;
- if (sp < (stack_page + sizeof(struct thread_struct)) ||
- sp >= (stack_page + THREAD_SIZE))
+ if (sp < stack_page + sizeof(struct thread_struct))
+ break;
+ if (sp >= stack_page + THREAD_SIZE)
break;
if (__get_user(ip, (unsigned long *)(sp + 16)))
break;
void dump_stack(void)
{
- show_tsk_stack(current, (unsigned long)_get_SP());
+ show_stack(current, (unsigned long *)_get_SP());
}
void show_trace_task(struct task_struct *tsk)
{
- show_tsk_stack(tsk, tsk->thread.ksp);
+ show_stack(tsk, (unsigned long *)tsk->thread.ksp);
}
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
extern unsigned long thread_saved_pc(struct task_struct *tsk);
+void show_trace(struct task_struct *task, unsigned long *stack);
unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019])
extern void init_idle(task_t *idle, int cpu);
extern void show_state(void);
-extern void show_trace(unsigned long *stack);
-extern void show_stack(unsigned long *stack);
extern void show_regs(struct pt_regs *);
+/*
+ * TASK is a pointer to the task whose backtrace we want to see (or NULL for current
+ * task), SP is the stack pointer of the first frame that should be shown in the back
+ * trace (or NULL if the entire call-chain of the task should be shown).
+ */
+extern void show_stack(struct task_struct *task, unsigned long *sp);
+
void io_schedule(void);
long io_schedule_timeout(long timeout);
else
printk(" (NOTLB)\n");
- {
- extern void show_trace_task(task_t *tsk);
- show_trace_task(p);
- }
+ show_stack(p, NULL);
}
void show_state(void)