/* This routine abuses get_user()/put_user() to reference pointers with at least a bit of error checking ...  */
static void show_stacktrace(struct task_struct *task, const struct pt_regs *regs)
/* This routine abuses get_user()/put_user() to reference pointers with at least a bit of error checking ...  */
static void show_stacktrace(struct task_struct *task, const struct pt_regs *regs)
{
	const int field = 2 * sizeof(unsigned long);
	long stackdata;
	int i;
	unsigned long __user *sp = (unsigned long __user *)regs->regs[29];
	printk("Stack :");
	i = 0;
	while ((unsigned long) sp & (PAGE_SIZE - 1)) {
		if (i && ((i % (64 / field)) == 0))
			printk("\n       ");
		if (i > 39) {
			printk(" ...");
			break;
		}
		if (__get_user(stackdata, sp++)) {
			printk(" (Bad stack address)");
			break;
		}
		printk(" %0*lx", field, stackdata);
		i++;
	}
	printk("\n");
	show_backtrace(task, regs);
}